diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index b4c9b46947..e512b7f65f 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -281,7 +281,7 @@ * * Advanced settings can be found in Configuration_adv.h */ -#define CONFIGURATION_H_VERSION 02000900 +#define CONFIGURATION_H_VERSION 02000901 //=========================================================================== //============================= Getting Started ============================= @@ -943,6 +943,8 @@ //#define PSU_NAME "Power Supply" #if ENABLED(PSU_CONTROL) + //#define PS_OFF_CONFIRM // Confirm dialog when power off + //#define PS_OFF_SOUND // Beep 1s when power off #if ENABLED(PowerShutoffKit) #define PS_ON_PIN 12 #define PSU_ACTIVE_STATE HIGH @@ -977,70 +979,92 @@ // @section temperature /** - * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * --NORMAL IS 4.7kΩ PULLUP!-- 1kΩ pullup can be used on hotend sensor, using correct resistor and table * * Temperature sensors available: * - * -5 : PT100 / PT1000 with MAX31865 (only for sensors 0-1) - * -3 : thermocouple with MAX31855 (only for sensors 0-1) - * -2 : thermocouple with MAX6675 (only for sensors 0-1) - * -4 : thermocouple with AD8495 - * -1 : thermocouple with AD595 + * SPI RTD/Thermocouple Boards - IMPORTANT: Read the NOTE below! + * ------- + * -5 : MAX31865 with Pt100/Pt1000, 2, 3, or 4-wire (only for sensors 0-1) + * NOTE: You must uncomment/set the MAX31865_*_OHMS_n defines below. + * -3 : MAX31855 with Thermocouple, -200°C to +700°C (only for sensors 0-1) + * -2 : MAX6675 with Thermocouple, 0°C to +700°C (only for sensors 0-1) + * + * NOTE: Ensure TEMP_n_CS_PIN is set in your pins file for each TEMP_SENSOR_n using an SPI Thermocouple. By default, + * Hardware SPI on the default serial bus is used. If you have also set TEMP_n_SCK_PIN and TEMP_n_MISO_PIN, + * Software SPI will be used on those ports instead. You can force Hardware SPI on the default bus in the + * Configuration_adv.h file. At this time, separate Hardware SPI buses for sensors are not supported. + * + * Analog Themocouple Boards + * ------- + * -4 : AD8495 with Thermocouple + * -1 : AD595 with Thermocouple + * + * Analog Thermistors - 4.7kΩ pullup - Normal + * ------- + * 1 : 100kΩ EPCOS - Best choice for EPCOS thermistors + * 331 : 100kΩ Same as #1, but 3.3V scaled for MEGA + * 332 : 100kΩ Same as #1, but 3.3V scaled for DUE + * 2 : 200kΩ ATC Semitec 204GT-2 + * 202 : 200kΩ Copymaster 3D + * 3 : ???Ω Mendel-parts thermistor + * 4 : 10kΩ Generic Thermistor !! DO NOT use for a hotend - it gives bad resolution at high temp. !! + * 5 : 100kΩ ATC Semitec 104GT-2/104NT-4-R025H42G - Used in ParCan, J-Head, and E3D, SliceEngineering 300°C + * 501 : 100kΩ Zonestar - Tronxy X3A + * 502 : 100kΩ Zonestar - used by hot bed in Zonestar Průša P802M + * 512 : 100kΩ RPW-Ultra hotend + * 6 : 100kΩ EPCOS - Not as accurate as table #1 (created using a fluke thermocouple) + * 7 : 100kΩ Honeywell 135-104LAG-J01 + * 71 : 100kΩ Honeywell 135-104LAF-J01 + * 8 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT + * 9 : 100kΩ GE Sensing AL03006-58.2K-97-G1 + * 10 : 100kΩ RS PRO 198-961 + * 11 : 100kΩ Keenovo AC silicone mats, most Wanhao i3 machines - beta 3950, 1% + * 12 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT (#8) - calibrated for Makibox hot bed + * 13 : 100kΩ Hisens up to 300°C - for "Simple ONE" & "All In ONE" hotend - beta 3950, 1% + * 15 : 100kΩ Calibrated for JGAurora A5 hotend + * 18 : 200kΩ ATC Semitec 204GT-2 Dagoma.Fr - MKS_Base_DKU001327 + * 22 : 100kΩ GTM32 Pro vB - hotend - 4.7kΩ pullup to 3.3V and 220Ω to analog input + * 23 : 100kΩ GTM32 Pro vB - bed - 4.7kΩ pullup to 3.3v and 220Ω to analog input + * 30 : 100kΩ Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K - beta 3950 + * 60 : 100kΩ Maker's Tool Works Kapton Bed Thermistor - beta 3950 + * 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950 + * 66 : 4.7MΩ Dyze Design High Temperature Thermistor + * 67 : 500kΩ SliceEngineering 450°C Thermistor + * 70 : 100kΩ bq Hephestos 2 + * 75 : 100kΩ Generic Silicon Heat Pad with NTC100K MGB18-104F39050L32 + * + * Analog Thermistors - 1kΩ pullup - Atypical, and requires changing out the 4.7kΩ pullup for 1kΩ. + * ------- (but gives greater accuracy and more stable PID) + * 51 : 100kΩ EPCOS (1kΩ pullup) + * 52 : 200kΩ ATC Semitec 204GT-2 (1kΩ pullup) + * 55 : 100kΩ ATC Semitec 104GT-2 - Used in ParCan & J-Head (1kΩ pullup) + * + * Analog Thermistors - 10kΩ pullup - Atypical + * ------- + * 99 : 100kΩ Found on some Wanhao i3 machines with a 10kΩ pull-up resistor + * + * Analog RTDs (Pt100/Pt1000) + * ------- + * 110 : Pt100 with 1kΩ pullup (atypical) + * 147 : Pt100 with 4.7kΩ pullup + * 1010 : Pt1000 with 1kΩ pullup (atypical) + * 1047 : Pt1000 with 4.7kΩ pullup (E3D) + * 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage. + * NOTE: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21. + * 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v ADC reference voltage (STM32, LPC176x....) and 5V INA826 amplifier board supply. + * NOTE: ADC pins are not 5V tolerant. Not recommended because it's possible to damage the CPU by going over 500°C. + * 201 : Pt100 with circuit in Overlord, similar to Ultimainboard V2.x + * + * Custom/Dummy/Other Thermos + * ------ * 0 : not used - * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) - * 331 : (3.3V scaled thermistor 1 table for MEGA) - * 332 : (3.3V scaled thermistor 1 table for DUE) - * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) - * 202 : 200k thermistor - Copymaster 3D - * 3 : Mendel-parts thermistor (4.7k pullup) - * 4 : 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! - * 5 : 100K thermistor - ATC Semitec 104GT-2/104NT-4-R025H42G (Used in ParCan, J-Head, and E3D) (4.7k pullup) - * 501 : 100K Zonestar (Tronxy X3A) Thermistor - * 502 : 100K Zonestar Thermistor used by hot bed in Zonestar Průša P802M - * 512 : 100k RPW-Ultra hotend thermistor (4.7k pullup) - * 6 : 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) - * 7 : 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup) - * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) - * 8 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) - * 9 : 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) - * 10 : 100k RS thermistor 198-961 (4.7k pullup) - * 11 : 100k beta 3950 1% thermistor (Used in Keenovo AC silicone mats and most Wanhao i3 machines) (4.7k pullup) - * 12 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) - * 13 : 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE" - * 15 : 100k thermistor calibration for JGAurora A5 hotend - * 18 : ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327 - * 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage. - * NOTES: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21. - * 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v ADC reference voltage (STM32, LPC176x....) and 5V INA826 amplifier board supply. - * NOTE: ADC pins are not 5V tolerant. Not recommended because it's possible to damage the CPU by going over 500°C. - * 22 : 100k (hotend) with 4.7k pullup to 3.3V and 220R to analog input (as in GTM32 Pro vB) - * 23 : 100k (bed) with 4.7k pullup to 3.3v and 220R to analog input (as in GTM32 Pro vB) - * 30 : Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K / B3950 (4.7k pullup) - * 201 : Pt100 with circuit in Overlord, similar to Ultimainboard V2.x - * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 - * 61 : 100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup - * 66 : 4.7M High Temperature thermistor from Dyze Design - * 67 : 450C thermistor from SliceEngineering - * 70 : the 100K thermistor found in the bq Hephestos 2 - * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor - * 99 : 100k thermistor with a 10K pull-up resistor (found on some Wanhao i3 machines) - * - * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. - * (but gives greater accuracy and more stable PID) - * 51 : 100k thermistor - EPCOS (1k pullup) - * 52 : 200k thermistor - ATC Semitec 204GT-2 (1k pullup) - * 55 : 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) - * - * 1047 : Pt1000 with 4k7 pullup (E3D) - * 1010 : Pt1000 with 1k pullup (non standard) - * 147 : Pt100 with 4k7 pullup - * 110 : Pt100 with 1k pullup (non standard) - * * 1000 : Custom - Specify parameters in Configuration_adv.h * - * Use these for Testing or Development purposes. NEVER for production machine. + * !!! Use these for Testing or Development purposes. NEVER for production machine. !!! * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * */ #if ENABLED(ConfigurableThermistors) #define TEMP_SENSOR_0 1000 @@ -1092,7 +1116,7 @@ // Resistor values when using MAX31865 sensors (-5) on TEMP_SENSOR_0 / 1 //#define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000) -//#define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for AdaFruit PT100; 4300 for AdaFruit PT1000 +//#define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for Adafruit PT100; 4300 for Adafruit PT1000 //#define MAX31865_SENSOR_OHMS_1 100 //#define MAX31865_CALIBRATION_OHMS_1 430 @@ -2217,7 +2241,8 @@ #define WAIT_FOR_HOTEND // Wait for hotend to heat back up between probes (to improve accuracy & prevent cold extrude) #endif //#define PROBING_FANS_OFF // Turn fans off when probing -//#define PROBING_STEPPERS_OFF // Turn steppers off (unless needed to hold position) when probing +//#define PROBING_ESTEPPERS_OFF // Turn all extruder steppers off when probing +//#define PROBING_STEPPERS_OFF // Turn all steppers off (unless needed to hold position) when probing (including extruders) //#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors // Require minimum nozzle and/or bed temperature for probing @@ -2948,15 +2973,13 @@ //#define MANUAL_J_HOME_POS 0 //#define MANUAL_K_HOME_POS 0 -// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. -// -// With this feature enabled: -// -// - Allow Z homing only after X and Y homing AND stepper drivers still enabled. -// - If stepper drivers time out, it will need X and Y homing again before Z homing. -// - Move the Z probe (or nozzle) to a defined XY point before Z Homing. -// - Prevent Z homing when the Z probe is outside bed area. -// +/** + * Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. + * + * - Moves the Z probe (or nozzle) to a defined XY point before Z homing. + * - Allows Z homing only when XY positions are known and trusted. + * - If stepper drivers sleep, XY homing may be required again before Z homing. + */ #if ANY(ABL_EZABL, ABL_NCSW, ABL_BLTOUCH, ABL_TOUCH_MI, NOZZLE_AS_PROBE) #define Z_SAFE_HOMING #endif diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 09e61755cf..c281958c43 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -30,7 +30,7 @@ * * Basic settings can be found in Configuration.h */ -#define CONFIGURATION_ADV_H_VERSION 02000900 +#define CONFIGURATION_ADV_H_VERSION 02000901 //=========================================================================== //============================= Thermal Settings ============================ @@ -131,10 +131,21 @@ #define REDUNDANT_BETA 3950 // Beta value #endif -// -// Hephestos 2 24V heated bed upgrade kit. -// https://store.bq.com/en/heated-bed-kit-hephestos2 -// +/** + * Configuration options for MAX Thermocouples (-2, -3, -5). + * FORCE_HW_SPI: Ignore SCK/MOSI/MISO pins and just use the CS pin & default SPI bus. + * MAX31865_WIRES: Set the number of wires for the probe connected to a MAX31865 board, 2-4. Default: 2 + * MAX31865_50HZ: Enable 50Hz filter instead of the default 60Hz. + */ +//#define TEMP_SENSOR_FORCE_HW_SPI +//#define MAX31865_SENSOR_WIRES_0 2 +//#define MAX31865_SENSOR_WIRES_1 2 +//#define MAX31865_50HZ_FILTER + +/** + * Hephestos 2 24V heated bed upgrade kit. + * https://store.bq.com/en/heated-bed-kit-hephestos2 + */ //#define HEPHESTOS2_HEATED_BED_KIT #if ENABLED(HEPHESTOS2_HEATED_BED_KIT) #undef TEMP_SENSOR_BED @@ -3036,7 +3047,7 @@ * * It is recommended to set HOMING_BUMP_MM to { 0, 0, 0 }. * - * SPI_ENDSTOPS *** Beta feature! *** TMC2130 Only *** + * SPI_ENDSTOPS *** Beta feature! *** TMC2130/TMC5160 Only *** * Poll the driver through SPI to determine load when homing. * Removes the need for a wire from DIAG1 to an endstop pin. * diff --git a/Marlin/src/HAL/SAMD51/inc/SanityCheck.h b/Marlin/src/HAL/SAMD51/inc/SanityCheck.h index 2a4bde98e6..38c6dd9e08 100644 --- a/Marlin/src/HAL/SAMD51/inc/SanityCheck.h +++ b/Marlin/src/HAL/SAMD51/inc/SanityCheck.h @@ -31,7 +31,8 @@ #error "No custom SD drive cable defined for this board." #endif -#if defined(MAX6675_SCK_PIN) && defined(MAX6675_DO_PIN) && (MAX6675_SCK_PIN == SCK1 || MAX6675_DO_PIN == MISO1) +#if (defined(TEMP_0_SCK_PIN) && defined(TEMP_0_MISO_PIN) && (TEMP_0_SCK_PIN == SCK1 || TEMP_0_MISO_PIN == MISO1)) || \ + (defined(TEMP_1_SCK_PIN) && defined(TEMP_1_MISO_PIN) && (TEMP_1_SCK_PIN == SCK1 || TEMP_1_MISO_PIN == MISO1)) #error "OnBoard SPI BUS can't be shared with other devices." #endif diff --git a/Marlin/src/HAL/STM32F1/onboard_sd.cpp b/Marlin/src/HAL/STM32F1/onboard_sd.cpp index 6092aea320..e26947145d 100644 --- a/Marlin/src/HAL/STM32F1/onboard_sd.cpp +++ b/Marlin/src/HAL/STM32F1/onboard_sd.cpp @@ -38,8 +38,8 @@ #define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_2 #endif -#define CS_LOW() WRITE(ONBOARD_SD_CS_PIN, LOW) /* Set OnboardSPI cs low */ -#define CS_HIGH() WRITE(ONBOARD_SD_CS_PIN, HIGH) /* Set OnboardSPI cs high */ +#define CS_LOW() WRITE(ONBOARD_SD_CS_PIN, LOW) // Set OnboardSPI cs low +#define CS_HIGH() WRITE(ONBOARD_SD_CS_PIN, HIGH) // Set OnboardSPI cs high #define FCLK_FAST() ONBOARD_SD_SPI.setClockDivider(SPI_CLOCK_MAX) #define FCLK_SLOW() ONBOARD_SD_SPI.setClockDivider(SPI_BAUD_PCLK_DIV_256) @@ -49,32 +49,32 @@ ---------------------------------------------------------------------------*/ /* MMC/SD command */ -#define CMD0 (0) /* GO_IDLE_STATE */ -#define CMD1 (1) /* SEND_OP_COND (MMC) */ -#define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */ -#define CMD8 (8) /* SEND_IF_COND */ -#define CMD9 (9) /* SEND_CSD */ -#define CMD10 (10) /* SEND_CID */ -#define CMD12 (12) /* STOP_TRANSMISSION */ -#define ACMD13 (0x80+13) /* SD_STATUS (SDC) */ -#define CMD16 (16) /* SET_BLOCKLEN */ -#define CMD17 (17) /* READ_SINGLE_BLOCK */ -#define CMD18 (18) /* READ_MULTIPLE_BLOCK */ -#define CMD23 (23) /* SET_BLOCK_COUNT (MMC) */ -#define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */ -#define CMD24 (24) /* WRITE_BLOCK */ -#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */ -#define CMD32 (32) /* ERASE_ER_BLK_START */ -#define CMD33 (33) /* ERASE_ER_BLK_END */ -#define CMD38 (38) /* ERASE */ -#define CMD48 (48) /* READ_EXTR_SINGLE */ -#define CMD49 (49) /* WRITE_EXTR_SINGLE */ -#define CMD55 (55) /* APP_CMD */ -#define CMD58 (58) /* READ_OCR */ +#define CMD0 (0) // GO_IDLE_STATE +#define CMD1 (1) // SEND_OP_COND (MMC) +#define ACMD41 (0x80+41) // SEND_OP_COND (SDC) +#define CMD8 (8) // SEND_IF_COND +#define CMD9 (9) // SEND_CSD +#define CMD10 (10) // SEND_CID +#define CMD12 (12) // STOP_TRANSMISSION +#define ACMD13 (0x80+13) // SD_STATUS (SDC) +#define CMD16 (16) // SET_BLOCKLEN +#define CMD17 (17) // READ_SINGLE_BLOCK +#define CMD18 (18) // READ_MULTIPLE_BLOCK +#define CMD23 (23) // SET_BLOCK_COUNT (MMC) +#define ACMD23 (0x80+23) // SET_WR_BLK_ERASE_COUNT (SDC) +#define CMD24 (24) // WRITE_BLOCK +#define CMD25 (25) // WRITE_MULTIPLE_BLOCK +#define CMD32 (32) // ERASE_ER_BLK_START +#define CMD33 (33) // ERASE_ER_BLK_END +#define CMD38 (38) // ERASE +#define CMD48 (48) // READ_EXTR_SINGLE +#define CMD49 (49) // WRITE_EXTR_SINGLE +#define CMD55 (55) // APP_CMD +#define CMD58 (58) // READ_OCR -static volatile DSTATUS Stat = STA_NOINIT; /* Physical drive status */ +static volatile DSTATUS Stat = STA_NOINIT; // Physical drive status static volatile UINT timeout; -static BYTE CardType; /* Card type flags */ +static BYTE CardType; // Card type flags /*-----------------------------------------------------------------------*/ /* Send/Receive data to the MMC (Platform dependent) */ @@ -82,7 +82,7 @@ static BYTE CardType; /* Card type flags */ /* Exchange a byte */ static BYTE xchg_spi ( - BYTE dat /* Data to send */ + BYTE dat // Data to send ) { BYTE returnByte = ONBOARD_SD_SPI.transfer(dat); return returnByte; @@ -90,18 +90,18 @@ static BYTE xchg_spi ( /* Receive multiple byte */ static void rcvr_spi_multi ( - BYTE *buff, /* Pointer to data buffer */ - UINT btr /* Number of bytes to receive (16, 64 or 512) */ + BYTE *buff, // Pointer to data buffer + UINT btr // Number of bytes to receive (16, 64 or 512) ) { ONBOARD_SD_SPI.dmaTransfer(0, const_cast(buff), btr); } #if _DISKIO_WRITE - /* Send multiple bytes */ + // Send multiple bytes static void xmit_spi_multi ( - const BYTE *buff, /* Pointer to the data */ - UINT btx /* Number of bytes to send (multiple of 16) */ + const BYTE *buff, // Pointer to the data + UINT btx // Number of bytes to send (multiple of 16) ) { ONBOARD_SD_SPI.dmaSend(const_cast(buff), btx); } @@ -112,16 +112,15 @@ static void rcvr_spi_multi ( /* Wait for card ready */ /*-----------------------------------------------------------------------*/ -static int wait_ready ( /* 1:Ready, 0:Timeout */ - UINT wt /* Timeout [ms] */ +static int wait_ready ( // 1:Ready, 0:Timeout + UINT wt // Timeout [ms] ) { BYTE d; - timeout = millis() + wt; do { d = xchg_spi(0xFF); - /* This loop takes a while. Insert rot_rdq() here for multitask environment. */ - } while (d != 0xFF && (timeout > millis())); /* Wait for card goes ready or timeout */ + // This loop takes a while. Insert rot_rdq() here for multitask environment. + } while (d != 0xFF && (timeout > millis())); // Wait for card goes ready or timeout return (d == 0xFF) ? 1 : 0; } @@ -131,21 +130,21 @@ static int wait_ready ( /* 1:Ready, 0:Timeout */ /*-----------------------------------------------------------------------*/ static void deselect() { - CS_HIGH(); /* CS = H */ - xchg_spi(0xFF); /* Dummy clock (force DO hi-z for multiple slave SPI) */ + CS_HIGH(); // CS = H + xchg_spi(0xFF); // Dummy clock (force DO hi-z for multiple slave SPI) } /*-----------------------------------------------------------------------*/ /* Select card and wait for ready */ /*-----------------------------------------------------------------------*/ -static int select() { /* 1:OK, 0:Timeout */ - CS_LOW(); /* CS = L */ - xchg_spi(0xFF); /* Dummy clock (force DO enabled) */ +static int select() { // 1:OK, 0:Timeout + CS_LOW(); // CS = L + xchg_spi(0xFF); // Dummy clock (force DO enabled) - if (wait_ready(500)) return 1; /* Leading busy check: Wait for card ready */ + if (wait_ready(500)) return 1; // Leading busy check: Wait for card ready - deselect(); /* Timeout */ + deselect(); // Timeout return 0; } @@ -153,16 +152,18 @@ static int select() { /* 1:OK, 0:Timeout */ /* Control SPI module (Platform dependent) */ /*-----------------------------------------------------------------------*/ -static void power_on() { /* Enable SSP module and attach it to I/O pads */ +// Enable SSP module and attach it to I/O pads +static void sd_power_on() { ONBOARD_SD_SPI.setModule(ONBOARD_SPI_DEVICE); ONBOARD_SD_SPI.begin(); ONBOARD_SD_SPI.setBitOrder(MSBFIRST); ONBOARD_SD_SPI.setDataMode(SPI_MODE0); - OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH); /* Set CS# high */ + OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH); // Set CS# high } -static void power_off() { /* Disable SPI function */ - select(); /* Wait for card ready */ +// Disable SPI function +static void sd_power_off() { + select(); // Wait for card ready deselect(); } @@ -170,23 +171,23 @@ static void power_off() { /* Disable SPI function */ /* Receive a data packet from the MMC */ /*-----------------------------------------------------------------------*/ -static int rcvr_datablock ( /* 1:OK, 0:Error */ - BYTE *buff, /* Data buffer */ - UINT btr /* Data block length (byte) */ +static int rcvr_datablock ( // 1:OK, 0:Error + BYTE *buff, // Data buffer + UINT btr // Data block length (byte) ) { BYTE token; timeout = millis() + 200; - do { /* Wait for DataStart token in timeout of 200ms */ + do { // Wait for DataStart token in timeout of 200ms token = xchg_spi(0xFF); - /* This loop will take a while. Insert rot_rdq() here for multitask environment. */ + // This loop will take a while. Insert rot_rdq() here for multitask environment. } while ((token == 0xFF) && (timeout > millis())); - if (token != 0xFE) return 0; /* Function fails if invalid DataStart token or timeout */ + if (token != 0xFE) return 0; // Function fails if invalid DataStart token or timeout - rcvr_spi_multi(buff, btr); /* Store trailing data to the buffer */ - xchg_spi(0xFF); xchg_spi(0xFF); /* Discard CRC */ + rcvr_spi_multi(buff, btr); // Store trailing data to the buffer + xchg_spi(0xFF); xchg_spi(0xFF); // Discard CRC - return 1; /* Function succeeded */ + return 1; // Function succeeded } /*-----------------------------------------------------------------------*/ @@ -195,25 +196,25 @@ static int rcvr_datablock ( /* 1:OK, 0:Error */ #if _DISKIO_WRITE - static int xmit_datablock ( /* 1:OK, 0:Failed */ - const BYTE *buff, /* Ponter to 512 byte data to be sent */ - BYTE token /* Token */ + static int xmit_datablock( // 1:OK, 0:Failed + const BYTE *buff, // Pointer to 512 byte data to be sent + BYTE token // Token ) { BYTE resp; - if (!wait_ready(500)) return 0; /* Leading busy check: Wait for card ready to accept data block */ + if (!wait_ready(500)) return 0; // Leading busy check: Wait for card ready to accept data block - xchg_spi(token); /* Send token */ - if (token == 0xFD) return 1; /* Do not send data if token is StopTran */ + xchg_spi(token); // Send token + if (token == 0xFD) return 1; // Do not send data if token is StopTran - xmit_spi_multi(buff, 512); /* Data */ - xchg_spi(0xFF); xchg_spi(0xFF); /* Dummy CRC */ + xmit_spi_multi(buff, 512); // Data + xchg_spi(0xFF); xchg_spi(0xFF); // Dummy CRC - resp = xchg_spi(0xFF); /* Receive data resp */ + resp = xchg_spi(0xFF); // Receive data resp - return (resp & 0x1F) == 0x05 ? 1 : 0; /* Data was accepted or not */ + return (resp & 0x1F) == 0x05 ? 1 : 0; // Data was accepted or not - /* Busy check is done at next transmission */ + // Busy check is done at next transmission } #endif // _DISKIO_WRITE @@ -222,43 +223,43 @@ static int rcvr_datablock ( /* 1:OK, 0:Error */ /* Send a command packet to the MMC */ /*-----------------------------------------------------------------------*/ -static BYTE send_cmd ( /* Return value: R1 resp (bit7==1:Failed to send) */ - BYTE cmd, /* Command index */ - DWORD arg /* Argument */ +static BYTE send_cmd( // Return value: R1 resp (bit7==1:Failed to send) + BYTE cmd, // Command index + DWORD arg // Argument ) { BYTE n, res; - if (cmd & 0x80) { /* Send a CMD55 prior to ACMD */ + if (cmd & 0x80) { // Send a CMD55 prior to ACMD cmd &= 0x7F; res = send_cmd(CMD55, 0); if (res > 1) return res; } - /* Select the card and wait for ready except to stop multiple block read */ + // Select the card and wait for ready except to stop multiple block read if (cmd != CMD12) { deselect(); if (!select()) return 0xFF; } - /* Send command packet */ - xchg_spi(0x40 | cmd); /* Start + command index */ - xchg_spi((BYTE)(arg >> 24)); /* Argument[31..24] */ - xchg_spi((BYTE)(arg >> 16)); /* Argument[23..16] */ - xchg_spi((BYTE)(arg >> 8)); /* Argument[15..8] */ - xchg_spi((BYTE)arg); /* Argument[7..0] */ - n = 0x01; /* Dummy CRC + Stop */ - if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */ - if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */ + // Send command packet + xchg_spi(0x40 | cmd); // Start + command index + xchg_spi((BYTE)(arg >> 24)); // Argument[31..24] + xchg_spi((BYTE)(arg >> 16)); // Argument[23..16] + xchg_spi((BYTE)(arg >> 8)); // Argument[15..8] + xchg_spi((BYTE)arg); // Argument[7..0] + n = 0x01; // Dummy CRC + Stop + if (cmd == CMD0) n = 0x95; // Valid CRC for CMD0(0) + if (cmd == CMD8) n = 0x87; // Valid CRC for CMD8(0x1AA) xchg_spi(n); - /* Receive command resp */ - if (cmd == CMD12) xchg_spi(0xFF); /* Diacard following one byte when CMD12 */ - n = 10; /* Wait for response (10 bytes max) */ + // Receive command response + if (cmd == CMD12) xchg_spi(0xFF); // Discard the following byte when CMD12 + n = 10; // Wait for response (10 bytes max) do res = xchg_spi(0xFF); while ((res & 0x80) && --n); - return res; /* Return received response */ + return res; // Return received response } /*-------------------------------------------------------------------------- @@ -270,49 +271,52 @@ static BYTE send_cmd ( /* Return value: R1 resp (bit7==1:Failed to send) */ /*-----------------------------------------------------------------------*/ DSTATUS disk_initialize ( - BYTE drv /* Physical drive number (0) */ + BYTE drv // Physical drive number (0) ) { BYTE n, cmd, ty, ocr[4]; - if (drv) return STA_NOINIT; /* Supports only drive 0 */ - power_on(); /* Initialize SPI */ + if (drv) return STA_NOINIT; // Supports only drive 0 + sd_power_on(); // Initialize SPI - if (Stat & STA_NODISK) return Stat; /* Is a card existing in the soket? */ + if (Stat & STA_NODISK) return Stat; // Is a card existing in the soket? FCLK_SLOW(); - for (n = 10; n; n--) xchg_spi(0xFF); /* Send 80 dummy clocks */ + for (n = 10; n; n--) xchg_spi(0xFF); // Send 80 dummy clocks ty = 0; - if (send_cmd(CMD0, 0) == 1) { /* Put the card SPI state */ - timeout = millis() + 1000; /* Initialization timeout = 1 sec */ - if (send_cmd(CMD8, 0x1AA) == 1) { /* Is the catd SDv2? */ - for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); /* Get 32 bit return value of R7 resp */ - if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* Does the card support 2.7-3.6V? */ - while ((timeout > millis()) && send_cmd(ACMD41, 1UL << 30)) ; /* Wait for end of initialization with ACMD41(HCS) */ - if ((timeout > millis()) && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ + if (send_cmd(CMD0, 0) == 1) { // Put the card SPI state + timeout = millis() + 1000; // Initialization timeout = 1 sec + if (send_cmd(CMD8, 0x1AA) == 1) { // Is the catd SDv2? + for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); // Get 32 bit return value of R7 resp + if (ocr[2] == 0x01 && ocr[3] == 0xAA) { // Does the card support 2.7-3.6V? + while ((timeout > millis()) && send_cmd(ACMD41, 1UL << 30)); // Wait for end of initialization with ACMD41(HCS) + if ((timeout > millis()) && send_cmd(CMD58, 0) == 0) { // Check CCS bit in the OCR for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); - ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* Check if the card is SDv2 */ + ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; // Check if the card is SDv2 } } - } else { /* Not an SDv2 card */ - if (send_cmd(ACMD41, 0) <= 1) { /* SDv1 or MMCv3? */ - ty = CT_SD1; cmd = ACMD41; /* SDv1 (ACMD41(0)) */ - } else { - ty = CT_MMC; cmd = CMD1; /* MMCv3 (CMD1(0)) */ + } + else { // Not an SDv2 card + if (send_cmd(ACMD41, 0) <= 1) { // SDv1 or MMCv3? + ty = CT_SD1; cmd = ACMD41; // SDv1 (ACMD41(0)) } - while ((timeout > millis()) && send_cmd(cmd, 0)) ; /* Wait for the card leaves idle state */ - if (!(timeout > millis()) || send_cmd(CMD16, 512) != 0) /* Set block length: 512 */ + else { + ty = CT_MMC; cmd = CMD1; // MMCv3 (CMD1(0)) + } + while ((timeout > millis()) && send_cmd(cmd, 0)); // Wait for the card leaves idle state + if (!(timeout > millis()) || send_cmd(CMD16, 512) != 0) // Set block length: 512 ty = 0; } } - CardType = ty; /* Card type */ + CardType = ty; // Card type deselect(); - if (ty) { /* OK */ - FCLK_FAST(); /* Set fast clock */ - Stat &= ~STA_NOINIT; /* Clear STA_NOINIT flag */ - } else { /* Failed */ - power_off(); + if (ty) { // OK + FCLK_FAST(); // Set fast clock + Stat &= ~STA_NOINIT; // Clear STA_NOINIT flag + } + else { // Failed + sd_power_off(); Stat = STA_NOINIT; } @@ -324,10 +328,10 @@ DSTATUS disk_initialize ( /*-----------------------------------------------------------------------*/ DSTATUS disk_status ( - BYTE drv /* Physical drive number (0) */ + BYTE drv // Physical drive number (0) ) { - if (drv) return STA_NOINIT; /* Supports only drive 0 */ - return Stat; /* Return disk status */ + if (drv) return STA_NOINIT; // Supports only drive 0 + return Stat; // Return disk status } /*-----------------------------------------------------------------------*/ @@ -335,28 +339,28 @@ DSTATUS disk_status ( /*-----------------------------------------------------------------------*/ DRESULT disk_read ( - BYTE drv, /* Physical drive number (0) */ - BYTE *buff, /* Pointer to the data buffer to store read data */ - DWORD sector, /* Start sector number (LBA) */ - UINT count /* Number of sectors to read (1..128) */ + BYTE drv, // Physical drive number (0) + BYTE *buff, // Pointer to the data buffer to store read data + DWORD sector, // Start sector number (LBA) + UINT count // Number of sectors to read (1..128) ) { BYTE cmd; - if (drv || !count) return RES_PARERR; /* Check parameter */ - if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */ - if (!(CardType & CT_BLOCK)) sector *= 512; /* LBA ot BA conversion (byte addressing cards) */ + if (drv || !count) return RES_PARERR; // Check parameter + if (Stat & STA_NOINIT) return RES_NOTRDY; // Check if drive is ready + if (!(CardType & CT_BLOCK)) sector *= 512; // LBA ot BA conversion (byte addressing cards) FCLK_FAST(); - cmd = count > 1 ? CMD18 : CMD17; /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */ + cmd = count > 1 ? CMD18 : CMD17; // READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK if (send_cmd(cmd, sector) == 0) { do { if (!rcvr_datablock(buff, 512)) break; buff += 512; } while (--count); - if (cmd == CMD18) send_cmd(CMD12, 0); /* STOP_TRANSMISSION */ + if (cmd == CMD18) send_cmd(CMD12, 0); // STOP_TRANSMISSION } deselect(); - return count ? RES_ERROR : RES_OK; /* Return result */ + return count ? RES_ERROR : RES_OK; // Return result } /*-----------------------------------------------------------------------*/ @@ -366,36 +370,36 @@ DRESULT disk_read ( #if _DISKIO_WRITE DRESULT disk_write( - BYTE drv, /* Physical drive number (0) */ - const BYTE *buff, /* Ponter to the data to write */ - DWORD sector, /* Start sector number (LBA) */ - UINT count /* Number of sectors to write (1..128) */ + BYTE drv, // Physical drive number (0) + const BYTE *buff, // Pointer to the data to write + DWORD sector, // Start sector number (LBA) + UINT count // Number of sectors to write (1..128) ) { - if (drv || !count) return RES_PARERR; /* Check parameter */ - if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */ - if (Stat & STA_PROTECT) return RES_WRPRT; /* Check write protect */ + if (drv || !count) return RES_PARERR; // Check parameter + if (Stat & STA_NOINIT) return RES_NOTRDY; // Check drive status + if (Stat & STA_PROTECT) return RES_WRPRT; // Check write protect FCLK_FAST(); - if (!(CardType & CT_BLOCK)) sector *= 512; /* LBA ==> BA conversion (byte addressing cards) */ + if (!(CardType & CT_BLOCK)) sector *= 512; // LBA ==> BA conversion (byte addressing cards) - if (count == 1) { /* Single sector write */ - if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */ + if (count == 1) { // Single sector write + if ((send_cmd(CMD24, sector) == 0) // WRITE_BLOCK && xmit_datablock(buff, 0xFE)) { count = 0; } } - else { /* Multiple sector write */ - if (CardType & CT_SDC) send_cmd(ACMD23, count); /* Predefine number of sectors */ - if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */ + else { // Multiple sector write + if (CardType & CT_SDC) send_cmd(ACMD23, count); // Predefine number of sectors + if (send_cmd(CMD25, sector) == 0) { // WRITE_MULTIPLE_BLOCK do { if (!xmit_datablock(buff, 0xFC)) break; buff += 512; } while (--count); - if (!xmit_datablock(0, 0xFD)) count = 1; /* STOP_TRAN token */ + if (!xmit_datablock(0, 0xFD)) count = 1; // STOP_TRAN token } } deselect(); - return count ? RES_ERROR : RES_OK; /* Return result */ + return count ? RES_ERROR : RES_OK; // Return result } #endif // _DISKIO_WRITE @@ -407,9 +411,9 @@ DRESULT disk_read ( #if _DISKIO_IOCTL DRESULT disk_ioctl ( - BYTE drv, /* Physical drive number (0) */ - BYTE cmd, /* Control command code */ - void *buff /* Pointer to the conrtol data */ + BYTE drv, // Physical drive number (0) + BYTE cmd, // Control command code + void *buff // Pointer to the conrtol data ) { DRESULT res; BYTE n, csd[16], *ptr = (BYTE *)buff; @@ -420,22 +424,23 @@ DRESULT disk_read ( UINT dc; #endif - if (drv) return RES_PARERR; /* Check parameter */ - if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */ + if (drv) return RES_PARERR; // Check parameter + if (Stat & STA_NOINIT) return RES_NOTRDY; // Check if drive is ready res = RES_ERROR; FCLK_FAST(); switch (cmd) { - case CTRL_SYNC: /* Wait for end of internal write process of the drive */ + case CTRL_SYNC: // Wait for end of internal write process of the drive if (select()) res = RES_OK; break; - case GET_SECTOR_COUNT: /* Get drive capacity in unit of sector (DWORD) */ + case GET_SECTOR_COUNT: // Get drive capacity in unit of sector (DWORD) if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { - if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */ + if ((csd[0] >> 6) == 1) { // SDC ver 2.00 csize = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1; *(DWORD*)buff = csize << 10; - } else { /* SDC ver 1.XX or MMC ver 3 */ + } + else { // SDC ver 1.XX or MMC ver 3 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1; *(DWORD*)buff = csize << (n - 9); @@ -444,21 +449,23 @@ DRESULT disk_read ( } break; - case GET_BLOCK_SIZE: /* Get erase block size in unit of sector (DWORD) */ - if (CardType & CT_SD2) { /* SDC ver 2.00 */ - if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */ + case GET_BLOCK_SIZE: // Get erase block size in unit of sector (DWORD) + if (CardType & CT_SD2) { // SDC ver 2.00 + if (send_cmd(ACMD13, 0) == 0) { // Read SD status xchg_spi(0xFF); - if (rcvr_datablock(csd, 16)) { /* Read partial block */ - for (n = 64 - 16; n; n--) xchg_spi(0xFF); /* Purge trailing data */ + if (rcvr_datablock(csd, 16)) { // Read partial block + for (n = 64 - 16; n; n--) xchg_spi(0xFF); // Purge trailing data *(DWORD*)buff = 16UL << (csd[10] >> 4); res = RES_OK; } } - } else { /* SDC ver 1.XX or MMC */ - if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */ - if (CardType & CT_SD1) { /* SDC ver 1.XX */ + } + else { // SDC ver 1.XX or MMC + if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { // Read CSD + if (CardType & CT_SD1) { // SDC ver 1.XX *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1); - } else { /* MMC */ + } + else { // MMC *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1); } res = RES_OK; @@ -466,47 +473,47 @@ DRESULT disk_read ( } break; - case CTRL_TRIM: /* Erase a block of sectors (used when _USE_TRIM in ffconf.h is 1) */ - if (!(CardType & CT_SDC)) break; /* Check if the card is SDC */ - if (disk_ioctl(drv, MMC_GET_CSD, csd)) break; /* Get CSD */ - if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break; /* Check if sector erase can be applied to the card */ - dp = (DWORD *)buff; st = dp[0]; ed = dp[1]; /* Load sector block */ + case CTRL_TRIM: // Erase a block of sectors (used when _USE_TRIM in ffconf.h is 1) + if (!(CardType & CT_SDC)) break; // Check if the card is SDC + if (disk_ioctl(drv, MMC_GET_CSD, csd)) break; // Get CSD + if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break; // Check if sector erase can be applied to the card + dp = (DWORD *)buff; st = dp[0]; ed = dp[1]; // Load sector block if (!(CardType & CT_BLOCK)) { st *= 512; ed *= 512; } - if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) { /* Erase sector block */ - res = RES_OK; /* FatFs does not check result of this command */ + if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) { // Erase sector block + res = RES_OK; // FatFs does not check result of this command } break; - /* Following commands are never used by FatFs module */ + // The following commands are never used by FatFs module - case MMC_GET_TYPE: /* Get MMC/SDC type (BYTE) */ + case MMC_GET_TYPE: // Get MMC/SDC type (BYTE) *ptr = CardType; res = RES_OK; break; - case MMC_GET_CSD: /* Read CSD (16 bytes) */ - if (send_cmd(CMD9, 0) == 0 && rcvr_datablock(ptr, 16)) { /* READ_CSD */ + case MMC_GET_CSD: // Read CSD (16 bytes) + if (send_cmd(CMD9, 0) == 0 && rcvr_datablock(ptr, 16)) { res = RES_OK; } break; - case MMC_GET_CID: /* Read CID (16 bytes) */ - if (send_cmd(CMD10, 0) == 0 && rcvr_datablock(ptr, 16)) { /* READ_CID */ + case MMC_GET_CID: // Read CID (16 bytes) + if (send_cmd(CMD10, 0) == 0 && rcvr_datablock(ptr, 16)) { res = RES_OK; } break; - case MMC_GET_OCR: /* Read OCR (4 bytes) */ - if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */ + case MMC_GET_OCR: // Read OCR (4 bytes) + if (send_cmd(CMD58, 0) == 0) { for (n = 4; n; n--) *ptr++ = xchg_spi(0xFF); res = RES_OK; } break; - case MMC_GET_SDSTAT: /* Read SD status (64 bytes) */ - if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */ + case MMC_GET_SDSTAT: // Read SD status (64 bytes) + if (send_cmd(ACMD13, 0) == 0) { xchg_spi(0xFF); if (rcvr_datablock(ptr, 64)) res = RES_OK; } diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index f77f3b2f0b..dc9fbb2ba7 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -617,7 +617,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) { TERN_(USE_CONTROLLER_FAN, controllerFan.update()); // Check if fan should be turned on to cool stepper drivers down - TERN_(AUTO_POWER_CONTROL, powerManager.check()); + TERN_(AUTO_POWER_CONTROL, powerManager.check(!ui.on_status_screen() || printJobOngoing() || printingIsPaused())); TERN_(HOTEND_IDLE_TIMEOUT, hotend_idle.check()); @@ -1169,10 +1169,10 @@ void setup() { // Init and disable SPI thermocouples; this is still needed #if TEMP_SENSOR_0_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 0) - OUT_WRITE(MAX6675_SS_PIN, HIGH); // Disable + OUT_WRITE(TEMP_0_CS_PIN, HIGH); // Disable #endif #if TEMP_SENSOR_1_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 1) - OUT_WRITE(MAX6675_SS2_PIN, HIGH); // Disable + OUT_WRITE(TEMP_1_CS_PIN, HIGH); #endif #if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) diff --git a/Marlin/src/MarlinCore.h b/Marlin/src/MarlinCore.h index 01a1be4d59..243811d7fb 100644 --- a/Marlin/src/MarlinCore.h +++ b/Marlin/src/MarlinCore.h @@ -91,7 +91,11 @@ extern bool wait_for_heatup; #define PSU_OFF_SOON() powerManager.power_off_soon() #else #define PSU_ON() PSU_PIN_ON() - #define PSU_OFF() PSU_PIN_OFF() + #if ENABLED(PS_OFF_SOUND) + #define PSU_OFF() do{ BUZZ(1000, 659); PSU_PIN_OFF(); }while(0) + #else + #define PSU_OFF() PSU_PIN_OFF() + #endif #define PSU_OFF_SOON PSU_OFF #endif #endif diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h index 295eee9bcf..05640bce87 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -204,8 +204,8 @@ #define __TERN(T,V...) ___TERN(_CAT(_NO,T),V) // Prepend '_NO' to get '_NOT_0' or '_NOT_1' #define ___TERN(P,V...) THIRD(P,V) // If first argument has a comma, A. Else B. -#define _OPTARG(A) , A -#define OPTARG(O,A) TERN_(O,DEFER4(_OPTARG)(A)) +#define _OPTARG(A...) , A +#define OPTARG(O,A...) TERN_(O,DEFER4(_OPTARG)(A)) #define _OPTCODE(A) A; #define OPTCODE(O,A) TERN_(O,DEFER4(_OPTCODE)(A)) diff --git a/Marlin/src/core/types.h b/Marlin/src/core/types.h index f8b5cef77b..833167a7a1 100644 --- a/Marlin/src/core/types.h +++ b/Marlin/src/core/types.h @@ -83,7 +83,7 @@ enum AxisEnum : uint8_t { #undef _EN_ITEM // Core also keeps toolhead directions - #if IS_CORE + #if EITHER(IS_CORE, MARKFORGED_XY) , X_HEAD, Y_HEAD, Z_HEAD #endif diff --git a/Marlin/src/feature/dac/stepper_dac.cpp b/Marlin/src/feature/dac/stepper_dac.cpp index 1cb0813daa..3abaece443 100644 --- a/Marlin/src/feature/dac/stepper_dac.cpp +++ b/Marlin/src/feature/dac/stepper_dac.cpp @@ -85,10 +85,16 @@ void StepperDAC::print_values() { if (!dac_present) return; SERIAL_ECHO_MSG("Stepper current values in % (Amps):"); SERIAL_ECHO_START(); - SERIAL_ECHOPAIR_P( SP_X_LBL, dac_perc(X_AXIS), PSTR(" ("), dac_amps(X_AXIS), PSTR(")")); - SERIAL_ECHOPAIR_P( SP_Y_LBL, dac_perc(Y_AXIS), PSTR(" ("), dac_amps(Y_AXIS), PSTR(")")); - SERIAL_ECHOPAIR_P( SP_Z_LBL, dac_perc(Z_AXIS), PSTR(" ("), dac_amps(Z_AXIS), PSTR(")")); - SERIAL_ECHOLNPAIR_P(SP_E_LBL, dac_perc(E_AXIS), PSTR(" ("), dac_amps(E_AXIS), PSTR(")")); + SERIAL_ECHOPAIR_P(SP_X_LBL, dac_perc(X_AXIS), PSTR(" ("), dac_amps(X_AXIS), PSTR(")")); + #if HAS_Y_AXIS + SERIAL_ECHOPAIR_P(SP_Y_LBL, dac_perc(Y_AXIS), PSTR(" ("), dac_amps(Y_AXIS), PSTR(")")); + #endif + #if HAS_Z_AXIS + SERIAL_ECHOPAIR_P(SP_Z_LBL, dac_perc(Z_AXIS), PSTR(" ("), dac_amps(Z_AXIS), PSTR(")")); + #endif + #if HAS_EXTRUDERS + SERIAL_ECHOLNPAIR_P(SP_E_LBL, dac_perc(E_AXIS), PSTR(" ("), dac_amps(E_AXIS), PSTR(")")); + #endif } void StepperDAC::commit_eeprom() { diff --git a/Marlin/src/feature/leds/neopixel.h b/Marlin/src/feature/leds/neopixel.h index e577948cd8..b2c16459f5 100644 --- a/Marlin/src/feature/leds/neopixel.h +++ b/Marlin/src/feature/leds/neopixel.h @@ -114,7 +114,6 @@ public: #if CONJOINED_NEOPIXEL adaneo2.show(); #else - IF_DISABLED(NEOPIXEL2_SEPARATE, adaneo1.setPin(NEOPIXEL2_PIN)); adaneo1.show(); adaneo1.setPin(NEOPIXEL_PIN); #endif diff --git a/Marlin/src/feature/power.cpp b/Marlin/src/feature/power.cpp index fb2f1312e0..9b173d6ee7 100644 --- a/Marlin/src/feature/power.cpp +++ b/Marlin/src/feature/power.cpp @@ -33,6 +33,10 @@ #include "../module/stepper/indirection.h" #include "../MarlinCore.h" +#if ENABLED(PS_OFF_SOUND) + #include "../libs/buzzer.h" +#endif + #if defined(PSU_POWERUP_GCODE) || defined(PSU_POWEROFF_GCODE) #include "../gcode/gcode.h" #endif @@ -46,6 +50,9 @@ Power powerManager; millis_t Power::lastPowerOn; bool Power::is_power_needed() { + + if (printJobOngoing() || printingIsPaused()) return true; + #if ENABLED(AUTO_POWER_FANS) FANS_LOOP(i) if (thermalManager.fan_speed[i]) return true; #endif @@ -81,7 +88,10 @@ bool Power::is_power_needed() { #endif ) return true; - HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0 || thermalManager.temp_hotend[e].soft_pwm_amount > 0) return true; + #if HAS_HOTEND + HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0 || thermalManager.temp_hotend[e].soft_pwm_amount > 0) return true; + #endif + if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0 || thermalManager.temp_bed.soft_pwm_amount > 0)) return true; #if HAS_HOTEND && AUTO_POWER_E_TEMP @@ -103,20 +113,29 @@ bool Power::is_power_needed() { #define POWER_TIMEOUT 0 #endif -void Power::check() { +void Power::check(const bool pause) { + static bool _pause = false; static millis_t nextPowerCheck = 0; - millis_t ms = millis(); - if (ELAPSED(ms, nextPowerCheck)) { - nextPowerCheck = ms + 2500UL; + const millis_t now = millis(); + #if POWER_TIMEOUT > 0 + if (pause != _pause) { + lastPowerOn = now + !now; + _pause = pause; + } + if (pause) return; + #endif + if (ELAPSED(now, nextPowerCheck)) { + nextPowerCheck = now + 2500UL; if (is_power_needed()) power_on(); - else if (!lastPowerOn || (POWER_TIMEOUT > 0 && ELAPSED(ms, lastPowerOn + SEC_TO_MS(POWER_TIMEOUT)))) + else if (!lastPowerOn || (POWER_TIMEOUT > 0 && ELAPSED(now, lastPowerOn + SEC_TO_MS(POWER_TIMEOUT)))) power_off(); } } void Power::power_on() { - lastPowerOn = millis(); + const millis_t now = millis(); + lastPowerOn = now + !now; if (!powersupply_on) { PSU_PIN_ON(); safe_delay(PSU_POWERUP_DELAY); @@ -133,6 +152,11 @@ void Power::power_off() { #ifdef PSU_POWEROFF_GCODE GcodeSuite::process_subcommands_now_P(PSTR(PSU_POWEROFF_GCODE)); #endif + + #if ENABLED(PS_OFF_SOUND) + BUZZ(1000, 659); + #endif + PSU_PIN_OFF(); } } @@ -140,6 +164,7 @@ void Power::power_off() { void Power::power_off_soon() { #if POWER_OFF_DELAY lastPowerOn = millis() - SEC_TO_MS(POWER_TIMEOUT) + SEC_TO_MS(POWER_OFF_DELAY); + //if (!lastPowerOn) ++lastPowerOn; #else power_off(); #endif diff --git a/Marlin/src/feature/power.h b/Marlin/src/feature/power.h index 2462b9231b..bca5432946 100644 --- a/Marlin/src/feature/power.h +++ b/Marlin/src/feature/power.h @@ -29,7 +29,7 @@ class Power { public: - static void check(); + static void check(const bool pause); static void power_on(); static void power_off(); static void power_off_soon(); diff --git a/Marlin/src/feature/tmc_util.h b/Marlin/src/feature/tmc_util.h index 3a856b3af8..741b840ec7 100644 --- a/Marlin/src/feature/tmc_util.h +++ b/Marlin/src/feature/tmc_util.h @@ -361,10 +361,10 @@ void test_tmc_connection(LOGICAL_AXIS_DECL(const bool, true)); extern millis_t sg_guard_period; constexpr uint16_t default_sg_guard_duration = 400; - struct slow_homing_t { + struct motion_state_t { xy_ulong_t acceleration; #if ENABLED(HAS_CLASSIC_JERK) - xy_float_t jerk_xy; + xy_float_t jerk_state; #endif }; #endif diff --git a/Marlin/src/gcode/bedlevel/G26.cpp b/Marlin/src/gcode/bedlevel/G26.cpp index 616f16a58a..882197139e 100644 --- a/Marlin/src/gcode/bedlevel/G26.cpp +++ b/Marlin/src/gcode/bedlevel/G26.cpp @@ -291,7 +291,7 @@ typedef struct { if (p2.x < 0 || p2.x >= (GRID_MAX_POINTS_X)) return; if (p2.y < 0 || p2.y >= (GRID_MAX_POINTS_Y)) return; - if(circle_flags.marked(p1.x, p1.y) && circle_flags.marked(p2.x, p2.y)) { + if (circle_flags.marked(p1.x, p1.y) && circle_flags.marked(p2.x, p2.y)) { xyz_pos_t s, e; s.x = _GET_MESH_X(p1.x) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dx; e.x = _GET_MESH_X(p2.x) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dx; diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index 69cdd02d16..7cd1f65fbf 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -164,24 +164,24 @@ #if ENABLED(IMPROVE_HOMING_RELIABILITY) - slow_homing_t begin_slow_homing() { - slow_homing_t slow_homing{0}; - slow_homing.acceleration.set(planner.settings.max_acceleration_mm_per_s2[X_AXIS], + motion_state_t begin_slow_homing() { + motion_state_t motion_state{0}; + motion_state.acceleration.set(planner.settings.max_acceleration_mm_per_s2[X_AXIS], planner.settings.max_acceleration_mm_per_s2[Y_AXIS]); planner.settings.max_acceleration_mm_per_s2[X_AXIS] = 100; planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = 100; #if HAS_CLASSIC_JERK - slow_homing.jerk_xy = planner.max_jerk; + motion_state.jerk_state = planner.max_jerk; planner.max_jerk.set(0, 0); #endif planner.reset_acceleration_rates(); - return slow_homing; + return motion_state; } - void end_slow_homing(const slow_homing_t &slow_homing) { - planner.settings.max_acceleration_mm_per_s2[X_AXIS] = slow_homing.acceleration.x; - planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = slow_homing.acceleration.y; - TERN_(HAS_CLASSIC_JERK, planner.max_jerk = slow_homing.jerk_xy); + void end_slow_homing(const motion_state_t &motion_state) { + planner.settings.max_acceleration_mm_per_s2[X_AXIS] = motion_state.acceleration.x; + planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = motion_state.acceleration.y; + TERN_(HAS_CLASSIC_JERK, planner.max_jerk = motion_state.jerk_state); planner.reset_acceleration_rates(); } @@ -289,7 +289,9 @@ void GcodeSuite::G28() { #endif #endif - TERN_(IMPROVE_HOMING_RELIABILITY, slow_homing_t slow_homing = begin_slow_homing()); + #if ENABLED(IMPROVE_HOMING_RELIABILITY) + motion_state_t saved_motion_state = begin_slow_homing(); + #endif // Always home with tool 0 active #if HAS_MULTI_HOTEND @@ -315,7 +317,7 @@ void GcodeSuite::G28() { home_delta(); - TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(slow_homing)); + TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state)); #elif ENABLED(AXEL_TPARA) @@ -401,7 +403,7 @@ void GcodeSuite::G28() { if (DISABLED(HOME_Y_BEFORE_X) && doY) homeaxis(Y_AXIS); - TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(slow_homing)); + TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state)); // Home Z last if homing towards the bed #if HAS_Z_AXIS && DISABLED(HOME_Z_FIRST) @@ -440,7 +442,7 @@ void GcodeSuite::G28() { if (idex_is_duplicating()) { - TERN_(IMPROVE_HOMING_RELIABILITY, slow_homing = begin_slow_homing()); + TERN_(IMPROVE_HOMING_RELIABILITY, saved_motion_state = begin_slow_homing()); // Always home the 2nd (right) extruder first active_extruder = 1; @@ -459,7 +461,7 @@ void GcodeSuite::G28() { dual_x_carriage_mode = IDEX_saved_mode; set_duplication_enabled(IDEX_saved_duplication_state); - TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(slow_homing)); + TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state)); } #endif // DUAL_X_CARRIAGE diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp index 6869962028..50f3419c89 100644 --- a/Marlin/src/gcode/calibrate/G34_M422.cpp +++ b/Marlin/src/gcode/calibrate/G34_M422.cpp @@ -314,11 +314,13 @@ void GcodeSuite::G34() { sprintf_P(msg, PSTR("1:2=%s" TERN_(TRIPLE_Z, " 3-2=%s 3-1=%s") TERN_(QUAD_Z, " 4-3=%s 4-2=%s 4-1=%s")), dtostrf(ABS(z_measured[1] - z_measured[0]), 1, 3, fstr1) - OPTARG(TRIPLE_Z, dtostrf(ABS(z_measured[2] - z_measured[1]), 1, 3, fstr2)) - OPTARG(TRIPLE_Z, dtostrf(ABS(z_measured[2] - z_measured[0]), 1, 3, fstr3)) - OPTARG(QUAD_Z, dtostrf(ABS(z_measured[3] - z_measured[2]), 1, 3, fstr4)) - OPTARG(QUAD_Z, dtostrf(ABS(z_measured[3] - z_measured[1]), 1, 3, fstr5)) - OPTARG(QUAD_Z, dtostrf(ABS(z_measured[3] - z_measured[0]), 1, 3, fstr6)) + OPTARG(TRIPLE_Z, + dtostrf(ABS(z_measured[2] - z_measured[1]), 1, 3, fstr2), + dtostrf(ABS(z_measured[2] - z_measured[0]), 1, 3, fstr3)) + OPTARG(QUAD_Z, + dtostrf(ABS(z_measured[3] - z_measured[2]), 1, 3, fstr4), + dtostrf(ABS(z_measured[3] - z_measured[1]), 1, 3, fstr5), + dtostrf(ABS(z_measured[3] - z_measured[0]), 1, 3, fstr6)) ); ui.set_status(msg); #endif diff --git a/Marlin/src/gcode/calibrate/M666.cpp b/Marlin/src/gcode/calibrate/M666.cpp index a3a48cd3fc..8ff51f0e3f 100644 --- a/Marlin/src/gcode/calibrate/M666.cpp +++ b/Marlin/src/gcode/calibrate/M666.cpp @@ -71,29 +71,27 @@ #endif #if ENABLED(Z_MULTI_ENDSTOPS) if (parser.seenval('Z')) { - #if NUM_Z_STEPPER_DRIVERS >= 3 - const float z_adj = parser.value_linear_units(); - const int ind = parser.intval('S'); - if (!ind || ind == 2) endstops.z2_endstop_adj = z_adj; - if (!ind || ind == 3) endstops.z3_endstop_adj = z_adj; - #if NUM_Z_STEPPER_DRIVERS >= 4 - if (!ind || ind == 4) endstops.z4_endstop_adj = z_adj; - #endif + const float z_adj = parser.value_linear_units(); + #if NUM_Z_STEPPER_DRIVERS == 2 + endstops.z2_endstop_adj = z_adj; #else - endstops.z2_endstop_adj = parser.value_linear_units(); + const int ind = parser.intval('S'); + #define _SET_ZADJ(N) if (!ind || ind == N) endstops.z##N##_endstop_adj = z_adj; + REPEAT_S(2, INCREMENT(NUM_Z_STEPPER_DRIVERS), _SET_ZADJ) #endif } #endif if (!parser.seen("XYZ")) { + auto echo_adj = [](PGM_P const label, const_float_t value) { SERIAL_ECHOPAIR_P(label, value); }; SERIAL_ECHOPGM("Dual Endstop Adjustment (mm): "); #if ENABLED(X_DUAL_ENDSTOPS) - SERIAL_ECHOPAIR(" X2:", endstops.x2_endstop_adj); + echo_adj(PSTR(" X2:"), endstops.x2_endstop_adj); #endif #if ENABLED(Y_DUAL_ENDSTOPS) - SERIAL_ECHOPAIR(" Y2:", endstops.y2_endstop_adj); + echo_adj(PSTR(" Y2:"), endstops.y2_endstop_adj); #endif #if ENABLED(Z_MULTI_ENDSTOPS) - #define _ECHO_ZADJ(N) SERIAL_ECHOPAIR(" Z" STRINGIFY(N) ":", endstops.z##N##_endstop_adj); + #define _ECHO_ZADJ(N) echo_adj(PSTR(" Z" STRINGIFY(N) ":"), endstops.z##N##_endstop_adj); REPEAT_S(2, INCREMENT(NUM_Z_STEPPER_DRIVERS), _ECHO_ZADJ) #endif SERIAL_EOL(); diff --git a/Marlin/src/gcode/feature/L6470/M906.cpp b/Marlin/src/gcode/feature/L6470/M906.cpp index 90fd6c487e..dddf7f8aee 100644 --- a/Marlin/src/gcode/feature/L6470/M906.cpp +++ b/Marlin/src/gcode/feature/L6470/M906.cpp @@ -32,31 +32,6 @@ #define DEBUG_OUT ENABLED(L6470_CHITCHAT) #include "../../../core/debug_out.h" -/** - * M906: report or set KVAL_HOLD which sets the maximum effective voltage provided by the - * PWMs to the steppers - * - * On L6474 this sets the TVAL register (same address). - * - * I - select which driver(s) to change on multi-driver axis - * 0 - (default) all drivers on the axis or E0 - * 1 - monitor only X, Y, Z or E1 - * 2 - monitor only X2, Y2, Z2 or E2 - * 3 - monitor only Z3 or E3 - * 4 - monitor only Z4 or E4 - * 5 - monitor only E5 - * Xxxx, Yxxx, Zxxx, Exxx - axis to change (optional) - * L6474 - current in mA (4A max) - * All others - 0-255 - */ - -/** - * Sets KVAL_HOLD wich affects the current being driven through the stepper. - * - * L6470 is used in the STEP-CLOCK mode. KVAL_HOLD is the only KVAL_xxx - * that affects the effective voltage seen by the stepper. - */ - /** * MACRO to fetch information on the items associated with current limiting * and maximum voltage output. @@ -220,6 +195,28 @@ void L64XX_report_current(L64XX &motor, const L64XX_axis_t axis) { } } +/** + * M906: report or set KVAL_HOLD which sets the maximum effective voltage provided by the + * PWMs to the steppers + * + * On L6474 this sets the TVAL register (same address). + * + * I - select which driver(s) to change on multi-driver axis + * 0 - (default) all drivers on the axis or E0 + * 1 - monitor only X, Y, Z or E1 + * 2 - monitor only X2, Y2, Z2 or E2 + * 3 - monitor only Z3 or E3 + * 4 - monitor only Z4 or E4 + * 5 - monitor only E5 + * Xxxx, Yxxx, Zxxx, Exxx - axis to change (optional) + * L6474 - current in mA (4A max) + * All others - 0-255 + * + * Sets KVAL_HOLD wich affects the current being driven through the stepper. + * + * L6470 is used in the STEP-CLOCK mode. KVAL_HOLD is the only KVAL_xxx + * that affects the effective voltage seen by the stepper. + */ void GcodeSuite::M906() { L64xxManager.pause_monitor(true); // Keep monitor_driver() from stealing status @@ -281,11 +278,11 @@ void GcodeSuite::M906() { break; #endif - #if HAS_EXTRUDERS + #if E_STEPPERS case E_AXIS: { - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; - switch (target_extruder) { + const int8_t target_e_stepper = get_target_e_stepper_from_command(); + if (target_e_stepper < 0) return; + switch (target_e_stepper) { #if AXIS_IS_L64XX(E0) case 0: L6470_SET_KVAL_HOLD(E0); break; #endif diff --git a/Marlin/src/gcode/feature/leds/M150.cpp b/Marlin/src/gcode/feature/leds/M150.cpp index 5d175ea8f7..4d271007e5 100644 --- a/Marlin/src/gcode/feature/leds/M150.cpp +++ b/Marlin/src/gcode/feature/leds/M150.cpp @@ -52,14 +52,16 @@ * M150 I1 R ; Set NEOPIXEL index 1 to red * M150 S1 I1 R ; Set SEPARATE index 1 to red */ - void GcodeSuite::M150() { #if ENABLED(NEOPIXEL_LED) - const uint8_t index = parser.intval('I', -1); + const int8_t index = parser.intval('I', -1); #if ENABLED(NEOPIXEL2_SEPARATE) - const uint8_t unit = parser.intval('S'), - brightness = unit ? neo2.brightness() : neo.brightness(); - *(unit ? &neo2.neoindex : &neo.neoindex) = index; + int8_t brightness, unit = parser.intval('S', -1); + switch (unit) { + case -1: neo2.neoindex = index; // fall-thru + case 0: neo.neoindex = index; brightness = neo.brightness(); break; + case 1: neo2.neoindex = index; brightness = neo2.brightness(); break; + } #else const uint8_t brightness = neo.brightness(); neo.neoindex = index; @@ -75,10 +77,15 @@ void GcodeSuite::M150() { ); #if ENABLED(NEOPIXEL2_SEPARATE) - if (unit == 1) { leds2.set_color(color); return; } + switch (unit) { + case 0: leds.set_color(color); return; + case 1: leds2.set_color(color); return; + } #endif + // If 'S' is not specified use both leds.set_color(color); + TERN_(NEOPIXEL2_SEPARATE, leds2.set_color(color)); } #endif // HAS_COLOR_LEDS diff --git a/Marlin/src/gcode/feature/pause/M125.cpp b/Marlin/src/gcode/feature/pause/M125.cpp index 2eb4ceea41..bc31e1225d 100644 --- a/Marlin/src/gcode/feature/pause/M125.cpp +++ b/Marlin/src/gcode/feature/pause/M125.cpp @@ -56,7 +56,7 @@ */ void GcodeSuite::M125() { // Initial retract before move to filament change position - const float retract = -ABS(parser.axisunitsval('L', E_AXIS, PAUSE_PARK_RETRACT_LENGTH)); + const float retract = TERN0(HAS_EXTRUDERS, -ABS(parser.axisunitsval('L', E_AXIS, PAUSE_PARK_RETRACT_LENGTH))); xyz_pos_t park_point = NOZZLE_PARK_POINT; diff --git a/Marlin/src/gcode/feature/trinamic/M569.cpp b/Marlin/src/gcode/feature/trinamic/M569.cpp index a3fb07df13..9a7f1fbce9 100644 --- a/Marlin/src/gcode/feature/trinamic/M569.cpp +++ b/Marlin/src/gcode/feature/trinamic/M569.cpp @@ -40,7 +40,7 @@ void tmc_set_stealthChop(TMC &st, const bool enable) { st.refresh_stepping_mode(); } -static void set_stealth_status(const bool enable, const int8_t target_extruder) { +static void set_stealth_status(const bool enable, const int8_t target_e_stepper) { #define TMC_SET_STEALTH(Q) tmc_set_stealthChop(stepper##Q, enable) #if X_HAS_STEALTHCHOP || Y_HAS_STEALTHCHOP || Z_HAS_STEALTHCHOP \ @@ -82,17 +82,19 @@ static void set_stealth_status(const bool enable, const int8_t target_extruder) case K_AXIS: TMC_SET_STEALTH(K); break; #endif - #if HAS_EXTRUDERS + #if E_STEPPERS case E_AXIS: { - if (target_extruder < 0) return; - OPTCODE(E0_HAS_STEALTHCHOP, else if (target_extruder == 0) TMC_SET_STEALTH(E0)) - OPTCODE(E1_HAS_STEALTHCHOP, else if (target_extruder == 1) TMC_SET_STEALTH(E1)) - OPTCODE(E2_HAS_STEALTHCHOP, else if (target_extruder == 2) TMC_SET_STEALTH(E2)) - OPTCODE(E3_HAS_STEALTHCHOP, else if (target_extruder == 3) TMC_SET_STEALTH(E3)) - OPTCODE(E4_HAS_STEALTHCHOP, else if (target_extruder == 4) TMC_SET_STEALTH(E4)) - OPTCODE(E5_HAS_STEALTHCHOP, else if (target_extruder == 5) TMC_SET_STEALTH(E5)) - OPTCODE(E6_HAS_STEALTHCHOP, else if (target_extruder == 6) TMC_SET_STEALTH(E6)) - OPTCODE(E7_HAS_STEALTHCHOP, else if (target_extruder == 7) TMC_SET_STEALTH(E7)) + if (target_e_stepper < 0) return; + switch (target_e_stepper) { + TERN_(E0_HAS_STEALTHCHOP, case 0: TMC_SET_STEALTH(E0); break;) + TERN_(E1_HAS_STEALTHCHOP, case 1: TMC_SET_STEALTH(E1); break;) + TERN_(E2_HAS_STEALTHCHOP, case 2: TMC_SET_STEALTH(E2); break;) + TERN_(E3_HAS_STEALTHCHOP, case 3: TMC_SET_STEALTH(E3); break;) + TERN_(E4_HAS_STEALTHCHOP, case 4: TMC_SET_STEALTH(E4); break;) + TERN_(E5_HAS_STEALTHCHOP, case 5: TMC_SET_STEALTH(E5); break;) + TERN_(E6_HAS_STEALTHCHOP, case 6: TMC_SET_STEALTH(E6); break;) + TERN_(E7_HAS_STEALTHCHOP, case 7: TMC_SET_STEALTH(E7); break;) + } } break; #endif } @@ -131,7 +133,7 @@ static void say_stealth_status() { */ void GcodeSuite::M569() { if (parser.seen('S')) - set_stealth_status(parser.value_bool(), get_target_extruder_from_command()); + set_stealth_status(parser.value_bool(), get_target_e_stepper_from_command()); else say_stealth_status(); } diff --git a/Marlin/src/gcode/feature/trinamic/M906.cpp b/Marlin/src/gcode/feature/trinamic/M906.cpp index 70e6a00b36..9e56e51358 100644 --- a/Marlin/src/gcode/feature/trinamic/M906.cpp +++ b/Marlin/src/gcode/feature/trinamic/M906.cpp @@ -102,11 +102,11 @@ void GcodeSuite::M906() { case K_AXIS: TMC_SET_CURRENT(K); break; #endif - #if HAS_EXTRUDERS + #if E_STEPPERS case E_AXIS: { - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; - switch (target_extruder) { + const int8_t target_e_stepper = get_target_e_stepper_from_command(); + if (target_e_stepper < 0) return; + switch (target_e_stepper) { #if AXIS_IS_TMC(E0) case 0: TMC_SET_CURRENT(E0); break; #endif diff --git a/Marlin/src/gcode/feature/trinamic/M911-M914.cpp b/Marlin/src/gcode/feature/trinamic/M911-M914.cpp index 747f1c9516..f90a30aab2 100644 --- a/Marlin/src/gcode/feature/trinamic/M911-M914.cpp +++ b/Marlin/src/gcode/feature/trinamic/M911-M914.cpp @@ -265,20 +265,22 @@ TERN_(Z3_HAS_STEALTCHOP, if (index == 0 || index == 3) TMC_SET_PWMTHRS(Z,Z3)); TERN_(Z4_HAS_STEALTCHOP, if (index == 0 || index == 4) TMC_SET_PWMTHRS(Z,Z4)); break; - case E_AXIS: { - #if E_STEPPERS - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; - TERN_(E0_HAS_STEALTHCHOP, else if (target_extruder == 0) TMC_SET_PWMTHRS_E(0)); - TERN_(E1_HAS_STEALTHCHOP, else if (target_extruder == 1) TMC_SET_PWMTHRS_E(1)); - TERN_(E2_HAS_STEALTHCHOP, else if (target_extruder == 2) TMC_SET_PWMTHRS_E(2)); - TERN_(E3_HAS_STEALTHCHOP, else if (target_extruder == 3) TMC_SET_PWMTHRS_E(3)); - TERN_(E4_HAS_STEALTHCHOP, else if (target_extruder == 4) TMC_SET_PWMTHRS_E(4)); - TERN_(E5_HAS_STEALTHCHOP, else if (target_extruder == 5) TMC_SET_PWMTHRS_E(5)); - TERN_(E6_HAS_STEALTHCHOP, else if (target_extruder == 6) TMC_SET_PWMTHRS_E(6)); - TERN_(E7_HAS_STEALTHCHOP, else if (target_extruder == 7) TMC_SET_PWMTHRS_E(7)); - #endif // E_STEPPERS - } break; + #if E_STEPPERS + case E_AXIS: { + const int8_t target_e_stepper = get_target_e_stepper_from_command(); + if (target_e_stepper < 0) return; + switch (target_e_stepper) { + TERN_(E0_HAS_STEALTHCHOP, case 0: TMC_SET_PWMTHRS_E(0); break;) + TERN_(E1_HAS_STEALTHCHOP, case 1: TMC_SET_PWMTHRS_E(1); break;) + TERN_(E2_HAS_STEALTHCHOP, case 2: TMC_SET_PWMTHRS_E(2); break;) + TERN_(E3_HAS_STEALTHCHOP, case 3: TMC_SET_PWMTHRS_E(3); break;) + TERN_(E4_HAS_STEALTHCHOP, case 4: TMC_SET_PWMTHRS_E(4); break;) + TERN_(E5_HAS_STEALTHCHOP, case 5: TMC_SET_PWMTHRS_E(5); break;) + TERN_(E6_HAS_STEALTHCHOP, case 6: TMC_SET_PWMTHRS_E(6); break;) + TERN_(E7_HAS_STEALTHCHOP, case 7: TMC_SET_PWMTHRS_E(7); break;) + } + } break; + #endif // E_STEPPERS } } diff --git a/Marlin/src/gcode/host/M114.cpp b/Marlin/src/gcode/host/M114.cpp index 2fdce1edfd..7d69033319 100644 --- a/Marlin/src/gcode/host/M114.cpp +++ b/Marlin/src/gcode/host/M114.cpp @@ -216,10 +216,12 @@ void GcodeSuite::M114() { report_current_position_detail(); return; } - if (parser.seen_test('E')) { - SERIAL_ECHOLNPAIR("Count E:", stepper.position(E_AXIS)); - return; - } + #if HAS_EXTRUDERS + if (parser.seen_test('E')) { + SERIAL_ECHOLNPAIR("Count E:", stepper.position(E_AXIS)); + return; + } + #endif #endif #if ENABLED(M114_REALTIME) diff --git a/Marlin/src/gcode/parser.h b/Marlin/src/gcode/parser.h index 5a1748cc4d..08cf10004a 100644 --- a/Marlin/src/gcode/parser.h +++ b/Marlin/src/gcode/parser.h @@ -311,7 +311,13 @@ public: } static inline float axis_unit_factor(const AxisEnum axis) { - return (axis >= E_AXIS && volumetric_enabled ? volumetric_unit_factor : linear_unit_factor); + return ( + #if HAS_EXTRUDERS + axis >= E_AXIS && volumetric_enabled ? volumetric_unit_factor : linear_unit_factor + #else + linear_unit_factor + #endif + ); } static inline float linear_value_to_mm(const_float_t v) { return v * linear_unit_factor; } diff --git a/Marlin/src/gcode/sd/M20.cpp b/Marlin/src/gcode/sd/M20.cpp index 7ac4affdae..5731838338 100644 --- a/Marlin/src/gcode/sd/M20.cpp +++ b/Marlin/src/gcode/sd/M20.cpp @@ -33,7 +33,7 @@ void GcodeSuite::M20() { if (card.flag.mounted) { SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST); - card.ls(); + card.ls(TERN_(LONG_FILENAME_HOST_SUPPORT, parser.boolval('L'))); SERIAL_ECHOLNPGM(STR_END_FILE_LIST); } else diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index b82cf32d8b..c65c17558f 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -1078,7 +1078,11 @@ #if ENABLED(DWIN_CREALITY_LCD) #define SERIAL_CATCHALL -1 #ifndef LCD_SERIAL_PORT - #define LCD_SERIAL_PORT 3 // Creality 4.x board + #if MB(BTT_SKR_MINI_E3_V1_0, BTT_SKR_MINI_E3_V1_2, BTT_SKR_MINI_E3_V2_0, BTT_SKR_E3_TURBO) + #define LCD_SERIAL_PORT 1 + #else + #define LCD_SERIAL_PORT 3 // Creality 4.x board + #endif #endif #endif diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 503bec59fe..862b4a6cb6 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -526,102 +526,110 @@ #undef ANY_TEMP_SENSOR_IS // Usurp a sensor to do redundant readings -#if TEMP_SENSOR_REDUNDANT && !PIN_EXISTS(TEMP_REDUNDANT) - #if TEMP_SENSOR_REDUNDANT_SOURCE == -5 - #if !PIN_EXISTS(TEMP_COOLER) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to COOLER requires TEMP_COOLER_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_COOLER_PIN - #endif - #elif TEMP_SENSOR_REDUNDANT_SOURCE == -4 - #if !PIN_EXISTS(TEMP_PROBE) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to PROBE requires TEMP_PROBE_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_PROBE_PIN - #endif - #elif TEMP_SENSOR_REDUNDANT_SOURCE == -2 - #if !PIN_EXISTS(TEMP_CHAMBER) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to CHAMBER requires TEMP_CHAMBER_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_CHAMBER_PIN - #endif - #elif TEMP_SENSOR_REDUNDANT_SOURCE == -1 - #if !PIN_EXISTS(TEMP_BED) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to BED requires TEMP_BED_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_BED_PIN - #endif - #elif TEMP_SENSOR_REDUNDANT_SOURCE == 0 - #if !PIN_EXISTS(TEMP_0) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 0 requires TEMP_0_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_0_PIN - #endif - #elif TEMP_SENSOR_REDUNDANT_SOURCE == 1 - #if !PIN_EXISTS(TEMP_1) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 1 requires TEMP_1_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_1_PIN - #endif - #elif TEMP_SENSOR_REDUNDANT_SOURCE == 2 - #if !PIN_EXISTS(TEMP_2) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 2 requires TEMP_2_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_2_PIN - #endif - #elif TEMP_SENSOR_REDUNDANT_SOURCE == 3 - #if !PIN_EXISTS(TEMP_3) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 3 requires TEMP_3_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_3_PIN - #endif - #elif TEMP_SENSOR_REDUNDANT_SOURCE == 4 - #if !PIN_EXISTS(TEMP_4) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 4 requires TEMP_4_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_4_PIN - #endif - #elif TEMP_SENSOR_REDUNDANT_SOURCE == 5 - #if !PIN_EXISTS(TEMP_5) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 5 requires TEMP_5_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_5_PIN - #endif - #elif TEMP_SENSOR_REDUNDANT_SOURCE == 6 - #if !PIN_EXISTS(TEMP_6) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 6 requires TEMP_6_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_6_PIN - #endif - #elif TEMP_SENSOR_REDUNDANT_SOURCE == 7 - #if !PIN_EXISTS(TEMP_7) - #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 7 requires TEMP_7_PIN." - #else - #define TEMP_REDUNDANT_PIN TEMP_7_PIN - #endif +#if TEMP_SENSOR_REDUNDANT + #ifndef TEMP_SENSOR_REDUNDANT_SOURCE + #define TEMP_SENSOR_REDUNDANT_SOURCE 1 #endif - - #ifndef TEMP_SENSOR_REDUNDANT_MAX_DIFF - #define TEMP_SENSOR_REDUNDANT_MAX_DIFF 10 + #ifndef TEMP_SENSOR_REDUNDANT_TARGET + #define TEMP_SENSOR_REDUNDANT_TARGET 0 + #endif + #if !PIN_EXISTS(TEMP_REDUNDANT) + #ifndef TEMP_SENSOR_REDUNDANT_MAX_DIFF + #define TEMP_SENSOR_REDUNDANT_MAX_DIFF 10 + #endif + #if TEMP_SENSOR_REDUNDANT_SOURCE == -5 + #if !PIN_EXISTS(TEMP_COOLER) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to COOLER requires TEMP_COOLER_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_COOLER_PIN + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == -4 + #if !PIN_EXISTS(TEMP_PROBE) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to PROBE requires TEMP_PROBE_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_PROBE_PIN + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == -2 + #if !PIN_EXISTS(TEMP_CHAMBER) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to CHAMBER requires TEMP_CHAMBER_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_CHAMBER_PIN + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == -1 + #if !PIN_EXISTS(TEMP_BED) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to BED requires TEMP_BED_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_BED_PIN + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == 0 + #if !PIN_EXISTS(TEMP_0) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 0 requires TEMP_0_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_0_PIN + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == 1 + #if !PIN_EXISTS(TEMP_1) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 1 requires TEMP_1_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_1_PIN + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == 2 + #if !PIN_EXISTS(TEMP_2) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 2 requires TEMP_2_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_2_PIN + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == 3 + #if !PIN_EXISTS(TEMP_3) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 3 requires TEMP_3_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_3_PIN + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == 4 + #if !PIN_EXISTS(TEMP_4) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 4 requires TEMP_4_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_4_PIN + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == 5 + #if !PIN_EXISTS(TEMP_5) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 5 requires TEMP_5_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_5_PIN + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == 6 + #if !PIN_EXISTS(TEMP_6) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 6 requires TEMP_6_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_6_PIN + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == 7 + #if !PIN_EXISTS(TEMP_7) + #error "TEMP_SENSOR_REDUNDANT_SOURCE set to 7 requires TEMP_7_PIN." + #else + #define TEMP_REDUNDANT_PIN TEMP_7_PIN + #endif + #endif #endif #endif #if TEMP_SENSOR_0 == -5 || TEMP_SENSOR_0 == -3 || TEMP_SENSOR_0 == -2 #define TEMP_SENSOR_0_IS_MAX_TC 1 - #define HAS_MAX_TC 1 - #if TEMP_SENSOR_0 == -3 - #define TEMP_SENSOR_0_MAX_TC_TMIN -270 - #define TEMP_SENSOR_0_MAX_TC_TMAX 1800 - #else - #define TEMP_SENSOR_0_MAX_TC_TMIN 0 - #define TEMP_SENSOR_0_MAX_TC_TMAX 1024 - #endif #if TEMP_SENSOR_0 == -5 #define TEMP_SENSOR_0_IS_MAX31865 1 + #define TEMP_SENSOR_0_MAX_TC_TMIN 0 + #define TEMP_SENSOR_0_MAX_TC_TMAX 1024 + #ifndef MAX31865_SENSOR_WIRES_0 + #define MAX31865_SENSOR_WIRES_0 2 + #endif #elif TEMP_SENSOR_0 == -3 #define TEMP_SENSOR_0_IS_MAX31855 1 + #define TEMP_SENSOR_0_MAX_TC_TMIN -270 + #define TEMP_SENSOR_0_MAX_TC_TMAX 1800 #elif TEMP_SENSOR_0 == -2 #define TEMP_SENSOR_0_IS_MAX6675 1 + #define TEMP_SENSOR_0_MAX_TC_TMIN 0 + #define TEMP_SENSOR_0_MAX_TC_TMAX 1024 #endif #elif TEMP_SENSOR_0 == -4 #define TEMP_SENSOR_0_IS_AD8495 1 @@ -641,21 +649,23 @@ #if TEMP_SENSOR_1 == -5 || TEMP_SENSOR_1 == -3 || TEMP_SENSOR_1 == -2 #define TEMP_SENSOR_1_IS_MAX_TC 1 - #define HAS_MAX_TC 1 - #if TEMP_SENSOR_1 == -3 + #if TEMP_SENSOR_1 == -5 + #define TEMP_SENSOR_1_IS_MAX31865 1 + #define TEMP_SENSOR_1_MAX_TC_TMIN 0 + #define TEMP_SENSOR_1_MAX_TC_TMAX 1024 + #ifndef MAX31865_SENSOR_WIRES_1 + #define MAX31865_SENSOR_WIRES_1 2 + #endif + #elif TEMP_SENSOR_1 == -3 + #define TEMP_SENSOR_1_IS_MAX31855 1 #define TEMP_SENSOR_1_MAX_TC_TMIN -270 #define TEMP_SENSOR_1_MAX_TC_TMAX 1800 - #else + #elif TEMP_SENSOR_1 == -2 + #define TEMP_SENSOR_1_IS_MAX6675 1 #define TEMP_SENSOR_1_MAX_TC_TMIN 0 #define TEMP_SENSOR_1_MAX_TC_TMAX 1024 #endif - #if TEMP_SENSOR_1 == -5 - #define TEMP_SENSOR_1_IS_MAX31865 1 - #elif TEMP_SENSOR_1 == -3 - #define TEMP_SENSOR_1_IS_MAX31855 1 - #elif TEMP_SENSOR_1 == -2 - #define TEMP_SENSOR_1_IS_MAX6675 1 - #endif + #if TEMP_SENSOR_1 != TEMP_SENSOR_0 #if TEMP_SENSOR_1 == -5 #error "If MAX31865 Thermocouple (-5) is used for TEMP_SENSOR_1 then TEMP_SENSOR_0 must match." @@ -683,37 +693,48 @@ #if TEMP_SENSOR_REDUNDANT == -5 || TEMP_SENSOR_REDUNDANT == -3 || TEMP_SENSOR_REDUNDANT == -2 #define TEMP_SENSOR_REDUNDANT_IS_MAX_TC 1 - #define HAS_MAX_TC 1 - #if TEMP_SENSOR_REDUNDANT == -3 - #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN -270 - #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX 1800 - #else - #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN 0 - #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX 1024 - #endif - #if TEMP_SENSOR_REDUNDANT_SOURCE == 0 - #define TEMP_SENSOR_0_MAX_TC_TMIN TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN - #define TEMP_SENSOR_0_MAX_TC_TMAX TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX - #elif TEMP_SENSOR_REDUNDANT_SOURCE == 1 - #define TEMP_SENSOR_1_MAX_TC_TMIN TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN - #define TEMP_SENSOR_1_MAX_TC_TMAX TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX - #endif + #if TEMP_SENSOR_REDUNDANT == -5 #if TEMP_SENSOR_REDUNDANT_SOURCE != 0 && TEMP_SENSOR_REDUNDANT_SOURCE != 1 #error "MAX31865 Thermocouples (-5) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1 (0/1)." #endif - #define TEMP_SENSOR_REDUNDANT_IS_MAX31865 1 + + #define TEMP_SENSOR_REDUNDANT_IS_MAX31865 1 + #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN 0 + #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX 1024 #elif TEMP_SENSOR_REDUNDANT == -3 #if TEMP_SENSOR_REDUNDANT_SOURCE != 0 && TEMP_SENSOR_REDUNDANT_SOURCE != 1 #error "MAX31855 Thermocouples (-3) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1 (0/1)." #endif - #define TEMP_SENSOR_REDUNDANT_IS_MAX31855 1 + + #define TEMP_SENSOR_REDUNDANT_IS_MAX31855 1 + #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN -270 + #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX 1800 #elif TEMP_SENSOR_REDUNDANT == -2 #if TEMP_SENSOR_REDUNDANT_SOURCE != 0 && TEMP_SENSOR_REDUNDANT_SOURCE != 1 #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1 (0/1)." #endif - #define TEMP_SENSOR_REDUNDANT_IS_MAX6675 1 + + #define TEMP_SENSOR_REDUNDANT_IS_MAX6675 1 + #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN 0 + #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX 1024 #endif + + // mimic setting up the source TEMP_SENSOR + #if TEMP_SENSOR_REDUNDANT_SOURCE == 0 + #define TEMP_SENSOR_0_MAX_TC_TMIN TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN + #define TEMP_SENSOR_0_MAX_TC_TMAX TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX + #ifndef MAX31865_SENSOR_WIRES_0 + #define MAX31865_SENSOR_WIRES_0 2 + #endif + #elif TEMP_SENSOR_REDUNDANT_SOURCE == 1 + #define TEMP_SENSOR_1_MAX_TC_TMIN TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN + #define TEMP_SENSOR_1_MAX_TC_TMAX TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX + #ifndef MAX31865_SENSOR_WIRES_1 + #define MAX31865_SENSOR_WIRES_1 2 + #endif + #endif + #if (TEMP_SENSOR_0_IS_MAX_TC && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_0) || (TEMP_SENSOR_1_IS_MAX_TC && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_1) #if TEMP_SENSOR_REDUNDANT == -5 #error "If MAX31865 Thermocouple (-5) is used for TEMP_SENSOR_0/TEMP_SENSOR_1 then TEMP_SENSOR_REDUNDANT must match." @@ -736,101 +757,182 @@ #endif #endif +#if TEMP_SENSOR_0_IS_MAX_TC || TEMP_SENSOR_1_IS_MAX_TC || TEMP_SENSOR_REDUNDANT_IS_MAX_TC + #define HAS_MAX_TC 1 +#endif +#if TEMP_SENSOR_0_IS_MAX6675 || TEMP_SENSOR_1_IS_MAX6675 || TEMP_SENSOR_REDUNDANT_IS_MAX6675 + #define HAS_MAX6675 1 +#endif #if TEMP_SENSOR_0_IS_MAX31855 || TEMP_SENSOR_1_IS_MAX31855 || TEMP_SENSOR_REDUNDANT_IS_MAX31855 #define HAS_MAX31855 1 #endif #if TEMP_SENSOR_0_IS_MAX31865 || TEMP_SENSOR_1_IS_MAX31865 || TEMP_SENSOR_REDUNDANT_IS_MAX31865 #define HAS_MAX31865 1 #endif -#if TEMP_SENSOR_0_IS_MAX6675 || TEMP_SENSOR_1_IS_MAX6675 || TEMP_SENSOR_REDUNDANT_IS_MAX6675 - #define HAS_MAX6675 1 -#endif // // Compatibility layer for MAX (SPI) temp boards // -#define TEMP_SENSOR_IS_MAX(n, M) (ENABLED(TEMP_SENSOR_##n##_IS_##M) || (ENABLED(TEMP_SENSOR_REDUNDANT_IS_##M) && TEMP_SENSOR_REDUNDANT_SOURCE == (n))) +#if HAS_MAX_TC -#if PIN_EXISTS(MAX6675_SS) - #if TEMP_SENSOR_IS_MAX(0, MAX31855) - #define MAX31855_CS_PIN MAX6675_SS_PIN - #elif TEMP_SENSOR_IS_MAX(0, MAX31865) - #define MAX31865_CS_PIN MAX6675_SS_PIN - #elif TEMP_SENSOR_IS_MAX(0, MAX6675) - #define MAX6675_CS_PIN MAX6675_SS_PIN + // Translate old _SS, _CS, _SCK, _DO, _DI, _MISO, and _MOSI PIN defines. + #if TEMP_SENSOR_0_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 1) + + #if !PIN_EXISTS(TEMP_0_CS) // SS, CS + #if PIN_EXISTS(MAX6675_SS) + #define TEMP_0_CS_PIN MAX6675_SS_PIN + #elif PIN_EXISTS(MAX6675_CS) + #define TEMP_0_CS_PIN MAX6675_CS_PIN + #elif PIN_EXISTS(MAX31855_SS) + #define TEMP_0_CS_PIN MAX31855_SS_PIN + #elif PIN_EXISTS(MAX31855_CS) + #define TEMP_0_CS_PIN MAX31855_CS_PIN + #elif PIN_EXISTS(MAX31865_SS) + #define TEMP_0_CS_PIN MAX31865_SS_PIN + #elif PIN_EXISTS(MAX31865_CS) + #define TEMP_0_CS_PIN MAX31865_CS_PIN + #endif + #endif + + #if TEMP_SENSOR_0_IS_MAX6675 + #if !PIN_EXISTS(TEMP_0_MISO) // DO + #if PIN_EXISTS(MAX6675_MISO) + #define TEMP_0_MISO_PIN MAX6675_MISO_PIN + #elif PIN_EXISTS(MAX6675_DO) + #define TEMP_0_MISO_PIN MAX6675_DO_PIN + #endif + #endif + #if !PIN_EXISTS(TEMP_0_SCK) && PIN_EXISTS(MAX6675_SCK) + #define TEMP_0_SCK_PIN MAX6675_SCK_PIN + #endif + + #elif TEMP_SENSOR_0_IS_MAX31855 + #if !PIN_EXISTS(TEMP_0_MISO) // DO + #if PIN_EXISTS(MAX31855_MISO) + #define TEMP_0_MISO_PIN MAX31855_MISO_PIN + #elif PIN_EXISTS(MAX31855_DO) + #define TEMP_0_MISO_PIN MAX31855_DO_PIN + #endif + #endif + #if !PIN_EXISTS(TEMP_0_SCK) && PIN_EXISTS(MAX31855_SCK) + #define TEMP_0_SCK_PIN MAX31855_SCK_PIN + #endif + + #elif TEMP_SENSOR_1_IS_MAX31865 + #if !PIN_EXISTS(TEMP_1_MISO) // DO + #if PIN_EXISTS(MAX31865_MISO) + #define TEMP_1_MISO_PIN MAX31865_MISO_PIN + #elif PIN_EXISTS(MAX31865_DO) + #define TEMP_1_MISO_PIN MAX31865_DO_PIN + #endif + #endif + #if !PIN_EXISTS(TEMP_1_SCK) && PIN_EXISTS(MAX31865_SCK) + #define TEMP_1_SCK_PIN MAX31865_SCK_PIN + #endif + #if !PIN_EXISTS(TEMP_1_MOSI) && PIN_EXISTS(MAX31865_MOSI) // MOSI for '65 only + #define TEMP_1_MOSI_PIN MAX31865_MOSI_PIN + #endif + #endif + + // Software SPI - enable if MISO/SCK are defined. + #if PIN_EXISTS(TEMP_0_MISO) && PIN_EXISTS(TEMP_0_SCK) && DISABLED(TEMP_SENSOR_0_FORCE_HW_SPI) + #if TEMP_SENSOR_0_IS_MAX31865 && !PIN_EXISTS(TEMP_0_MOSI) + #error "TEMP_SENSOR_0 MAX31865 requires TEMP_0_MOSI_PIN defined for Software SPI. To use Hardware SPI instead, undefine MISO/SCK or enable TEMP_SENSOR_0_FORCE_HW_SPI." + #else + #define TEMP_SENSOR_0_HAS_SPI_PINS 1 + #endif + #endif + + #endif // TEMP_SENSOR_0_IS_MAX_TC + + #if TEMP_SENSOR_1_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 1) + + #if !PIN_EXISTS(TEMP_1_CS) // SS2, CS2 + #if PIN_EXISTS(MAX6675_SS2) + #define TEMP_1_CS_PIN MAX6675_SS2_PIN + #elif PIN_EXISTS(MAX6675_CS) + #define TEMP_1_CS_PIN MAX6675_CS2_PIN + #elif PIN_EXISTS(MAX31855_SS2) + #define TEMP_1_CS_PIN MAX31855_SS2_PIN + #elif PIN_EXISTS(MAX31855_CS2) + #define TEMP_1_CS_PIN MAX31855_CS2_PIN + #elif PIN_EXISTS(MAX31865_SS2) + #define TEMP_1_CS_PIN MAX31865_SS2_PIN + #elif PIN_EXISTS(MAX31865_CS2) + #define TEMP_1_CS_PIN MAX31865_CS2_PIN + #endif + #endif + + #if TEMP_SENSOR_1_IS_MAX6675 + #if !PIN_EXISTS(TEMP_1_MISO) // DO + #if PIN_EXISTS(MAX6675_MISO) + #define TEMP_1_MISO_PIN MAX6675_MISO_PIN + #elif PIN_EXISTS(MAX6675_DO) + #define TEMP_1_MISO_PIN MAX6675_DO_PIN + #endif + #endif + #if !PIN_EXISTS(TEMP_1_SCK) && PIN_EXISTS(MAX6675_SCK) + #define TEMP_1_SCK_PIN MAX6675_SCK_PIN + #endif + + #elif TEMP_SENSOR_1_IS_MAX31855 + #if !PIN_EXISTS(TEMP_1_MISO) // DO + #if PIN_EXISTS(MAX31855_MISO) + #define TEMP_1_MISO_PIN MAX31855_MISO_PIN + #elif PIN_EXISTS(MAX31855_DO) + #define TEMP_1_MISO_PIN MAX31855_DO_PIN + #endif + #endif + #if !PIN_EXISTS(TEMP_1_SCK) && PIN_EXISTS(MAX31855_SCK) + #define TEMP_1_SCK_PIN MAX31855_SCK_PIN + #endif + + #elif TEMP_SENSOR_1_IS_MAX31865 + #if !PIN_EXISTS(TEMP_1_MISO) // DO + #if PIN_EXISTS(MAX31865_MISO) + #define TEMP_1_MISO_PIN MAX31865_MISO_PIN + #elif PIN_EXISTS(MAX31865_DO) + #define TEMP_1_MISO_PIN MAX31865_DO_PIN + #endif + #endif + #if !PIN_EXISTS(TEMP_1_SCK) && PIN_EXISTS(MAX31865_SCK) + #define TEMP_1_SCK_PIN MAX31865_SCK_PIN + #endif + #if !PIN_EXISTS(TEMP_1_MOSI) && PIN_EXISTS(MAX31865_MOSI) // MOSI for '65 only + #define TEMP_1_MOSI_PIN MAX31865_MOSI_PIN + #endif + #endif + + // Software SPI - enable if MISO/SCK are defined. + #if PIN_EXISTS(TEMP_1_MISO) && PIN_EXISTS(TEMP_1_SCK) && DISABLED(TEMP_SENSOR_1_FORCE_HW_SPI) + #if TEMP_SENSOR_1_IS_MAX31865 && !PIN_EXISTS(TEMP_1_MOSI) + #error "TEMP_SENSOR_1 MAX31865 requires TEMP_1_MOSI_PIN defined for Software SPI. To use Hardware SPI instead, undefine MISO/SCK or enable TEMP_SENSOR_1_FORCE_HW_SPI." + #else + #define TEMP_SENSOR_1_HAS_SPI_PINS 1 + #endif + #endif + + #endif // TEMP_SENSOR_1_IS_MAX_TC + + // + // User-defined thermocouple libraries + // + // Add LIB_MAX6675 / LIB_MAX31855 / LIB_MAX31865 to the build_flags + // to select a USER library for MAX6675, MAX31855, MAX31865 + // + #if BOTH(HAS_MAX6675, LIB_MAX6675) + #define LIB_USR_MAX6675 1 #endif -#endif - -#if PIN_EXISTS(MAX6675_SS2) - #if TEMP_SENSOR_IS_MAX(1, MAX31855) - #define MAX31855_CS2_PIN MAX6675_SS2_PIN - #elif TEMP_SENSOR_IS_MAX(1, MAX31865) - #define MAX31865_CS2_PIN MAX6675_SS2_PIN - #elif TEMP_SENSOR_IS_MAX(1, MAX6675) - #define MAX6675_CS2_PIN MAX6675_SS2_PIN + #if BOTH(HAS_MAX31855, LIB_MAX31855) + #define LIB_USR_MAX31855 1 #endif -#endif - -#if PIN_EXISTS(MAX6675_DO) - #if HAS_MAX31855 - #define MAX31855_MISO_PIN MAX6675_DO_PIN - #elif HAS_MAX31865 - #define MAX31865_MISO_PIN MAX6675_DO_PIN - #elif HAS_MAX6675 - #define MAX6675_MISO_PIN MAX6675_DO_PIN - #endif -#endif - -#if PIN_EXISTS(MAX6675_SCK) - #if HAS_MAX31855 - #define MAX31855_SCK_PIN MAX6675_SCK_PIN - #elif HAS_MAX31865 - #define MAX31865_SCK_PIN MAX6675_SCK_PIN - #endif -#endif - -// Compatibility Layer for use when HAL manipulates PINS for MAX31855 and MAX6675 -#if PIN_EXISTS(MAX31855_CS) && !PIN_EXISTS(MAX6675_SS) - #define MAX6675_SS_PIN MAX31855_CS_PIN -#endif -#if PIN_EXISTS(MAX31855_CS2) && !PIN_EXISTS(MAX6675_SS2) - #define MAX6675_SS2_PIN MAX31855_CS2_PIN -#endif -#if PIN_EXISTS(MAX6675_CS) && !PIN_EXISTS(MAX6675_SS) - #define MAX6675_SS_PIN MAX6675_CS_PIN -#endif -#if PIN_EXISTS(MAX6675_CS2) && !PIN_EXISTS(MAX6675_SS2) - #define MAX6675_SS2_PIN MAX6675_CS2_PIN -#endif -#if PIN_EXISTS(MAX31855_MISO) && !PIN_EXISTS(MAX6675_DO) - #define MAX6675_DO_PIN MAX31855_MISO_PIN -#endif -#if PIN_EXISTS(MAX6675_MISO) && !PIN_EXISTS(MAX6675_DO) - #define MAX6675_DO_PIN MAX6675_MISO_PIN -#endif -#if PIN_EXISTS(MAX31855_SCK) && !PIN_EXISTS(MAX6675_SCK) - #define MAX6675_SCK_PIN MAX31855_SCK_PIN -#endif - -// -// User-defined thermocouple libraries -// -// Add LIB_MAX6675 / LIB_MAX31855 / LIB_MAX31865 to the build_flags -// to select a USER library for MAX6675, MAX31855, MAX31865 -// -#if BOTH(HAS_MAX6675, LIB_MAX6675) - #define LIB_USR_MAX6675 1 -#endif -#if BOTH(HAS_MAX31855, LIB_MAX31855) - #define LIB_USR_MAX31855 1 -#endif -#if HAS_MAX31865 - #if ENABLED(LIB_MAX31865) + #if BOTH(HAS_MAX31865, LIB_MAX31865) #define LIB_USR_MAX31865 1 - #else - #define LIB_ADAFRUIT_MAX31865 1 + #elif HAS_MAX31865 + #define LIB_INTERNAL_MAX31865 1 #endif -#endif + +#endif //HAS_MAX_TC #if TEMP_SENSOR_2 == -4 #define TEMP_SENSOR_2_IS_AD8495 1 @@ -2715,6 +2817,77 @@ #define BED_OR_CHAMBER_OR_FAN 1 #endif +/** + * Up to 3 PWM fans + */ +#ifndef FAN_INVERTING + #define FAN_INVERTING false +#endif + +#if HAS_FAN7 + #define FAN_COUNT 8 +#elif HAS_FAN6 + #define FAN_COUNT 7 +#elif HAS_FAN5 + #define FAN_COUNT 6 +#elif HAS_FAN4 + #define FAN_COUNT 5 +#elif HAS_FAN3 + #define FAN_COUNT 4 +#elif HAS_FAN2 + #define FAN_COUNT 3 +#elif HAS_FAN1 + #define FAN_COUNT 2 +#elif HAS_FAN0 + #define FAN_COUNT 1 +#else + #define FAN_COUNT 0 +#endif + +#if FAN_COUNT > 0 + #define HAS_FAN 1 +#endif + +/** + * Part Cooling fan multipliexer + */ +#if PIN_EXISTS(FANMUX0) + #define HAS_FANMUX 1 +#endif + +/** + * MIN/MAX fan PWM scaling + */ +#ifndef FAN_OFF_PWM + #define FAN_OFF_PWM 0 +#endif +#ifndef FAN_MIN_PWM + #if FAN_OFF_PWM > 0 + #define FAN_MIN_PWM (FAN_OFF_PWM + 1) + #else + #define FAN_MIN_PWM 0 + #endif +#endif +#ifndef FAN_MAX_PWM + #define FAN_MAX_PWM 255 +#endif +#if FAN_MIN_PWM < 0 || FAN_MIN_PWM > 255 + #error "FAN_MIN_PWM must be a value from 0 to 255." +#elif FAN_MAX_PWM < 0 || FAN_MAX_PWM > 255 + #error "FAN_MAX_PWM must be a value from 0 to 255." +#elif FAN_MIN_PWM > FAN_MAX_PWM + #error "FAN_MIN_PWM must be less than or equal to FAN_MAX_PWM." +#elif FAN_OFF_PWM > FAN_MIN_PWM + #error "FAN_OFF_PWM must be less than or equal to FAN_MIN_PWM." +#endif + +/** + * FAST PWM FAN Settings + */ +#if ENABLED(FAST_PWM_FAN) && !defined(FAST_PWM_FAN_FREQUENCY) + #define FAST_PWM_FAN_FREQUENCY ((F_CPU) / (2 * 255 * 1)) // Fan frequency default +#endif + // Servos #if PIN_EXISTS(SERVO0) && NUM_SERVOS > 0 #define HAS_SERVO_0 1 @@ -2989,77 +3162,6 @@ #undef PREHEAT_SHORTCUT_MENU_ITEM #endif -/** - * Up to 3 PWM fans - */ -#ifndef FAN_INVERTING - #define FAN_INVERTING false -#endif - -#if HAS_FAN7 - #define FAN_COUNT 8 -#elif HAS_FAN6 - #define FAN_COUNT 7 -#elif HAS_FAN5 - #define FAN_COUNT 6 -#elif HAS_FAN4 - #define FAN_COUNT 5 -#elif HAS_FAN3 - #define FAN_COUNT 4 -#elif HAS_FAN2 - #define FAN_COUNT 3 -#elif HAS_FAN1 - #define FAN_COUNT 2 -#elif HAS_FAN0 - #define FAN_COUNT 1 -#else - #define FAN_COUNT 0 -#endif - -#if FAN_COUNT > 0 - #define HAS_FAN 1 -#endif - -/** - * Part Cooling fan multipliexer - */ -#if PIN_EXISTS(FANMUX0) - #define HAS_FANMUX 1 -#endif - -/** - * MIN/MAX fan PWM scaling - */ -#ifndef FAN_OFF_PWM - #define FAN_OFF_PWM 0 -#endif -#ifndef FAN_MIN_PWM - #if FAN_OFF_PWM > 0 - #define FAN_MIN_PWM (FAN_OFF_PWM + 1) - #else - #define FAN_MIN_PWM 0 - #endif -#endif -#ifndef FAN_MAX_PWM - #define FAN_MAX_PWM 255 -#endif -#if FAN_MIN_PWM < 0 || FAN_MIN_PWM > 255 - #error "FAN_MIN_PWM must be a value from 0 to 255." -#elif FAN_MAX_PWM < 0 || FAN_MAX_PWM > 255 - #error "FAN_MAX_PWM must be a value from 0 to 255." -#elif FAN_MIN_PWM > FAN_MAX_PWM - #error "FAN_MIN_PWM must be less than or equal to FAN_MAX_PWM." -#elif FAN_OFF_PWM > FAN_MIN_PWM - #error "FAN_OFF_PWM must be less than or equal to FAN_MIN_PWM." -#endif - -/** - * FAST PWM FAN Settings - */ -#if ENABLED(FAST_PWM_FAN) && !defined(FAST_PWM_FAN_FREQUENCY) - #define FAST_PWM_FAN_FREQUENCY ((F_CPU) / (2 * 255 * 1)) // Fan frequency default -#endif - /** * MIN/MAX case light PWM scaling */ @@ -3092,6 +3194,7 @@ #endif #else #undef NOZZLE_TO_PROBE_OFFSET + #undef PROBING_STEPPERS_OFF #endif /** @@ -3134,18 +3237,26 @@ /** * Heater, Fan, and Probe interactions */ -#if FAN_COUNT == 0 - #undef PROBING_FANS_OFF +#if !HAS_FAN #undef ADAPTIVE_FAN_SLOWING #undef NO_FAN_SLOWING_IN_PID_TUNING #endif - -#if HAS_BED_PROBE && (EITHER(PROBING_HEATERS_OFF, PROBING_FANS_OFF) || DELAY_BEFORE_PROBING > 0) - #define HAS_QUIET_PROBING 1 +#if !BOTH(HAS_BED_PROBE, HAS_FAN) + #undef PROBING_FANS_OFF +#endif +#if !BOTH(HAS_BED_PROBE, HAS_EXTRUDERS) + #undef PROBING_ESTEPPERS_OFF +#endif +#if BOTH(PROBING_STEPPERS_OFF, PROBING_ESTEPPERS_OFF) + #undef PROBING_ESTEPPERS_OFF + #warning "PROBING_STEPPERS_OFF includes PROBING_ESTEPPERS_OFF. Disabling PROBING_ESTEPPERS_OFF." #endif #if EITHER(ADVANCED_PAUSE_FEATURE, PROBING_HEATERS_OFF) #define HEATER_IDLE_HANDLER 1 #endif +#if HAS_BED_PROBE && (ANY(PROBING_HEATERS_OFF, PROBING_STEPPERS_OFF, PROBING_ESTEPPERS_OFF, PROBING_FANS_OFF) || DELAY_BEFORE_PROBING > 0) + #define HAS_QUIET_PROBING 1 +#endif /** * Advanced Pause - Filament Change @@ -3381,9 +3492,14 @@ #endif #endif -// LCD timeout to status screen default is 15s -#ifndef LCD_TIMEOUT_TO_STATUS - #define LCD_TIMEOUT_TO_STATUS 15000 +#if HAS_LCD_MENU + // LCD timeout to status screen default is 15s + #ifndef LCD_TIMEOUT_TO_STATUS + #define LCD_TIMEOUT_TO_STATUS 15000 + #endif + #if LCD_TIMEOUT_TO_STATUS + #define SCREENS_CAN_TIME_OUT 1 + #endif #endif // Add commands that need sub-codes to this list diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index ea565e92b1..43c82da90a 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -416,8 +416,19 @@ #error "MBL_Z_STEP is now MESH_EDIT_Z_STEP." #elif defined(CHDK) #error "CHDK is now CHDK_PIN." -#elif defined(MAX6675_SS) || defined(MAX6675_SS2) - #error "MAX6675_SS / MAX6675_SS2 is now MAX6675_SS_PIN / MAX6675_SS2_PIN." +#elif ANY_PIN( \ + MAX6675_SS, MAX6675_SS2, MAX6675_CS, MAX6675_CS2, \ + MAX31855_SS, MAX31855_SS2, MAX31855_CS, MAX31855_CS2, \ + MAX31865_SS, MAX31865_SS2, MAX31865_CS, MAX31865_CS2) + #warning "MAX*_SS_PIN, MAX*_SS2_PIN, MAX*_CS_PIN, and MAX*_CS2_PIN are deprecated and will be removed in a future version. Please use TEMP_0_CS_PIN/TEMP_1_CS_PIN instead." +#elif ANY_PIN(MAX6675_SCK, MAX31855_SCK, MAX31865_SCK) + #warning "MAX*_SCK_PIN is deprecated and will be removed in a future version. Please use TEMP_0_SCK_PIN/TEMP_1_SCK_PIN instead." +#elif ANY_PIN(MAX6675_MISO, MAX6675_DO, MAX31855_MISO, MAX31855_DO, MAX31865_MISO, MAX31865_DO) + #warning "MAX*_MISO_PIN and MAX*_DO_PIN are deprecated and will be removed in a future version. Please use TEMP_0_MISO_PIN/TEMP_1_MISO_PIN instead." +#elif PIN_EXISTS(MAX31865_MOSI) + #warning "MAX31865_MOSI_PIN is deprecated and will be removed in a future version. Please use TEMP_0_MOSI_PIN/TEMP_1_MOSI_PIN instead." +#elif ANY_PIN(THERMO_CS1_PIN, THERMO_CS2_PIN, THERMO_DO_PIN, THERMO_SCK_PIN) + #error "THERMO_*_PIN is now TEMP_n_CS_PIN, TEMP_n_SCK_PIN, TEMP_n_MOSI_PIN, TEMP_n_MISO_PIN." #elif defined(MAX31865_SENSOR_OHMS) #error "MAX31865_SENSOR_OHMS is now MAX31865_SENSOR_OHMS_0." #elif defined(MAX31865_CALIBRATION_OHMS) @@ -593,24 +604,29 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #endif #ifdef PTC_SAMPLE_START - constexpr int _ptc_sample_start = PTC_SAMPLE_START; - static_assert(_test_ptc_sample_start != PTC_SAMPLE_START, "PTC_SAMPLE_START must be a whole number."); + constexpr auto _ptc_sample_start = PTC_SAMPLE_START; + constexpr decltype(_ptc_sample_start) _test_ptc_sample_start = 12.3f; + static_assert(_test_ptc_sample_start != 12.3f, "PTC_SAMPLE_START must be a whole number."); #endif #ifdef PTC_SAMPLE_RES - constexpr int _ptc_sample_res = PTC_SAMPLE_END; - static_assert(_test_ptc_sample_res != PTC_SAMPLE_END, "PTC_SAMPLE_RES must be a whole number."); + constexpr auto _ptc_sample_res = PTC_SAMPLE_RES; + constexpr decltype(_ptc_sample_res) _test_ptc_sample_res = 12.3f; + static_assert(_test_ptc_sample_res != 12.3f, "PTC_SAMPLE_RES must be a whole number."); #endif #ifdef BTC_SAMPLE_START - constexpr int _btc_sample_start = BTC_SAMPLE_START; - static_assert(_test_btc_sample_start != BTC_SAMPLE_START, "BTC_SAMPLE_START must be a whole number."); + constexpr auto _btc_sample_start = BTC_SAMPLE_START; + constexpr decltype(_btc_sample_start) _test_btc_sample_start = 12.3f; + static_assert(_test_btc_sample_start != 12.3f, "BTC_SAMPLE_START must be a whole number."); #endif #ifdef BTC_SAMPLE_RES - constexpr int _btc_sample_res = BTC_SAMPLE_END; - static_assert(_test_btc_sample_res != BTC_SAMPLE_END, "BTC_SAMPLE_RES must be a whole number."); + constexpr _btc_sample_res = BTC_SAMPLE_RES; + constexpr decltype(_btc_sample_res) _test_btc_sample_res = 12.3f; + static_assert(_test_btc_sample_res != 12.3f, "BTC_SAMPLE_RES must be a whole number."); #endif #ifdef BTC_PROBE_TEMP - constexpr int _btc_probe_temp = BTC_PROBE_TEMP; - static_assert(_test_btc_probe_temp != BTC_PROBE_TEMP, "BTC_PROBE_TEMP must be a whole number."); + constexpr auto _btc_probe_temp = BTC_PROBE_TEMP; + constexpr decltype(_btc_probe_temp) _test_btc_probe_temp = 12.3f; + static_assert(_test_btc_probe_temp != 12.3f, "BTC_PROBE_TEMP must be a whole number."); #endif #endif @@ -1039,6 +1055,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "EXTRUDERS must be 1 with HEATERS_PARALLEL." #endif + #if ENABLED(STATUS_HOTEND_INVERTED) && NONE(STATUS_HOTEND_NUMBERLESS, STATUS_HOTEND_ANIM) + #error "With multiple hotends STATUS_HOTEND_INVERTED requires STATUS_HOTEND_ANIM or STATUS_HOTEND_NUMBERLESS." + #endif + #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) #ifndef TOOLCHANGE_FS_LENGTH #error "TOOLCHANGE_FILAMENT_SWAP requires TOOLCHANGE_FS_LENGTH." @@ -1245,23 +1265,28 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif /** - * (Electro)magnetic Switching Toolhead requirements + * Magnetic / Electromagnetic Switching Toolhead requirements */ #if EITHER(MAGNETIC_SWITCHING_TOOLHEAD, ELECTROMAGNETIC_SWITCHING_TOOLHEAD) #ifndef SWITCHING_TOOLHEAD_Y_POS - #error "(ELECTRO)MAGNETIC_SWITCHING_TOOLHEAD requires SWITCHING_TOOLHEAD_Y_POS" + #error "(ELECTRO)?MAGNETIC_SWITCHING_TOOLHEAD requires SWITCHING_TOOLHEAD_Y_POS" #elif !defined(SWITCHING_TOOLHEAD_X_POS) - #error "(ELECTRO)MAGNETIC_SWITCHING_TOOLHEAD requires SWITCHING_TOOLHEAD_X_POS" - #elif !defined(SWITCHING_TOOLHEAD_Z_HOP) - #error "(ELECTRO)MAGNETIC_SWITCHING_TOOLHEAD requires SWITCHING_TOOLHEAD_Z_HOP." + #error "(ELECTRO)?MAGNETIC_SWITCHING_TOOLHEAD requires SWITCHING_TOOLHEAD_X_POS" #elif !defined(SWITCHING_TOOLHEAD_Y_CLEAR) - #error "(ELECTRO)MAGNETIC_SWITCHING_TOOLHEAD requires SWITCHING_TOOLHEAD_Y_CLEAR." - #elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) - #if ENABLED(EXT_SOLENOID) - #error "(ELECTRO)MAGNETIC_SWITCHING_TOOLHEAD and EXT_SOLENOID are incompatible. (Pins are used twice.)" - #elif !PIN_EXISTS(SOL0) - #error "(ELECTRO)MAGNETIC_SWITCHING_TOOLHEAD requires SOL0_PIN." - #endif + #error "(ELECTRO)?MAGNETIC_SWITCHING_TOOLHEAD requires SWITCHING_TOOLHEAD_Y_CLEAR." + #endif +#endif + +/** + * Electromagnetic Switching Toolhead requirements + */ +#if ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) + #if ENABLED(EXT_SOLENOID) + #error "ELECTROMAGNETIC_SWITCHING_TOOLHEAD and EXT_SOLENOID are incompatible. (Pins are used twice.)" + #elif !PIN_EXISTS(SOL0) + #error "ELECTROMAGNETIC_SWITCHING_TOOLHEAD requires SOL0_PIN." + #elif !defined(SWITCHING_TOOLHEAD_Z_HOP) + #error "ELECTROMAGNETIC_SWITCHING_TOOLHEAD requires SWITCHING_TOOLHEAD_Z_HOP." #endif #endif @@ -1939,14 +1964,21 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif /** - * Pins and Sensor IDs must be set for each heater + * Required MAX31865 settings */ -#if TEMP_SENSOR_0_IS_MAX6675 && !ANY_PIN(MAX6675_SS, MAX31855_CS, MAX31865_CS, MAX6675_CS) - #error "TEMP_SENSOR_0 -2 requires a MAX6675_SS_PIN, MAX6675_CS_PIN, MAX31855_CS_PIN, or MAX31865_CS_PIN." -#elif HAS_HOTEND && !HAS_TEMP_HOTEND && !TEMP_SENSOR_0_IS_DUMMY - #error "TEMP_0_PIN (required for TEMP_SENSOR_0) not defined for this board." -#elif EITHER(HAS_MULTI_HOTEND, HEATERS_PARALLEL) && !HAS_HEATER_1 - #error "HEATER_1_PIN is not defined. TEMP_SENSOR_1 might not be set, or the board (not EEB / EEF?) doesn't define a pin." +#if TEMP_SENSOR_0_IS_MAX31865 || (TEMP_SENSOR_REDUNDANT_IS_MAX31865 && TEMP_SENSOR_REDUNDANT_SOURCE == 0) + #if !defined(MAX31865_SENSOR_WIRES_0) || !WITHIN(MAX31865_SENSOR_WIRES_0, 2, 4) + #error "MAX31865_SENSOR_WIRES_0 must be defined as an integer between 2 and 4." + #elif !defined(MAX31865_SENSOR_OHMS_0) || !defined(MAX31865_CALIBRATION_OHMS_0) + #error "MAX31865_SENSOR_OHMS_0 and MAX31865_CALIBRATION_OHMS_0 must be set if TEMP_SENSOR_0/TEMP_SENSOR_REDUNDANT is MAX31865." + #endif +#endif +#if TEMP_SENSOR_1_IS_MAX31865 || (TEMP_SENSOR_REDUNDANT_IS_MAX31865 && TEMP_SENSOR_REDUNDANT_SOURCE == 1) + #if !defined(MAX31865_SENSOR_WIRES_1) || !WITHIN(MAX31865_SENSOR_WIRES_1, 2, 4) + #error "MAX31865_SENSOR_WIRES_1 must be defined as an integer between 2 and 4." + #elif !defined(MAX31865_SENSOR_OHMS_1) || !defined(MAX31865_CALIBRATION_OHMS_1) + #error "MAX31865_SENSOR_OHMS_1 and MAX31865_CALIBRATION_OHMS_1 must be set if TEMP_SENSOR_1/TEMP_SENSOR_REDUNDANT is MAX31865." + #endif #endif /** @@ -2009,20 +2041,36 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "TEMP_SENSOR_REDUNDANT_TARGET can't be Cooler (-5): requires TEMP_COOLER_PIN" #endif - #if TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 0 && !PIN_EXISTS(MAX6675_SS) - #error "TEMP_SENSOR_REDUNDANT MAX Thermocouple with TEMP_SENSOR_REDUNDANT_SOURCE 0 requires a MAX6675_SS_PIN, MAX6675_CS_PIN, MAX31855_CS_PIN, or MAX31865_CS_PIN." - #elif TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 1 && !PIN_EXISTS(MAX6675_SS2) - #error "TEMP_SENSOR_REDUNDANT MAX Thermocouple with TEMP_SENSOR_REDUNDANT_SOURCE 1 requires a MAX6675_SS2_PIN, MAX6675_CS_PIN, MAX31855_CS_PIN, or MAX31865_CS_PIN." + #if TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 0 && !PIN_EXISTS(TEMP_0_CS) + #error "TEMP_SENSOR_REDUNDANT MAX Thermocouple with TEMP_SENSOR_REDUNDANT_SOURCE 0 requires TEMP_0_CS_PIN." + #elif TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 1 && !PIN_EXISTS(TEMP_1_CS) + #error "TEMP_SENSOR_REDUNDANT MAX Thermocouple with TEMP_SENSOR_REDUNDANT_SOURCE 1 requires TEMP_1_CS_PIN." #endif #endif +/** + * Test Sensor & Heater pin combos. + * Pins and Sensor IDs must be set for each heater + */ +#if !ANY_PIN(TEMP_0, TEMP_0_CS) + #error "TEMP_0_PIN or TEMP_0_CS_PIN not defined for this board." +#elif !HAS_HEATER_0 && EXTRUDERS + #error "HEATER_0_PIN not defined for this board." +#elif TEMP_SENSOR_0_IS_MAX_TC && !PIN_EXISTS(TEMP_0_CS) + #error "TEMP_SENSOR_0 MAX thermocouple requires TEMP_0_CS_PIN." +#elif HAS_HOTEND && !HAS_TEMP_HOTEND && !TEMP_SENSOR_0_IS_DUMMY + #error "TEMP_0_PIN (required for TEMP_SENSOR_0) not defined for this board." +#elif EITHER(HAS_MULTI_HOTEND, HEATERS_PARALLEL) && !HAS_HEATER_1 + #error "HEATER_1_PIN is not defined. TEMP_SENSOR_1 might not be set, or the board (not EEB / EEF?) doesn't define a pin." +#endif + #if HAS_MULTI_HOTEND - #if TEMP_SENSOR_1_IS_MAX6675 && !ANY_PIN(MAX6675_SS2, MAX31855_CS2, MAX31865_CS2, MAX6675_CS2) - #error "TEMP_SENSOR_1 requires a MAX6675_SS2_PIN, MAX6675_CS2_PIN, MAX31855_CS2_PIN, or MAX31865_CS2_PIN." + #if TEMP_SENSOR_1_IS_MAX_TC && !PIN_EXISTS(TEMP_1_CS) + #error "TEMP_SENSOR_1 MAX thermocouple requires TEMP_1_CS_PIN." #elif TEMP_SENSOR_1 == 0 #error "TEMP_SENSOR_1 is required with 2 or more HOTENDS." - #elif !ANY_PIN(TEMP_1, MAX6675_SS2) && !TEMP_SENSOR_1_IS_DUMMY - #error "TEMP_1_PIN or MAX6675_SS2_PIN not defined for this board." + #elif !ANY_PIN(TEMP_1, TEMP_1_CS) && !TEMP_SENSOR_1_IS_DUMMY + #error "TEMP_1_PIN or TEMP_1_CS_PIN not defined for this board." #endif #if HOTENDS > 2 #if TEMP_SENSOR_2 == 0 @@ -2134,14 +2182,31 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "TEMP_SENSOR_6 shouldn't be set with only 1 HOTEND." #elif TEMP_SENSOR_7 != 0 #error "TEMP_SENSOR_7 shouldn't be set with only 1 HOTEND." -#endif +#endif // HAS_MULTI_HOTEND +/** + * Pins must be set for temp sensors, with some other feature requirements. + */ #if TEMP_SENSOR_CHAMBER && !PIN_EXISTS(TEMP_CHAMBER) #error "TEMP_SENSOR_CHAMBER requires TEMP_CHAMBER_PIN." #endif -#if TEMP_SENSOR_COOLER && !(PIN_EXISTS(TEMP_COOLER) && ENABLED(LASER_FEATURE)) - #error "TEMP_SENSOR_COOLER requires LASER_FEATURE and TEMP_COOLER_PIN." +#if TEMP_SENSOR_COOLER + #if !PIN_EXISTS(TEMP_COOLER) + #error "TEMP_SENSOR_COOLER requires TEMP_COOLER_PIN." + #elif DISABLED(LASER_FEATURE) + #error "TEMP_SENSOR_COOLER requires LASER_FEATURE." + #endif +#endif + +#if TEMP_SENSOR_PROBE + #if !PIN_EXISTS(TEMP_PROBE) + #error "TEMP_SENSOR_PROBE requires TEMP_PROBE_PIN." + #elif !HAS_TEMP_ADC_PROBE + #error "TEMP_PROBE_PIN must be an ADC pin." + #elif DISABLED(FIX_MOUNTED_PROBE) + #error "TEMP_SENSOR_PROBE shouldn't be set without FIX_MOUNTED_PROBE." + #endif #endif #if ENABLED(LASER_COOLANT_FLOW_METER) && !(PIN_EXISTS(FLOWMETER) && ENABLED(LASER_FEATURE)) @@ -2172,41 +2237,6 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif #endif -#if TEMP_SENSOR_PROBE - #if !PIN_EXISTS(TEMP_PROBE) - #error "TEMP_SENSOR_PROBE requires TEMP_PROBE_PIN." - #elif !HAS_TEMP_ADC_PROBE - #error "TEMP_PROBE_PIN must be an ADC pin." - #elif DISABLED(FIX_MOUNTED_PROBE) - #error "TEMP_SENSOR_PROBE shouldn't be set without FIX_MOUNTED_PROBE." - #endif -#endif - -#if TEMP_SENSOR_IS_MAX(0, MAX31865) && !(defined(MAX31865_SENSOR_OHMS_0) && defined(MAX31865_CALIBRATION_OHMS_0)) - #error "MAX31865_SENSOR_OHMS_0 and MAX31865_CALIBRATION_OHMS_0 must be set if TEMP_SENSOR_0/TEMP_SENSOR_REDUNDANT is MAX31865." -#elif TEMP_SENSOR_IS_MAX(1, MAX31865) && !(defined(MAX31865_SENSOR_OHMS_1) && defined(MAX31865_CALIBRATION_OHMS_1)) - #error "MAX31865_SENSOR_OHMS_1 and MAX31865_CALIBRATION_OHMS_1 must be set if TEMP_SENSOR_1/TEMP_SENSOR_REDUNDANT is MAX31865." -#endif - -/** - * Test Heater, Temp Sensor, and Extruder Pins - */ -#if !HAS_HEATER_0 && EXTRUDERS - #error "HEATER_0_PIN not defined for this board." -#elif !ANY_PIN(TEMP_0, MAX6675_SS) - #error "TEMP_0_PIN or MAX6675_SS not defined for this board." -#endif - -#if HAS_EXTRUDERS - #if ((defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && !PINS_EXIST(E0_STEP, E0_DIR)) - #error "E0_STEP_PIN or E0_DIR_PIN not defined for this board." - #elif ( !(defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && (!PINS_EXIST(E0_STEP, E0_DIR) || !HAS_E0_ENABLE)) - #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board." - #elif EXTRUDERS && TEMP_SENSOR_0 == 0 - #error "TEMP_SENSOR_0 is required if there are any extruders." - #endif -#endif - /** * Temperature status LEDs */ @@ -2248,6 +2278,16 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS /** * Test Extruder Stepper Pins */ +#if HAS_EXTRUDERS + #if ((defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && !PINS_EXIST(E0_STEP, E0_DIR)) + #error "E0_STEP_PIN or E0_DIR_PIN not defined for this board." + #elif ( !(defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && (!PINS_EXIST(E0_STEP, E0_DIR) || !HAS_E0_ENABLE)) + #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board." + #elif EXTRUDERS && TEMP_SENSOR_0 == 0 + #error "TEMP_SENSOR_0 is required if there are any extruders." + #endif +#endif + #if E_STEPPERS #if !(PINS_EXIST(E0_STEP, E0_DIR) && HAS_E0_ENABLE) #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board." @@ -3574,6 +3614,13 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #error "Either enable MEATPACK_ON_SERIAL_PORT_* or BINARY_FILE_TRANSFER, not both." #endif +/** + * Sanity Check for Slim LCD Menus and Probe Offset Wizard + */ +#if BOTH(SLIM_LCD_MENUS, PROBE_OFFSET_WIZARD) + #error "SLIM_LCD_MENUS disables \"Advanced Settings > Probe Offsets > PROBE_OFFSET_WIZARD.\"" +#endif + /** * Sanity check for unique start and stop values in NOZZLE_CLEAN_FEATURE */ diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index da6f10991a..9c9e2d3ee2 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-06-18" + #define STRING_DISTRIBUTION_DATE "2021-07-07" #endif /** @@ -52,7 +52,7 @@ * to alert users to major changes. */ -#define MARLIN_HEX_VERSION 02000900 +#define MARLIN_HEX_VERSION 02000901 #ifndef REQUIRED_CONFIGURATION_H_VERSION #define REQUIRED_CONFIGURATION_H_VERSION MARLIN_HEX_VERSION #endif diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp index 1a07b7ab75..726eb2cc39 100644 --- a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp +++ b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp @@ -369,13 +369,12 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { if (mark_as_selected(row, style & SS_INVERT)) { - pixel_len_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed - - const int8_t plen = pstr ? utf8_strlen_P(pstr) : 0, - vlen = vstr ? utf8_strlen(vstr) : 0; + + const int plen = pstr ? calculateWidth(pstr) : 0, + vlen = vstr ? utf8_strlen(vstr) : 0; if (style & SS_CENTER) { - int8_t pad = (LCD_WIDTH - plen - vlen) / 2; + int pad = (LCD_PIXEL_WIDTH - plen - vlen * MENU_FONT_WIDTH) / MENU_FONT_WIDTH / 2; while (--pad >= 0) n -= lcd_put_wchar(' '); } @@ -400,8 +399,9 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop if (mark_as_selected(row, sel)) { const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen((char*)inStr)), pixelwidth = (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), (char*)inStr)); + const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1; - pixel_len_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vallen) * (MENU_FONT_WIDTH); + pixel_len_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vallen * prop) * (MENU_FONT_WIDTH); if (vallen) { lcd_put_wchar(':'); while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); @@ -414,15 +414,16 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const value/*=nullptr*/) { ui.encoder_direction_normal(); + const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1; const u8g_uint_t labellen = utf8_strlen_P(pstr), vallen = utf8_strlen(value); - bool extra_row = labellen > LCD_WIDTH - 2 - vallen; + bool extra_row = labellen * prop > LCD_WIDTH - 2 - vallen * prop; #if ENABLED(USE_BIG_EDIT_FONT) // Use the menu font if the label won't fit on a single line constexpr u8g_uint_t lcd_edit_width = (LCD_PIXEL_WIDTH) / (EDIT_FONT_WIDTH); u8g_uint_t lcd_chr_fit, one_chr_width; - if (labellen <= lcd_edit_width - 1) { - if (labellen + vallen + 1 > lcd_edit_width) extra_row = true; + if (labellen * prop <= lcd_edit_width - 1) { + if (labellen * prop + vallen * prop + 1 > lcd_edit_width) extra_row = true; lcd_chr_fit = lcd_edit_width + 1; one_chr_width = EDIT_FONT_WIDTH; ui.set_font(FONT_EDIT); @@ -454,7 +455,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop onpage = PAGE_CONTAINS(baseline - (EDIT_FONT_ASCENT - 1), baseline); } if (onpage) { - lcd_put_wchar(((lcd_chr_fit - 1) - (vallen + 1)) * one_chr_width, baseline, ' '); // Right-justified, padded, add a leading space + lcd_put_wchar(((lcd_chr_fit - 1) - (vallen * prop + 1)) * one_chr_width, baseline, ' '); // Right-justified, padded, add a leading space lcd_put_u8str(value); } } @@ -468,7 +469,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop const pixel_len_t bw = len * prop * (MENU_FONT_WIDTH), bx = x * prop * (MENU_FONT_WIDTH); if (inv) { u8g.setColorIndex(1); - u8g.drawBox(bx / prop - 1, by - (MENU_FONT_ASCENT) + 1, bw / prop + 2, MENU_FONT_HEIGHT - 1); + u8g.drawBox(bx / prop - 1, by - (MENU_FONT_ASCENT), bw + 2, MENU_FONT_HEIGHT); u8g.setColorIndex(0); } lcd_put_u8str_P(bx / prop, by, pstr); @@ -478,8 +479,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { ui.draw_select_screen_prompt(pref, string, suff); draw_boxed_string(1, LCD_HEIGHT - 1, no, !yesno); - const u8g_uint_t xpos = (LCD_WIDTH) / (USE_WIDE_GLYPH ? 2 : 1); - draw_boxed_string(xpos - (utf8_strlen_P(yes) + 1), LCD_HEIGHT - 1, yes, yesno); + draw_boxed_string(LCD_WIDTH - (utf8_strlen_P(yes) * (USE_WIDE_GLYPH ? 2 : 1) + 1), LCD_HEIGHT - 1, yes, yesno); } #if ENABLED(SDSUPPORT) diff --git a/Marlin/src/lcd/dogm/status/hotend.h b/Marlin/src/lcd/dogm/status/hotend.h index 3a6e02acb6..aac29da451 100644 --- a/Marlin/src/lcd/dogm/status/hotend.h +++ b/Marlin/src/lcd/dogm/status/hotend.h @@ -39,20 +39,33 @@ #define STATUS_HOTEND1_WIDTH 16 -#if STATUS_HOTEND_BITMAPS == 1 || ENABLED(STATUS_HOTEND_NUMBERLESS) +#if STATUS_HOTEND_BITMAPS == 1 || defined(STATUS_HOTEND_NUMBERLESS) const unsigned char status_hotend_a_bmp[] PROGMEM = { B00011111,B11100000, - B00111111,B11110000, - B00111111,B11110000, - B00111111,B11110000, - B00011111,B11100000, - B00011111,B11100000, - B00111111,B11110000, - B00111111,B11110000, - B00111111,B11110000, - B00001111,B11000000, - B00000111,B10000000, + #if defined(STATUS_HOTEND_INVERTED) && !defined(STATUS_HOTEND_ANIM) + B00100000,B00010000, + B00100000,B00010000, + B00100000,B00010000, + B00010000,B00100000, + B00010000,B00100000, + B00100000,B00010000, + B00100000,B00010000, + B00110000,B00110000, + B00001000,B01000000, + B00000100,B10000000, + #else + B00111111,B11110000, + B00111111,B11110000, + B00111111,B11110000, + B00011111,B11100000, + B00011111,B11100000, + B00111111,B11110000, + B00111111,B11110000, + B00111111,B11110000, + B00001111,B11000000, + B00000111,B10000000, + #endif B00000011,B00000000 }; diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp index 8309c3a00e..d58be4dbaf 100644 --- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp +++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp @@ -236,18 +236,12 @@ FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, co #define HOTEND_DOT false #endif - #if ANIM_HOTEND && BOTH(STATUS_HOTEND_INVERTED, STATUS_HOTEND_NUMBERLESS) - #define OFF_BMP(N) status_hotend_b_bmp - #define ON_BMP(N) status_hotend_a_bmp - #elif ANIM_HOTEND && DISABLED(STATUS_HOTEND_INVERTED) && ENABLED(STATUS_HOTEND_NUMBERLESS) - #define OFF_BMP(N) status_hotend_a_bmp - #define ON_BMP(N) status_hotend_b_bmp - #elif BOTH(ANIM_HOTEND, STATUS_HOTEND_INVERTED) - #define OFF_BMP(N) status_hotend##N##_b_bmp - #define ON_BMP(N) status_hotend##N##_a_bmp + #if ENABLED(STATUS_HOTEND_NUMBERLESS) + #define OFF_BMP(N) TERN(STATUS_HOTEND_INVERTED, status_hotend_b_bmp, status_hotend_a_bmp) + #define ON_BMP(N) TERN(STATUS_HOTEND_INVERTED, status_hotend_a_bmp, status_hotend_b_bmp) #else - #define OFF_BMP(N) status_hotend##N##_a_bmp - #define ON_BMP(N) status_hotend##N##_b_bmp + #define OFF_BMP(N) TERN(STATUS_HOTEND_INVERTED, status_hotend##N##_b_bmp, status_hotend##N##_a_bmp) + #define ON_BMP(N) TERN(STATUS_HOTEND_INVERTED, status_hotend##N##_a_bmp, status_hotend##N##_b_bmp) #endif #if STATUS_HOTEND_BITMAPS > 1 @@ -275,20 +269,18 @@ FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, co uint8_t tall = uint8_t(perc * BAR_TALL + 0.5f); NOMORE(tall, BAR_TALL); - #if ANIM_HOTEND - // Draw hotend bitmap, either whole or split by the heating percent - const uint8_t hx = STATUS_HOTEND_X(heater_id), - bw = STATUS_HOTEND_BYTEWIDTH(heater_id); - #if ENABLED(STATUS_HEAT_PERCENT) - if (isHeat && tall <= BAR_TALL) { - const uint8_t ph = STATUS_HEATERS_HEIGHT - 1 - tall; - u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, ph, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), false)); - u8g.drawBitmapP(hx, STATUS_HEATERS_Y + ph, bw, tall + 1, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), true) + ph * bw); - } - else - #endif - u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, STATUS_HEATERS_HEIGHT, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), isHeat)); + // Draw hotend bitmap, either whole or split by the heating percent + const uint8_t hx = STATUS_HOTEND_X(heater_id), + bw = STATUS_HOTEND_BYTEWIDTH(heater_id); + #if ENABLED(STATUS_HEAT_PERCENT) + if (isHeat && tall <= BAR_TALL) { + const uint8_t ph = STATUS_HEATERS_HEIGHT - 1 - tall; + u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, ph, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), false)); + u8g.drawBitmapP(hx, STATUS_HEATERS_Y + ph, bw, tall + 1, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), true) + ph * bw); + } + else #endif + u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, STATUS_HEATERS_HEIGHT, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), isHeat)); } // PAGE_CONTAINS diff --git a/Marlin/src/lcd/extui/dgus/fysetc/DGUSDisplayDef.h b/Marlin/src/lcd/extui/dgus/fysetc/DGUSDisplayDef.h index 910f5f7791..79aee9a576 100644 --- a/Marlin/src/lcd/extui/dgus/fysetc/DGUSDisplayDef.h +++ b/Marlin/src/lcd/extui/dgus/fysetc/DGUSDisplayDef.h @@ -51,7 +51,7 @@ enum DGUSLCD_Screens : uint8_t { DGUSLCD_SCREEN_KILL = 250, ///< Kill Screen. Must always be 250 (to be able to display "Error wrong LCD Version") DGUSLCD_SCREEN_WAITING = 251, DGUSLCD_SCREEN_POPUP = 252, ///< special target, popup screen will also return this code to say "return to previous screen" - DGUSLDC_SCREEN_UNUSED = 255 + DGUSLCD_SCREEN_UNUSED = 255 }; // Display Memory layout used (T5UID) diff --git a/Marlin/src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.h b/Marlin/src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.h index d18989a48b..0c3a6aa352 100644 --- a/Marlin/src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.h +++ b/Marlin/src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.h @@ -51,7 +51,7 @@ enum DGUSLCD_Screens : uint8_t { DGUSLCD_SCREEN_KILL = 250, ///< Kill Screen. Must always be 250 (to be able to display "Error wrong LCD Version") DGUSLCD_SCREEN_WAITING = 251, DGUSLCD_SCREEN_POPUP = 252, ///< special target, popup screen will also return this code to say "return to previous screen" - DGUSLDC_SCREEN_UNUSED = 255 + DGUSLCD_SCREEN_UNUSED = 255 }; // Display Memory layout used (T5UID) diff --git a/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.h b/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.h index cd86ec5105..5c9ff02bfe 100644 --- a/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.h +++ b/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.h @@ -238,7 +238,7 @@ enum DGUSLCD_Screens : uint8_t { DGUSLCD_SCREEN_KILL = 250, ///< Kill Screen. Must always be 250 (to be able to display "Error wrong LCD Version") DGUSLCD_SCREEN_WAITING = 251, DGUSLCD_SCREEN_POPUP = 252, ///< special target, popup screen will also return this code to say "return to previous screen" - DGUSLDC_SCREEN_UNUSED = 255 + DGUSLCD_SCREEN_UNUSED = 255 }; diff --git a/Marlin/src/lcd/extui/dgus/origin/DGUSDisplayDef.h b/Marlin/src/lcd/extui/dgus/origin/DGUSDisplayDef.h index c1890c7c28..7885621d0b 100644 --- a/Marlin/src/lcd/extui/dgus/origin/DGUSDisplayDef.h +++ b/Marlin/src/lcd/extui/dgus/origin/DGUSDisplayDef.h @@ -46,7 +46,7 @@ enum DGUSLCD_Screens : uint8_t { DGUSLCD_SCREEN_KILL = 250, ///< Kill Screen. Must always be 250 (to be able to display "Error wrong LCD Version") DGUSLCD_SCREEN_WAITING = 251, DGUSLCD_SCREEN_POPUP = 252, ///< special target, popup screen will also return this code to say "return to previous screen" - DGUSLDC_SCREEN_UNUSED = 255 + DGUSLCD_SCREEN_UNUSED = 255 }; // Display Memory layout used (T5UID) diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp index a64c237fa1..1d4711c0e2 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp @@ -20,7 +20,7 @@ * location: . * ****************************************************************************/ -#include "../compat.h" +#include "../config.h" #if ENABLED(TOUCH_UI_FTDI_EVE) diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp index ea8d403753..b4165a742a 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp @@ -20,7 +20,7 @@ * location: . * ****************************************************************************/ -#include "../compat.h" +#include "../config.h" #if ENABLED(TOUCH_UI_FTDI_EVE) #include "media_file_reader.h" diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h index 249c57b9c6..eb76bb9b2b 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h @@ -32,9 +32,7 @@ class MediaFileReader { private: #if ENABLED(SDSUPPORT) - DiskIODriver_SPI_SD card; - SdVolume volume; - SdFile root, file; + SdFile root, file; #endif public: diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/bioprinter/screens.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/bioprinter/screens.h new file mode 100644 index 0000000000..7294c4aa0b --- /dev/null +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/bioprinter/screens.h @@ -0,0 +1,105 @@ +/************* + * screens.h * + *************/ + +/**************************************************************************** + * Written By Mark Pelletier 2017 - Aleph Objects, Inc. * + * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. * + * * + * 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. * + * * + * To view a copy of the GNU General Public License, go to the following * + * location: . * + ****************************************************************************/ + +/********************************* DL CACHE SLOTS ******************************/ + +// In order to reduce SPI traffic, we cache display lists (DL) in RAMG. This +// is done using the CLCD::DLCache class, which takes a unique ID for each +// cache location. These IDs are defined here: + +enum { + STATUS_SCREEN_CACHE, + MENU_SCREEN_CACHE, + TUNE_SCREEN_CACHE, + ALERT_BOX_CACHE, + SPINNER_CACHE, + ADVANCED_SETTINGS_SCREEN_CACHE, + TEMPERATURE_SCREEN_CACHE, + STEPS_SCREEN_CACHE, + MAX_FEEDRATE_SCREEN_CACHE, + MAX_VELOCITY_SCREEN_CACHE, + MAX_ACCELERATION_SCREEN_CACHE, + DEFAULT_ACCELERATION_SCREEN_CACHE, + FLOW_PERCENT_SCREEN_CACHE, + ZOFFSET_SCREEN_CACHE, + STEPPER_CURRENT_SCREEN_CACHE, + STEPPER_BUMP_SENSITIVITY_SCREEN_CACHE, + PRINTING_SCREEN_CACHE, + FILES_SCREEN_CACHE, + INTERFACE_SETTINGS_SCREEN_CACHE, + INTERFACE_SOUNDS_SCREEN_CACHE, + LOCK_SCREEN_CACHE, + DISPLAY_TIMINGS_SCREEN_CACHE +}; + +// To save MCU RAM, the status message is "baked" in to the status screen +// cache, so we reserve a large chunk of memory for the DL cache + +#define STATUS_SCREEN_DL_SIZE 4096 +#define ALERT_BOX_DL_SIZE 3072 +#define SPINNER_DL_SIZE 3072 +#define FILE_SCREEN_DL_SIZE 4160 +#define PRINTING_SCREEN_DL_SIZE 2048 + +/************************* MENU SCREEN DECLARATIONS *************************/ + +#include "../generic/base_screen.h" +#include "../generic/base_numeric_adjustment_screen.h" +#include "../generic/dialog_box_base_class.h" +#include "../generic/boot_screen.h" +#include "../generic/about_screen.h" +#include "../generic/kill_screen.h" +#include "../generic/alert_dialog_box.h" +#include "../generic/spinner_dialog_box.h" +#include "../generic/restore_failsafe_dialog_box.h" +#include "../generic/save_settings_dialog_box.h" +#include "../generic/confirm_start_print_dialog_box.h" +#include "../generic/confirm_abort_print_dialog_box.h" +#include "../generic/confirm_user_request_alert_box.h" +#include "../generic/touch_calibration_screen.h" +#include "../generic/move_axis_screen.h" +#include "../generic/steps_screen.h" +#include "../generic/feedrate_percent_screen.h" +#include "../generic/max_velocity_screen.h" +#include "../generic/max_acceleration_screen.h" +#include "../generic/default_acceleration_screen.h" +#include "../generic/temperature_screen.h" +#include "../generic/interface_sounds_screen.h" +#include "../generic/interface_settings_screen.h" +#include "../generic/lock_screen.h" +#include "../generic/endstop_state_screen.h" +#include "../generic/display_tuning_screen.h" +#include "../generic/media_player_screen.h" +#include "../generic/statistics_screen.h" +#include "../generic/stepper_current_screen.h" +#include "../generic/stepper_bump_sensitivity_screen.h" +#include "../generic/leveling_menu.h" +#include "../generic/z_offset_screen.h" +#include "../generic/files_screen.h" + +#include "bio_status_screen.h" +#include "bio_main_menu.h" +#include "bio_tune_menu.h" +#include "bio_advanced_settings.h" +#include "bio_printing_dialog_box.h" +#include "bio_confirm_home_xyz.h" +#include "bio_confirm_home_e.h" diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/leveling_menu.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/leveling_menu.cpp index ec3cc10a8e..57c8a7505c 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/leveling_menu.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/leveling_menu.cpp @@ -23,9 +23,9 @@ #include "../config.h" #include "../screens.h" -#if ENABLED(COCOA_LEVELING_MENU) +#ifdef COCOA_LEVELING_MENU -#if ENABLED(BLTOUCH) +#if BOTH(HAS_BED_PROBE,BLTOUCH) #include "../../../../feature/bltouch.h" #endif diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/main_menu.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/main_menu.cpp index 28dad42b13..a990717fb3 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/main_menu.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/main_menu.cpp @@ -88,7 +88,7 @@ bool MainMenu::onTouchEnd(uint8_t tag) { case 8: GOTO_SCREEN(AdvancedSettingsMenu); break; case 9: injectCommands_P(PSTR("M84")); break; #if HAS_LEVELING - case 10: GOTO_SCREEN(LevelingMenu); break; + case 10: GOTO_SCREEN(LevelingMenu); break; #endif case 11: GOTO_SCREEN(AboutScreen); break; default: diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/preheat_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/preheat_screen.cpp index 3bcc64fd93..75b1fcc9c1 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/preheat_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/preheat_screen.cpp @@ -84,16 +84,6 @@ void PreheatTimerScreen::draw_interaction_buttons(draw_mode_t what) { void PreheatTimerScreen::draw_adjuster(draw_mode_t what, uint8_t tag, progmem_str label, float value, int16_t x, int16_t y, int16_t w, int16_t h) { #define SUB_COLS 9 #define SUB_ROWS 2 - #define SUB_GRID_W(W) ((W)*w/SUB_COLS) - #define SUB_GRID_H(H) ((H)*h/SUB_ROWS) - #define SUB_GRID_X(X) (SUB_GRID_W((X)-1) + x) - #define SUB_GRID_Y(Y) (SUB_GRID_H((Y)-1) + y) - #define SUB_X(X) (SUB_GRID_X(X) + MARGIN_L) - #define SUB_Y(Y) (SUB_GRID_Y(Y) + MARGIN_T) - #define SUB_W(W) (SUB_GRID_W(W) - MARGIN_L - MARGIN_R) - #define SUB_H(H) (SUB_GRID_H(H) - MARGIN_T - MARGIN_B) - #define SUB_POS(X,Y) SUB_X(X), SUB_Y(Y) - #define SUB_SIZE(W,H) SUB_W(W), SUB_H(H) CommandProcessor cmd; cmd.tag(0) diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/screens.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/screens.h new file mode 100644 index 0000000000..87d31da6f6 --- /dev/null +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/screens.h @@ -0,0 +1,134 @@ +/************* + * screens.h * + *************/ + +/**************************************************************************** + * Written By Mark Pelletier 2017 - Aleph Objects, Inc. * + * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. * + * * + * 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. * + * * + * To view a copy of the GNU General Public License, go to the following * + * location: . * + ****************************************************************************/ + +#pragma once + + +/********************************* DL CACHE SLOTS ******************************/ + +// In order to reduce SPI traffic, we cache display lists (DL) in RAMG. This +// is done using the CLCD::DLCache class, which takes a unique ID for each +// cache location. These IDs are defined here: + +enum { + STATUS_SCREEN_CACHE, + MENU_SCREEN_CACHE, + TUNE_SCREEN_CACHE, + ALERT_BOX_CACHE, + SPINNER_CACHE, + ADVANCED_SETTINGS_SCREEN_CACHE, + MOVE_AXIS_SCREEN_CACHE, + TEMPERATURE_SCREEN_CACHE, + STEPS_SCREEN_CACHE, + MAX_FEEDRATE_SCREEN_CACHE, + MAX_VELOCITY_SCREEN_CACHE, + MAX_ACCELERATION_SCREEN_CACHE, + DEFAULT_ACCELERATION_SCREEN_CACHE, + FLOW_PERCENT_SCREEN_CACHE, + LEVELING_SCREEN_CACHE, + ZOFFSET_SCREEN_CACHE, + BED_MESH_VIEW_SCREEN_CACHE, + BED_MESH_EDIT_SCREEN_CACHE, + STEPPER_CURRENT_SCREEN_CACHE, + #if HAS_JUNCTION_DEVIATION + JUNC_DEV_SCREEN_CACHE, + #else + JERK_SCREEN_CACHE, + #endif + CASE_LIGHT_SCREEN_CACHE, + FILAMENT_MENU_CACHE, + LINEAR_ADVANCE_SCREEN_CACHE, + PREHEAT_MENU_CACHE, + PREHEAT_TIMER_SCREEN_CACHE, + LOAD_CHOCOLATE_SCREEN_CACHE, + MOVE_XYZ_SCREEN_CACHE, + MOVE_E_SCREEN_CACHE, + FILES_SCREEN_CACHE, + INTERFACE_SETTINGS_SCREEN_CACHE, + INTERFACE_SOUNDS_SCREEN_CACHE, + LOCK_SCREEN_CACHE, + DISPLAY_TIMINGS_SCREEN_CACHE +}; + +// To save MCU RAM, the status message is "baked" in to the status screen +// cache, so we reserve a large chunk of memory for the DL cache + +#define STATUS_SCREEN_DL_SIZE 4096 +#define ALERT_BOX_DL_SIZE 3072 +#define SPINNER_DL_SIZE 3072 +#define FILE_SCREEN_DL_SIZE 4160 +#define PRINTING_SCREEN_DL_SIZE 2048 + +/************************* MENU SCREEN DECLARATIONS *************************/ + +#include "../generic/base_screen.h" +#include "../generic/base_numeric_adjustment_screen.h" +#include "../generic/dialog_box_base_class.h" +#include "../generic/boot_screen.h" +#include "../generic/about_screen.h" +#include "../generic/kill_screen.h" +#include "../generic/alert_dialog_box.h" +#include "../generic/spinner_dialog_box.h" +#include "../generic/restore_failsafe_dialog_box.h" +#include "../generic/save_settings_dialog_box.h" +#include "../generic/confirm_start_print_dialog_box.h" +#include "../generic/confirm_abort_print_dialog_box.h" +#include "../generic/confirm_user_request_alert_box.h" +#include "../generic/touch_calibration_screen.h" +#include "../generic/move_axis_screen.h" +#include "../generic/steps_screen.h" +#include "../generic/feedrate_percent_screen.h" +#include "../generic/max_velocity_screen.h" +#include "../generic/max_acceleration_screen.h" +#include "../generic/default_acceleration_screen.h" +#include "../generic/temperature_screen.h" +#include "../generic/interface_sounds_screen.h" +#include "../generic/interface_settings_screen.h" +#include "../generic/lock_screen.h" +#include "../generic/endstop_state_screen.h" +#include "../generic/display_tuning_screen.h" +#include "../generic/statistics_screen.h" +#include "../generic/stepper_current_screen.h" +#include "../generic/leveling_menu.h" +#include "../generic/z_offset_screen.h" +#include "../generic/bed_mesh_base.h" +#include "../generic/bed_mesh_view_screen.h" +#include "../generic/bed_mesh_edit_screen.h" +#include "../generic/case_light_screen.h" +#include "../generic/linear_advance_screen.h" +#include "../generic/files_screen.h" +#include "../generic/move_axis_screen.h" +#include "../generic/flow_percent_screen.h" +#if HAS_JUNCTION_DEVIATION + #include "../generic/junction_deviation_screen.h" +#else + #include "../generic/jerk_screen.h" +#endif + +#include "status_screen.h" +#include "main_menu.h" +#include "advanced_settings_menu.h" +#include "preheat_menu.h" +#include "preheat_screen.h" +#include "load_chocolate.h" +#include "move_xyz_screen.h" +#include "move_e_screen.h" diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.cpp index 38fdc2bb26..467d3b9119 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.cpp @@ -294,4 +294,14 @@ void StatusScreen::onIdle() { } } +void StatusScreen::onMediaInserted() { + if (AT_SCREEN(StatusScreen)) + setStatusMessage(GET_TEXT_F(MSG_MEDIA_INSERTED)); +} + +void StatusScreen::onMediaRemoved() { + if (AT_SCREEN(StatusScreen) || ExtUI::isPrintingFromMedia()) + setStatusMessage(GET_TEXT_F(MSG_MEDIA_REMOVED)); +} + #endif // COCOA_STATUS_SCREEN diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.h index 1cddfa0896..75b4333351 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.h @@ -52,4 +52,6 @@ class StatusScreen : public BaseScreen, public CachedScreen static bool onTouchHeld(uint8_t tag); static bool onTouchEnd(uint8_t tag); static void onIdle(); + static void onMediaInserted(); + static void onMediaRemoved(); }; diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/config.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/config.h index 76b231536b..05e19b20e4 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/config.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/config.h @@ -21,6 +21,10 @@ #pragma once +// Configure this display with options in Configuration_adv.h +#include "../../../inc/MarlinConfigPre.h" +#if ENABLED(TOUCH_UI_FTDI_EVE) + #include "compat.h" -// Configure this display with options in Configuration_adv.h +#endif diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_extui.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_extui.cpp index e15f61be00..9faedae711 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_extui.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_extui.cpp @@ -45,24 +45,23 @@ namespace ExtUI { } void onMediaInserted() { - if (AT_SCREEN(StatusScreen)) - StatusScreen::setStatusMessage(GET_TEXT_F(MSG_MEDIA_INSERTED)); - sound.play(media_inserted, PLAY_ASYNCHRONOUS); + #if ENABLED(SDSUPPORT) + sound.play(media_inserted, PLAY_ASYNCHRONOUS); + StatusScreen::onMediaInserted(); + #endif } void onMediaRemoved() { - if (isPrintingFromMedia()) { - stopPrint(); - InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_FAILED); - } - else - sound.play(media_removed, PLAY_ASYNCHRONOUS); - - if (AT_SCREEN(StatusScreen) || isPrintingFromMedia()) - StatusScreen::setStatusMessage(GET_TEXT_F(MSG_MEDIA_REMOVED)); - #if ENABLED(SDSUPPORT) - if (AT_SCREEN(FilesScreen)) GOTO_SCREEN(StatusScreen); + if (isPrintingFromMedia()) { + stopPrint(); + InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_FAILED); + } + else + sound.play(media_removed, PLAY_ASYNCHRONOUS); + + StatusScreen::onMediaRemoved(); + FilesScreen::onMediaRemoved(); #endif } diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/poly_ui.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/poly_ui.h index ba41650f2f..2e74ec3a47 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/poly_ui.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/poly_ui.h @@ -239,9 +239,11 @@ class DeduplicatedPolyReader : public POLY_READER { */ template> class GenericPolyUI { - private: + protected: CommandProcessor &cmd; + draw_mode_t mode; + private: // Attributes used to paint buttons uint32_t btn_fill_color = 0x000000; @@ -250,8 +252,6 @@ class GenericPolyUI { uint32_t btn_stroke_color = 0x000000; uint8_t btn_stroke_width = 28; - draw_mode_t mode; - public: enum ButtonStyle : uint8_t { FILL = 1, diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/file2cpp.py b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/file2cpp.py new file mode 100755 index 0000000000..25919c3c4d --- /dev/null +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/file2cpp.py @@ -0,0 +1,47 @@ +#!/usr/bin/python + +# Written By Marcio Teixeira 2021 - SynDaver Labs, Inc. +# +# 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. +# +# To view a copy of the GNU General Public License, go to the following +# location: . + +from __future__ import print_function +import argparse +import textwrap +import os +import zlib + +def deflate(data): + return zlib.compress(data) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Converts a file into a packed C array for use as data') + parser.add_argument("input") + parser.add_argument("-d", "--deflate", action="store_true", help="Packs the data using the deflate algorithm") + args = parser.parse_args() + + varname = os.path.splitext(os.path.basename(args.input))[0]; + + with open(args.input, "rb") as in_file: + data = in_file.read() + if args.deflate: + data = deflate(data) + data = bytearray(data) + data = list(map(lambda a: "0x" + format(a, '02x'), data)) + nElements = len(data) + data = ', '.join(data) + data = textwrap.fill(data, 75, initial_indent = ' ', subsequent_indent = ' ') + + print("const unsigned char " + varname + "[" + format(nElements) + "] PROGMEM = {") + print(data) + print("};") diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/font2cpp.py b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/font2cpp.py new file mode 100755 index 0000000000..0c4499e9aa --- /dev/null +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/font2cpp.py @@ -0,0 +1,108 @@ +#!/usr/bin/python + +# Written By Marcio Teixeira 2019 - Aleph Objects, Inc. +# +# 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. +# +# To view a copy of the GNU General Public License, go to the following +# location: . + +from __future__ import print_function +from PIL import Image +import argparse +import textwrap + +def pack_rle(data): + """Use run-length encoding to pack the bytes""" + rle = [] + value = data[0] + count = 0 + for i in data: + if i != value or count == 255: + rle.append(count) + rle.append(value) + value = i + count = 1 + else: + count += 1 + rle.append(count) + rle.append(value) + return rle + +class WriteSource: + def __init__(self, lines_in_blocks): + self.blocks = [] + self.values = [] + self.block_size = lines_in_blocks + self.rows = 0 + + def add_pixel(self, value): + self.values.append(value) + + def convert_to_4bpp(self, data, chunk_size = 0): + # Invert the image + data = list(map(lambda i: 255 - i, data)) + # Quanitize 8-bit values into 4-bits + data = list(map(lambda i: i >> 4, data)) + # Make sure there is an even number of elements + if (len(data) & 1) == 1: + data.append(0) + # Combine each two adjacent values into one + i = iter(data) + data = list(map(lambda a, b: a << 4 | b, i ,i)) + # Pack the data + data = pack_rle(data) + # Convert values into hex strings + return list(map(lambda a: "0x" + format(a, '02x'), data)) + + def end_row(self, y): + # Pad each row into even number of values + if len(self.values) & 1: + self.values.append(0) + + self.rows += 1 + if self.block_size and (self.rows % self.block_size) == 0: + self.blocks.append(self.values) + self.values = [] + + def write(self): + if len(self.values): + self.blocks.append(self.values) + + block_strs = []; + for b in self.blocks: + data = self.convert_to_4bpp(b) + data = ', '.join(data) + data = textwrap.fill(data, 75, initial_indent = ' ', subsequent_indent = ' ') + block_strs.append(data) + + print("const unsigned char font[] PROGMEM = {") + for i, b in enumerate(block_strs): + if i: + print(',') + print('\n /* {} */'.format(i)) + print(b, end='') + print("\n};") + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Converts a grayscale bitmap into a 16-level RLE packed C array for use as font data') + parser.add_argument("input") + parser.add_argument('--char_height', help='Adds a separator every so many lines', type=int) + args = parser.parse_args() + + writer = WriteSource(args.char_height) + + img = Image.open(args.input).convert('L') + for y in range(img.height): + for x in range(img.width): + writer.add_pixel(img.getpixel((x,y))) + writer.end_row(y) + writer.write() diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/img2cpp.py b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/img2cpp.py new file mode 100755 index 0000000000..5908f5bf17 --- /dev/null +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/img2cpp.py @@ -0,0 +1,113 @@ +#!/usr/bin/python + +# Written By Marcio Teixeira 2021 - SynDaver Labs, Inc. +# +# 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. +# +# To view a copy of the GNU General Public License, go to the following +# location: . + +from __future__ import print_function +from PIL import Image +import argparse +import textwrap +import os +import sys +import zlib + +class WriteSource: + def __init__(self, mode): + self.values = [] + self.mode = mode + self.offset = 8 + self.byte = 0 + + def finish_byte(self): + if self.offset != 8: + self.values.append(self.byte) + self.offset = 8 + self.byte = 0 + + def add_bits_to_byte(self, value, size = 1): + self.offset -= size + self.byte = self.byte | value << self.offset + if self.offset == 0: + self.finish_byte() + + def append_rgb565(self, color): + value = ((color[0] & 0xF8) << 8) + ((color[1] & 0xFC) << 3) + ((color[2] & 0xF8) >> 3) + self.values.append((value & 0x00FF) >> 0); + self.values.append((value & 0xFF00) >> 8); + + def append_rgb332(self, color): + value = (color[0] & 0xE0) + ((color[1] & 0xE0) >> 3) + ((color[2] & 0xC0) >> 6) + self.values.append(value); + + def append_grayscale(self, color, bits): + luminance = int(0.2126 * color[0] + 0.7152 * color[1] + 0.0722 * color[2]) + self.add_bits_to_byte(luminance >> (8 - bits), bits) + + def deflate(self, data): + return zlib.compress(data) + + def add_pixel(self, color): + if self.mode == "l1": + self.append_grayscale(color, 1) + elif self.mode == "l2": + self.append_grayscale(color, 2) + elif self.mode == "l4": + self.append_grayscale(color, 4) + elif self.mode == "l8": + self.append_grayscale(color, 8) + elif self.mode == "rgb565": + self.append_rgb565(color) + elif self.mode == "rgb332": + self.append_rgb332(color) + + def end_row(self, y): + if self.mode in ["l1", "l2", "l3"]: + self.finish_byte() + + def write(self, varname, deflate): + print("Length of uncompressed data: ", len(self.values), file=sys.stderr) + data = bytes(bytearray(self.values)) + if deflate: + data = self.deflate(data) + print("Length of data after compression: ", len(data), file=sys.stderr) + data = bytearray(data) + data = list(map(lambda a: "0x" + format(a, '02x'), data)) + nElements = len(data) + data = ', '.join(data) + data = textwrap.fill(data, 75, initial_indent = ' ', subsequent_indent = ' ') + + print("const unsigned char " + varname + "[" + format(nElements) + "] PROGMEM = {") + print(data) + print("};") + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Converts a bitmap into a C array') + parser.add_argument("input") + parser.add_argument("-d", "--deflate", action="store_true", help="Packs the data using the deflate algorithm") + parser.add_argument("-m", "--mode", default="l1", help="Mode, can be l1, l2, l4, l8, rgb332 or rgb565") + args = parser.parse_args() + + varname = os.path.splitext(os.path.basename(args.input))[0]; + + writer = WriteSource(args.mode) + + img = Image.open(args.input) + print("Image height: ", img.height, file=sys.stderr) + print("Image width: ", img.width, file=sys.stderr) + for y in range(img.height): + for x in range(img.width): + writer.add_pixel(img.getpixel((x,y))) + writer.end_row(y) + writer.write(varname, args.deflate) diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp index 3d2c6a9e44..4e90e71e8a 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp @@ -91,20 +91,22 @@ void AboutScreen::onRedraw(draw_mode_t) { draw_text_box(cmd, FW_INFO_POS, about_str, OPT_CENTER, font_medium); draw_text_box(cmd, INSET_POS(LICENSE_POS), GET_TEXT_F(MSG_LICENSE), OPT_CENTER, font_tiny); - cmd.font(font_medium) - .colors(normal_btn) - .tag(2).button(STATS_POS, GET_TEXT_F(MSG_INFO_STATS_MENU)) - .colors(action_btn) + cmd.font(font_medium); + #if ENABLED(PRINTCOUNTER) && defined(FTDI_STATISTICS_SCREEN) + cmd.colors(normal_btn) + .tag(2).button(STATS_POS, GET_TEXT_F(MSG_INFO_STATS_MENU)); + #endif + cmd.colors(action_btn) .tag(1).button(BACK_POS, GET_TEXT_F(MSG_BACK)); } bool AboutScreen::onTouchEnd(uint8_t tag) { switch (tag) { case 1: GOTO_PREVIOUS(); break; - #if ENABLED(PRINTCOUNTER) + #if ENABLED(PRINTCOUNTER) && defined(FTDI_STATISTICS_SCREEN) case 2: GOTO_SCREEN(StatisticsScreen); break; #endif - #if ENABLED(TOUCH_UI_DEVELOPER_MENU) + #if ENABLED(TOUCH_UI_DEVELOPER_MENU) && defined(FTDI_DEVELOPER_MENU) case 3: GOTO_SCREEN(DeveloperMenu); break; #endif default: return false; diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.cpp index 3981a37042..0a8bebea3c 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.cpp @@ -45,7 +45,7 @@ bool BaseScreen::buttonStyleCallback(CommandProcessor &cmd, uint8_t tag, uint8_t return false; } - #if LCD_TIMEOUT_TO_STATUS > 0 + #if SCREENS_CAN_TIME_OUT if (EventLoop::get_pressed_tag() != 0) { reset_menu_timeout(); } @@ -65,7 +65,7 @@ bool BaseScreen::buttonStyleCallback(CommandProcessor &cmd, uint8_t tag, uint8_t } void BaseScreen::onIdle() { - #if LCD_TIMEOUT_TO_STATUS > 0 + #if SCREENS_CAN_TIME_OUT if ((millis() - last_interaction) > LCD_TIMEOUT_TO_STATUS) { reset_menu_timeout(); #if ENABLED(TOUCH_UI_DEBUG) @@ -77,12 +77,10 @@ void BaseScreen::onIdle() { } void BaseScreen::reset_menu_timeout() { - #if LCD_TIMEOUT_TO_STATUS > 0 - last_interaction = millis(); - #endif + TERN_(SCREENS_CAN_TIME_OUT, last_interaction = millis()); } -#if LCD_TIMEOUT_TO_STATUS > 0 +#if SCREENS_CAN_TIME_OUT uint32_t BaseScreen::last_interaction; #endif diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.h index cbeea1f750..030fa51a2a 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.h @@ -27,7 +27,7 @@ class BaseScreen : public UIScreen { protected: - #if LCD_TIMEOUT_TO_STATUS > 0 + #if SCREENS_CAN_TIME_OUT static uint32_t last_interaction; #endif diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_edit_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_edit_screen.cpp index e06fb52773..3dfcd429a5 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_edit_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_edit_screen.cpp @@ -190,17 +190,11 @@ bool BedMeshEditScreen::onTouchEnd(uint8_t tag) { } void BedMeshEditScreen::show() { - // On entry, home if needed and save current mesh - if (!ExtUI::isMachineHomed()) { - SpinnerDialogBox::enqueueAndWait_P(F("G28\nG29 S1")); - // After the spinner, go to this screen. - current_screen.forget(); - PUSH_SCREEN(BedMeshEditScreen); - } - else { - injectCommands_P(PSTR("G29 S1")); - GOTO_SCREEN(BedMeshEditScreen); - } + // On entry, always home (to account for possible Z offset changes) and save current mesh + SpinnerDialogBox::enqueueAndWait_P(F("G28\nG29 S1")); + // After the spinner, go to this screen. + current_screen.forget(); + PUSH_SCREEN(BedMeshEditScreen); } #endif // FTDI_BED_MESH_EDIT_SCREEN diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_view_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_view_screen.cpp index 75b15828a2..552cd831ea 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_view_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_view_screen.cpp @@ -132,7 +132,6 @@ void BedMeshViewScreen::onMeshUpdate(const int8_t x, const int8_t y, const ExtUI mydata.count = GRID_MAX_POINTS; break; case ExtUI::G26_START: - GOTO_SCREEN(BedMeshViewScreen); mydata.message = nullptr; mydata.count = 0; break; @@ -161,7 +160,7 @@ void BedMeshViewScreen::doProbe() { void BedMeshViewScreen::doMeshValidation() { mydata.count = 0; GOTO_SCREEN(StatusScreen); - injectCommands_P(PSTR("M75\nG28 O\nM117 Heating...\nG26 R X0 Y0\nG27\nM77")); + injectCommands_P(PSTR("G28\nM117 Heating...\nG26 R X0 Y0\nG27")); } void BedMeshViewScreen::show() { diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/boot_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/boot_screen.cpp index d2a2269295..c0940bed5c 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/boot_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/boot_screen.cpp @@ -83,8 +83,10 @@ void BootScreen::onIdle() { if (UIData::animations_enabled()) { // If there is a startup video in the flash SPI, play // that, otherwise show a static splash screen. - if (!MediaPlayerScreen::playBootMedia()) - showSplashScreen(); + #ifdef FTDI_MEDIA_PLAYER_SCREEN + if (!MediaPlayerScreen::playBootMedia()) + #endif + showSplashScreen(); } #endif diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/change_filament_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/change_filament_screen.cpp index a3cb91af5d..46d3a4ea1c 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/change_filament_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/change_filament_screen.cpp @@ -76,7 +76,7 @@ constexpr static ChangeFilamentScreenData &mydata = screen_data.ChangeFilamentSc /****************** COLOR SCALE ***********************/ -uint32_t getWarmColor(uint16_t temp, uint16_t cool, uint16_t low, uint16_t med, uint16_t high) { +uint32_t ChangeFilamentScreen::getWarmColor(uint16_t temp, uint16_t cool, uint16_t low, uint16_t med, uint16_t high) { rgb_t R0, R1, mix; float t; diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/change_filament_screen.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/change_filament_screen.h index 43a4bae6e0..42eaf25f4a 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/change_filament_screen.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/change_filament_screen.h @@ -38,9 +38,9 @@ class ChangeFilamentScreen : public BaseScreen, public CachedScreen. * + ****************************************************************************/ + +#pragma once + +/********************************* DL CACHE SLOTS ******************************/ + +// In order to reduce SPI traffic, we cache display lists (DL) in RAMG. This +// is done using the CLCD::DLCache class, which takes a unique ID for each +// cache location. These IDs are defined here: + +enum { + STATUS_SCREEN_CACHE, + MENU_SCREEN_CACHE, + TUNE_SCREEN_CACHE, + ALERT_BOX_CACHE, + SPINNER_CACHE, + ADVANCED_SETTINGS_SCREEN_CACHE, + MOVE_AXIS_SCREEN_CACHE, + TEMPERATURE_SCREEN_CACHE, + STEPS_SCREEN_CACHE, + MAX_FEEDRATE_SCREEN_CACHE, + MAX_VELOCITY_SCREEN_CACHE, + MAX_ACCELERATION_SCREEN_CACHE, + DEFAULT_ACCELERATION_SCREEN_CACHE, + FLOW_PERCENT_SCREEN_CACHE, + #if HAS_LEVELING + LEVELING_SCREEN_CACHE, + #if HAS_BED_PROBE + ZOFFSET_SCREEN_CACHE, + #endif + #if HAS_MESH + BED_MESH_VIEW_SCREEN_CACHE, + BED_MESH_EDIT_SCREEN_CACHE, + #endif + #endif + #if ENABLED(BABYSTEPPING) + ADJUST_OFFSETS_SCREEN_CACHE, + #endif + #if HAS_TRINAMIC_CONFIG + STEPPER_CURRENT_SCREEN_CACHE, + STEPPER_BUMP_SENSITIVITY_SCREEN_CACHE, + #endif + #if HAS_MULTI_HOTEND + NOZZLE_OFFSET_SCREEN_CACHE, + #endif + #if ENABLED(BACKLASH_GCODE) + BACKLASH_COMPENSATION_SCREEN_CACHE, + #endif + #if HAS_JUNCTION_DEVIATION + JUNC_DEV_SCREEN_CACHE, + #else + JERK_SCREEN_CACHE, + #endif + #if ENABLED(CASE_LIGHT_ENABLE) + CASE_LIGHT_SCREEN_CACHE, + #endif + #if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) + FILAMENT_MENU_CACHE, + #endif + #if ENABLED(LIN_ADVANCE) + LINEAR_ADVANCE_SCREEN_CACHE, + #endif + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + FILAMENT_RUNOUT_SCREEN_CACHE, + #endif + #if ENABLED(SDSUPPORT) + FILES_SCREEN_CACHE, + #endif + #if ENABLED(CUSTOM_MENU_MAIN) + CUSTOM_USER_MENUS_SCREEN_CACHE, + #endif + CHANGE_FILAMENT_SCREEN_CACHE, + INTERFACE_SETTINGS_SCREEN_CACHE, + INTERFACE_SOUNDS_SCREEN_CACHE, + LOCK_SCREEN_CACHE, + DISPLAY_TIMINGS_SCREEN_CACHE +}; + +// To save MCU RAM, the status message is "baked" in to the status screen +// cache, so we reserve a large chunk of memory for the DL cache + +#define STATUS_SCREEN_DL_SIZE 4096 +#define ALERT_BOX_DL_SIZE 3072 +#define SPINNER_DL_SIZE 3072 +#define FILE_SCREEN_DL_SIZE 4160 +#define PRINTING_SCREEN_DL_SIZE 2048 + +/************************* MENU SCREEN DECLARATIONS *************************/ + +#include "base_screen.h" +#include "base_numeric_adjustment_screen.h" +#include "dialog_box_base_class.h" +#include "status_screen.h" +#include "main_menu.h" +#include "advanced_settings_menu.h" +#include "tune_menu.h" +#include "boot_screen.h" +#include "about_screen.h" +#include "kill_screen.h" +#include "alert_dialog_box.h" +#include "spinner_dialog_box.h" +#include "restore_failsafe_dialog_box.h" +#include "save_settings_dialog_box.h" +#include "confirm_start_print_dialog_box.h" +#include "confirm_abort_print_dialog_box.h" +#include "confirm_user_request_alert_box.h" +#include "touch_calibration_screen.h" +#include "touch_registers_screen.h" +#include "change_filament_screen.h" +#include "move_axis_screen.h" +#include "steps_screen.h" +#include "feedrate_percent_screen.h" +#include "max_velocity_screen.h" +#include "max_acceleration_screen.h" +#include "default_acceleration_screen.h" +#include "temperature_screen.h" +#include "interface_sounds_screen.h" +#include "interface_settings_screen.h" +#include "lock_screen.h" +#include "endstop_state_screen.h" +#include "display_tuning_screen.h" +#include "media_player_screen.h" + +#if ENABLED(PRINTCOUNTER) + #include "statistics_screen.h" +#endif + +#if HAS_TRINAMIC_CONFIG + #include "stepper_current_screen.h" + #include "stepper_bump_sensitivity_screen.h" +#endif + +#if HAS_MULTI_HOTEND + #include "nozzle_offsets_screen.h" +#endif + +#if HAS_LEVELING + #if ENABLED(TOUCH_UI_SYNDAVER_LEVEL) + #include "syndaver_level/leveling_menu.h" + #else + #include "leveling_menu.h" + #endif + #if HAS_BED_PROBE + #include "z_offset_screen.h" + #endif + #if HAS_MESH + #include "bed_mesh_base.h" + #include "bed_mesh_view_screen.h" + #include "bed_mesh_edit_screen.h" + #endif +#endif + +#if ENABLED(CALIBRATION_GCODE) + #include "confirm_auto_calibration_dialog_box.h" +#endif + +#if ENABLED(BABYSTEPPING) + #include "nudge_nozzle_screen.h" +#endif + +#if ENABLED(BACKLASH_GCODE) + #include "backlash_compensation_screen.h" +#endif + +#if HAS_JUNCTION_DEVIATION + #include "junction_deviation_screen.h" +#else + #include "jerk_screen.h" +#endif + +#if ENABLED(CASE_LIGHT_ENABLE) + #include "case_light_screen.h" +#endif + +#if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) + #include "filament_menu.h" +#endif + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #include "filament_runout_screen.h" +#endif + +#if ENABLED(LIN_ADVANCE) + #include "linear_advance_screen.h" +#endif + +#if ENABLED(SDSUPPORT) + #include "files_screen.h" +#endif + +#if ENABLED(CUSTOM_MENU_MAIN) + #include "custom_user_menus.h" +#endif + +#if ENABLED(TOUCH_UI_DEVELOPER_MENU) + #include "developer_menu.h" + #include "confirm_erase_flash_dialog_box.h" + #include "widget_demo_screen.h" + #include "stress_test_screen.h" +#endif + +#if NUM_LANGUAGES > 1 + #include "language_menu.h" +#endif diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/status_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/status_screen.cpp index 9ef481d39b..23ac90107b 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/status_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/status_screen.cpp @@ -461,4 +461,14 @@ bool StatusScreen::onTouchEnd(uint8_t tag) { return true; } +void StatusScreen::onMediaInserted() { + if (AT_SCREEN(StatusScreen)) + setStatusMessage(GET_TEXT_F(MSG_MEDIA_INSERTED)); +} + +void StatusScreen::onMediaRemoved() { + if (AT_SCREEN(StatusScreen) || ExtUI::isPrintingFromMedia()) + setStatusMessage(GET_TEXT_F(MSG_MEDIA_REMOVED)); +} + #endif // FTDI_STATUS_SCREEN diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/status_screen.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/status_screen.h index 3a2ba1746c..6033ba1ad9 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/status_screen.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/status_screen.h @@ -42,4 +42,6 @@ class StatusScreen : public BaseScreen, public CachedScreen { private: static void move(float mm, int16_t steps); static void runWizard(); + static bool wizardRunning(); public: static void onEntry(); + static void onExit(); static void onRedraw(draw_mode_t); static bool onTouchHeld(uint8_t tag); }; diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language_en.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language_en.h index 4ac44501d5..0d883d8d02 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language_en.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language_en.h @@ -130,7 +130,7 @@ namespace Language_en { PROGMEM Language_Str MSG_EEPROM_RESTORED = u8"Settings restored from backup"; PROGMEM Language_Str MSG_EEPROM_RESET = u8"Settings restored to default"; PROGMEM Language_Str MSG_EEPROM_SAVED = u8"Settings saved!"; - PROGMEM Language_Str MSG_EEPROM_SAVE_PROMPT = u8"Do you wish to save these settings for next power-on?"; + PROGMEM Language_Str MSG_EEPROM_SAVE_PROMPT = u8"Settings applied. Save these settings for next power-on?"; PROGMEM Language_Str MSG_EEPROM_RESET_WARNING = u8"Are you sure? Customizations will be lost."; PROGMEM Language_Str MSG_PASSCODE_REJECTED = u8"Wrong passcode!"; @@ -146,7 +146,7 @@ namespace Language_en { PROGMEM Language_Str MSG_AXIS_LEVELING = u8"Axis Leveling"; 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_PRINT_TEST = u8"Print Test (PLA)"; PROGMEM Language_Str MSG_MOVE_Z_TO_TOP = u8"Raise Z to Top"; #if ENABLED(TOUCH_UI_LULZBOT_BIO) diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/screens.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/screens.cpp index e1900ac793..ec627e313b 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/screens.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/screens.cpp @@ -113,6 +113,7 @@ SCREEN_TABLE { DECL_SCREEN_IF_INCLUDED(COCOA_PREHEAT_MENU) DECL_SCREEN_IF_INCLUDED(COCOA_PREHEAT_SCREEN) DECL_SCREEN_IF_INCLUDED(COCOA_LOAD_CHOCOLATE_SCREEN) + DECL_SCREEN_IF_INCLUDED(COCOA_LEVELING_MENU) DECL_SCREEN_IF_INCLUDED(COCOA_MOVE_XYZ_SCREEN) DECL_SCREEN_IF_INCLUDED(COCOA_MOVE_E_SCREEN) }; diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/screens.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/screens.h index f5e2160d10..fb3e909d2f 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/screens.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/screens.h @@ -22,7 +22,7 @@ #pragma once -#include "compat.h" +#include "config.h" #if ENABLED(TOUCH_UI_FTDI_EVE) @@ -37,237 +37,14 @@ extern tiny_timer_t refresh_timer; -/********************************* DL CACHE SLOTS ******************************/ - -// In order to reduce SPI traffic, we cache display lists (DL) in RAMG. This -// is done using the CLCD::DLCache class, which takes a unique ID for each -// cache location. These IDs are defined here: - -enum { - STATUS_SCREEN_CACHE, - MENU_SCREEN_CACHE, - TUNE_SCREEN_CACHE, - ALERT_BOX_CACHE, - SPINNER_CACHE, - ADVANCED_SETTINGS_SCREEN_CACHE, - MOVE_AXIS_SCREEN_CACHE, - TEMPERATURE_SCREEN_CACHE, - STEPS_SCREEN_CACHE, - MAX_FEEDRATE_SCREEN_CACHE, - MAX_VELOCITY_SCREEN_CACHE, - MAX_ACCELERATION_SCREEN_CACHE, - DEFAULT_ACCELERATION_SCREEN_CACHE, - FLOW_PERCENT_SCREEN_CACHE, - #if HAS_LEVELING - LEVELING_SCREEN_CACHE, - #if HAS_BED_PROBE - ZOFFSET_SCREEN_CACHE, - #endif - #if HAS_MESH - BED_MESH_VIEW_SCREEN_CACHE, - BED_MESH_EDIT_SCREEN_CACHE, - #endif - #endif - #if ENABLED(BABYSTEPPING) - ADJUST_OFFSETS_SCREEN_CACHE, - #endif - #if HAS_TRINAMIC_CONFIG - STEPPER_CURRENT_SCREEN_CACHE, - STEPPER_BUMP_SENSITIVITY_SCREEN_CACHE, - #endif - #if HAS_MULTI_HOTEND - NOZZLE_OFFSET_SCREEN_CACHE, - #endif - #if ENABLED(BACKLASH_GCODE) - BACKLASH_COMPENSATION_SCREEN_CACHE, - #endif - #if HAS_JUNCTION_DEVIATION - JUNC_DEV_SCREEN_CACHE, - #else - JERK_SCREEN_CACHE, - #endif - #if ENABLED(CASE_LIGHT_ENABLE) - CASE_LIGHT_SCREEN_CACHE, - #endif - #if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) - FILAMENT_MENU_CACHE, - #endif - #if ENABLED(LIN_ADVANCE) - LINEAR_ADVANCE_SCREEN_CACHE, - #endif - #if ENABLED(FILAMENT_RUNOUT_SENSOR) - FILAMENT_RUNOUT_SCREEN_CACHE, - #endif - #if ENABLED(TOUCH_UI_LULZBOT_BIO) - PRINTING_SCREEN_CACHE, - #endif - #if ENABLED(TOUCH_UI_COCOA_PRESS) - PREHEAT_MENU_CACHE, - PREHEAT_TIMER_SCREEN_CACHE, - LOAD_CHOCOLATE_SCREEN_CACHE, - MOVE_XYZ_SCREEN_CACHE, - MOVE_E_SCREEN_CACHE, - #endif - #if ENABLED(SDSUPPORT) - FILES_SCREEN_CACHE, - #endif - #if ENABLED(CUSTOM_MENU_MAIN) - CUSTOM_USER_MENUS_SCREEN_CACHE, - #endif - CHANGE_FILAMENT_SCREEN_CACHE, - INTERFACE_SETTINGS_SCREEN_CACHE, - INTERFACE_SOUNDS_SCREEN_CACHE, - LOCK_SCREEN_CACHE, - DISPLAY_TIMINGS_SCREEN_CACHE -}; - -// To save MCU RAM, the status message is "baked" in to the status screen -// cache, so we reserve a large chunk of memory for the DL cache - -#define STATUS_SCREEN_DL_SIZE 4096 -#define ALERT_BOX_DL_SIZE 3072 -#define SPINNER_DL_SIZE 3072 -#define FILE_SCREEN_DL_SIZE 4160 -#define PRINTING_SCREEN_DL_SIZE 2048 - -/************************* MENU SCREEN DECLARATIONS *************************/ - -#include "generic/base_screen.h" -#include "generic/base_numeric_adjustment_screen.h" -#include "generic/dialog_box_base_class.h" - #if ENABLED(TOUCH_UI_LULZBOT_BIO) - #include "bio_status_screen.h" - #include "bio_main_menu.h" - #include "bio_tune_menu.h" - #include "bio_advanced_settings.h" - #include "bio_printing_dialog_box.h" - #include "bio_confirm_home_xyz.h" - #include "bio_confirm_home_e.h" - + #include "bioprinter/screens.h" #elif ENABLED(TOUCH_UI_COCOA_PRESS) - #include "generic/move_axis_screen.h" - #include "generic/flow_percent_screen.h" - #include "generic/tune_menu.h" - #include "cocoa_press/status_screen.h" - #include "cocoa_press/main_menu.h" - #include "cocoa_press/advanced_settings_menu.h" - #include "cocoa_press/preheat_menu.h" - #include "cocoa_press/preheat_screen.h" - #include "cocoa_press/load_chocolate.h" - #include "cocoa_press/move_xyz_screen.h" - #include "cocoa_press/move_e_screen.h" - + #include "cocoa_press/screens.h" +#elif ENABLED(TOUCH_UI_SYNDAVER_LEVEL) + #include "syndaver_level/screens.h" #else - #include "generic/status_screen.h" - #include "generic/main_menu.h" - #include "generic/advanced_settings_menu.h" - #include "generic/tune_menu.h" -#endif - -#include "generic/boot_screen.h" -#include "generic/about_screen.h" -#include "generic/kill_screen.h" -#include "generic/alert_dialog_box.h" -#include "generic/spinner_dialog_box.h" -#include "generic/restore_failsafe_dialog_box.h" -#include "generic/save_settings_dialog_box.h" -#include "generic/confirm_start_print_dialog_box.h" -#include "generic/confirm_abort_print_dialog_box.h" -#include "generic/confirm_user_request_alert_box.h" -#include "generic/touch_calibration_screen.h" -#include "generic/touch_registers_screen.h" -#include "generic/change_filament_screen.h" -#include "generic/move_axis_screen.h" -#include "generic/steps_screen.h" -#include "generic/feedrate_percent_screen.h" -#include "generic/max_velocity_screen.h" -#include "generic/max_acceleration_screen.h" -#include "generic/default_acceleration_screen.h" -#include "generic/temperature_screen.h" -#include "generic/interface_sounds_screen.h" -#include "generic/interface_settings_screen.h" -#include "generic/lock_screen.h" -#include "generic/endstop_state_screen.h" -#include "generic/display_tuning_screen.h" -#include "generic/media_player_screen.h" - -#if ENABLED(PRINTCOUNTER) - #include "generic/statistics_screen.h" -#endif - -#if HAS_TRINAMIC_CONFIG - #include "generic/stepper_current_screen.h" - #include "generic/stepper_bump_sensitivity_screen.h" -#endif - -#if HAS_MULTI_HOTEND - #include "generic/nozzle_offsets_screen.h" -#endif - -#if HAS_LEVELING - #include "generic/leveling_menu.h" - #if HAS_BED_PROBE - #include "generic/z_offset_screen.h" - #endif - #if HAS_MESH - #include "generic/bed_mesh_base.h" - #include "generic/bed_mesh_view_screen.h" - #include "generic/bed_mesh_edit_screen.h" - #endif -#endif - -#if ENABLED(CALIBRATION_GCODE) - #include "generic/confirm_auto_calibration_dialog_box.h" -#endif - -#if ENABLED(BABYSTEPPING) - #include "generic/nudge_nozzle_screen.h" -#endif - -#if ENABLED(BACKLASH_GCODE) - #include "generic/backlash_compensation_screen.h" -#endif - -#if HAS_JUNCTION_DEVIATION - #include "generic/junction_deviation_screen.h" -#else - #include "generic/jerk_screen.h" -#endif - -#if ENABLED(CASE_LIGHT_ENABLE) - #include "generic/case_light_screen.h" -#endif - -#if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR) - #include "generic/filament_menu.h" -#endif - -#if ENABLED(FILAMENT_RUNOUT_SENSOR) - #include "generic/filament_runout_screen.h" -#endif - -#if ENABLED(LIN_ADVANCE) - #include "generic/linear_advance_screen.h" -#endif - -#if ENABLED(SDSUPPORT) - #include "generic/files_screen.h" -#endif - -#if ENABLED(CUSTOM_MENU_MAIN) - #include "generic/custom_user_menus.h" -#endif - -#if ENABLED(TOUCH_UI_DEVELOPER_MENU) - #include "generic/developer_menu.h" - #include "generic/confirm_erase_flash_dialog_box.h" - #include "generic/widget_demo_screen.h" - #include "generic/stress_test_screen.h" -#endif - -#if NUM_LANGUAGES > 1 - #include "generic/language_menu.h" + #include "generic/screens.h" #endif #endif // TOUCH_UI_FTDI_EVE diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/bitmaps.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/bitmaps.h index 8c0366ebeb..f7cb63125f 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/bitmaps.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/bitmaps.h @@ -36,7 +36,7 @@ namespace Theme { .height = 23, }; - constexpr PROGMEM unsigned char Extruder_Icon[] = { + constexpr PROGMEM unsigned char Extruder_Icon[69] = { 0x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xFE, 0xC0, 0x00, 0x03, @@ -68,12 +68,12 @@ namespace Theme { .filter = BILINEAR, .wrapx = BORDER, .wrapy = BORDER, - .RAMG_offset = 8100, + .RAMG_offset = 8069, .width = 32, .height = 23, }; - constexpr PROGMEM unsigned char Bed_Heat_Icon[] = { + constexpr PROGMEM unsigned char Bed_Heat_Icon[92] = { 0x01, 0x81, 0x81, 0x80, 0x01, 0x81, 0x81, 0x80, 0x00, 0xC0, 0xC0, 0xC0, @@ -105,12 +105,12 @@ namespace Theme { .filter = BILINEAR, .wrapx = BORDER, .wrapy = BORDER, - .RAMG_offset = 8300, + .RAMG_offset = 8161, .width = 32, .height = 32, }; - constexpr PROGMEM unsigned char Fan_Icon[] = { + constexpr PROGMEM unsigned char Fan_Icon[128] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, @@ -151,12 +151,12 @@ namespace Theme { .filter = BILINEAR, .wrapx = BORDER, .wrapy = BORDER, - .RAMG_offset = 9000, + .RAMG_offset = 8289, .width = 50, .height = 20, }; - constexpr PROGMEM unsigned char TD_Icon[] = { + constexpr PROGMEM unsigned char TD_Icon[140] = { 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, // Thumb Drive Widget 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x80, @@ -179,5 +179,55 @@ namespace Theme { 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00 }; - constexpr PROGMEM uint32_t UTF8_FONT_OFFSET = 10000; + constexpr PROGMEM bitmap_info_t File_Icon_Info = { + .format = L1, + .linestride = 4, + .filter = BILINEAR, + .wrapx = BORDER, + .wrapy = BORDER, + .RAMG_offset = 8429, + .width = 25, + .height = 32, + }; + + const unsigned char File_Icon[128] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x40, 0x03, 0x00, 0x00, + 0x40, 0x02, 0x80, 0x00, 0x40, 0x02, 0x40, 0x00, 0x40, 0x02, 0x20, 0x00, + 0x40, 0x02, 0x10, 0x00, 0x40, 0x02, 0x08, 0x00, 0x40, 0x02, 0x04, 0x00, + 0x40, 0x02, 0x02, 0x00, 0x40, 0x03, 0xFF, 0x00, 0x40, 0x00, 0x01, 0x00, + 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, + 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, + 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, + 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, + 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, + 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x01, 0x00, + 0x7F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + constexpr PROGMEM bitmap_info_t Clock_Icon_Info = { + .format = L1, + .linestride = 4, + .filter = BILINEAR, + .wrapx = BORDER, + .wrapy = BORDER, + .RAMG_offset = 8557, + .width = 32, + .height = 32, + }; + + const unsigned char Clock_Icon[128] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x7E, 0x7E, 0x00, + 0x00, 0xE0, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x07, 0x01, 0x00, 0xE0, + 0x0C, 0x01, 0x80, 0x70, 0x0C, 0x01, 0x80, 0x30, 0x18, 0x01, 0x80, 0x18, + 0x30, 0x01, 0x80, 0x08, 0x30, 0x01, 0x80, 0x0C, 0x20, 0x01, 0x80, 0x0C, + 0x60, 0x01, 0x80, 0x04, 0x60, 0x01, 0x80, 0x06, 0x60, 0x01, 0x80, 0x06, + 0x60, 0x01, 0xFF, 0x06, 0x60, 0x01, 0xFF, 0x06, 0x60, 0x00, 0x00, 0x06, + 0x60, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x0C, + 0x30, 0x00, 0x00, 0x0C, 0x30, 0x00, 0x00, 0x08, 0x18, 0x00, 0x00, 0x18, + 0x0C, 0x00, 0x00, 0x30, 0x0E, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0xE0, + 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x7F, 0xFE, 0x00, + 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + constexpr PROGMEM uint32_t UTF8_FONT_OFFSET = 10000; }; // namespace Theme diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/colors.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/colors.h index 1649675122..995379fcda 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/colors.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/colors.h @@ -108,6 +108,7 @@ namespace Theme { constexpr uint32_t bed_mesh_lines_rgb = accent_color_6; constexpr uint32_t bed_mesh_shadow_rgb = 0x444444; + #define BED_MESH_POINTS_GRAY #else constexpr uint32_t theme_darkest = gray_color_1; constexpr uint32_t theme_dark = gray_color_2; diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/sounds.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/sounds.cpp index afbed0cab1..1ed712ded1 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/sounds.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/sounds.cpp @@ -20,7 +20,7 @@ * location: . * ****************************************************************************/ -#include "../compat.h" +#include "../config.h" #if ENABLED(TOUCH_UI_FTDI_EVE) diff --git a/Marlin/src/lcd/extui/ui_api.cpp b/Marlin/src/lcd/extui/ui_api.cpp index 21289eed25..71fc95ccd1 100644 --- a/Marlin/src/lcd/extui/ui_api.cpp +++ b/Marlin/src/lcd/extui/ui_api.cpp @@ -309,7 +309,7 @@ namespace ExtUI { } float getAxisPosition_mm(const axis_t axis) { - return TERN0(JOYSTICK, flags.jogging) ? destination[axis] : current_position[axis]; + return current_position[axis]; } float getAxisPosition_mm(const extruder_t extruder) { @@ -1044,10 +1044,10 @@ namespace ExtUI { } bool isPrintingFromMediaPaused() { - return TERN0(SDSUPPORT, isPrintingFromMedia() && printingIsPaused()); + return TERN0(SDSUPPORT, IS_SD_PAUSED()); } - bool isPrintingFromMedia() { return IS_SD_PRINTING(); } + bool isPrintingFromMedia() { return TERN0(SDSUPPORT, IS_SD_PRINTING() || IS_SD_PAUSED()); } bool isPrinting() { return commandsInQueue() || isPrintingFromMedia() || printJobOngoing() || printingIsPaused(); diff --git a/Marlin/src/lcd/extui/ui_api.h b/Marlin/src/lcd/extui/ui_api.h index 1589898dff..bec78493ee 100644 --- a/Marlin/src/lcd/extui/ui_api.h +++ b/Marlin/src/lcd/extui/ui_api.h @@ -194,7 +194,11 @@ namespace ExtUI { void setHostResponse(const uint8_t); #endif - inline void simulateUserClick() { ui.lcd_clicked = true; } + inline void simulateUserClick() { + #if EITHER(HAS_LCD_MENU, EXTENSIBLE_UI) + ui.lcd_clicked = true; + #endif + } #if ENABLED(PRINTCOUNTER) char* getFailedPrints_str(char buffer[21]); diff --git a/Marlin/src/lcd/language/language_an.h b/Marlin/src/lcd/language/language_an.h index 0513de7f7d..787096994f 100644 --- a/Marlin/src/lcd/language/language_an.h +++ b/Marlin/src/lcd/language/language_an.h @@ -89,6 +89,7 @@ namespace Language_an { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Mover 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Mover 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Mover 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Mover 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Velocidat"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Base Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Boquilla"); diff --git a/Marlin/src/lcd/language/language_bg.h b/Marlin/src/lcd/language/language_bg.h index 5964652156..0d4291b835 100644 --- a/Marlin/src/lcd/language/language_bg.h +++ b/Marlin/src/lcd/language/language_bg.h @@ -79,6 +79,7 @@ namespace Language_bg { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Премести с 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Премести с 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Премести с 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Премести с 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Скорост"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Bed Z"); PROGMEM Language_Str MSG_NOZZLE = " " LCD_STR_THERMOMETER _UxGT(" Дюза"); diff --git a/Marlin/src/lcd/language/language_ca.h b/Marlin/src/lcd/language/language_ca.h index 6709a0ce55..f97a783d01 100644 --- a/Marlin/src/lcd/language/language_ca.h +++ b/Marlin/src/lcd/language/language_ca.h @@ -89,6 +89,7 @@ namespace Language_ca { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Mou 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Mou 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Mou 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Mou 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Velocitat"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Llit Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Nozzle"); diff --git a/Marlin/src/lcd/language/language_cz.h b/Marlin/src/lcd/language/language_cz.h index c434f5493b..ab2aaa943f 100644 --- a/Marlin/src/lcd/language/language_cz.h +++ b/Marlin/src/lcd/language/language_cz.h @@ -241,6 +241,7 @@ namespace Language_cz { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Posunout o 0,1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Posunout o 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Posunout o 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Posunout o 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Rychlost"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Výška podl."); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Tryska"); diff --git a/Marlin/src/lcd/language/language_da.h b/Marlin/src/lcd/language/language_da.h index 9258812843..95c2573ae1 100644 --- a/Marlin/src/lcd/language/language_da.h +++ b/Marlin/src/lcd/language/language_da.h @@ -79,6 +79,7 @@ namespace Language_da { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Flyt 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Flyt 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Flyt 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Flyt 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Hastighed"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Plade Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Dyse"); diff --git a/Marlin/src/lcd/language/language_de.h b/Marlin/src/lcd/language/language_de.h index ebc2445b11..7e40d42665 100644 --- a/Marlin/src/lcd/language/language_de.h +++ b/Marlin/src/lcd/language/language_de.h @@ -231,9 +231,10 @@ namespace Language_de { PROGMEM Language_Str MSG_MOVE_EN = _UxGT("Bewege Extruder *"); PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("Hotend zu kalt"); PROGMEM Language_Str MSG_MOVE_N_MM = _UxGT(" %s mm"); - PROGMEM Language_Str MSG_MOVE_01MM = _UxGT(" 0,1 mm"); - PROGMEM Language_Str MSG_MOVE_1MM = _UxGT(" 1,0 mm"); - PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("10,0 mm"); + PROGMEM Language_Str MSG_MOVE_01MM = _UxGT(" 0,1 mm"); + PROGMEM Language_Str MSG_MOVE_1MM = _UxGT(" 1,0 mm"); + PROGMEM Language_Str MSG_MOVE_10MM = _UxGT(" 10,0 mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("100,0 mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Geschw."); PROGMEM Language_Str MSG_BED_Z = _UxGT("Bett Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Düse"); diff --git a/Marlin/src/lcd/language/language_el.h b/Marlin/src/lcd/language/language_el.h index ebe27fecbd..b69b4695d3 100644 --- a/Marlin/src/lcd/language/language_el.h +++ b/Marlin/src/lcd/language/language_el.h @@ -87,6 +87,7 @@ namespace Language_el { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Μετακίνηση 0,1 μμ"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Μετακίνηση 1 μμ"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Μετακίνηση 10 μμ"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Μετακίνηση 100 μμ"); PROGMEM Language_Str MSG_SPEED = _UxGT("Ταχύτητα"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Επ. Εκτύπωσης Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Ακροφύσιο"); diff --git a/Marlin/src/lcd/language/language_el_gr.h b/Marlin/src/lcd/language/language_el_gr.h index e6909ad5bf..208d7c2363 100644 --- a/Marlin/src/lcd/language/language_el_gr.h +++ b/Marlin/src/lcd/language/language_el_gr.h @@ -88,6 +88,7 @@ namespace Language_el_gr { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Μετακίνηση 0,1 μμ"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Μετακίνηση 1 μμ"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Μετακίνηση 10 μμ"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Μετακίνηση 100 μμ"); PROGMEM Language_Str MSG_SPEED = _UxGT("Ταχύτητα"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Κλίνη Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Ακροφύσιο"); diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index 9a3f9b6e9f..6920f00d36 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -281,9 +281,11 @@ namespace Language_en { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Move 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Move 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Move 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Move 100mm"); PROGMEM Language_Str MSG_MOVE_0001IN = _UxGT("Move 0.001in"); PROGMEM Language_Str MSG_MOVE_001IN = _UxGT("Move 0.01in"); PROGMEM Language_Str MSG_MOVE_01IN = _UxGT("Move 0.1in"); + PROGMEM Language_Str MSG_MOVE_1IN = _UxGT("Move 1.0in"); PROGMEM Language_Str MSG_SPEED = _UxGT("Speed"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Bed Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Nozzle"); @@ -590,9 +592,9 @@ namespace Language_en { PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X Driver %"); PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Driver %"); PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z Driver %"); - PROGMEM Language_Str MSG_DAC_PERCENT_I = _UxGT("I Driver %"); - PROGMEM Language_Str MSG_DAC_PERCENT_J = _UxGT("J Driver %"); - PROGMEM Language_Str MSG_DAC_PERCENT_K = _UxGT("K Driver %"); + PROGMEM Language_Str MSG_DAC_PERCENT_I = AXIS4_STR _UxGT(" Driver %"); + PROGMEM Language_Str MSG_DAC_PERCENT_J = AXIS5_STR _UxGT(" Driver %"); + PROGMEM Language_Str MSG_DAC_PERCENT_K = AXIS6_STR _UxGT(" Driver %"); PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E Driver %"); PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("TMC CONNECTION ERROR"); PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("DAC EEPROM Write"); diff --git a/Marlin/src/lcd/language/language_es.h b/Marlin/src/lcd/language/language_es.h index b2d83aa05b..f342732161 100644 --- a/Marlin/src/lcd/language/language_es.h +++ b/Marlin/src/lcd/language/language_es.h @@ -236,6 +236,7 @@ namespace Language_es { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Mover 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Mover 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Mover 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Mover 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Velocidad"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Cama Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Boquilla"); diff --git a/Marlin/src/lcd/language/language_eu.h b/Marlin/src/lcd/language/language_eu.h index 1c1c9e423d..2be6f399d8 100644 --- a/Marlin/src/lcd/language/language_eu.h +++ b/Marlin/src/lcd/language/language_eu.h @@ -143,6 +143,7 @@ namespace Language_eu { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Mugitu 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Mugitu 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Mugitu 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Mugitu 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Abiadura"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Z Ohea"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Pita"); diff --git a/Marlin/src/lcd/language/language_fi.h b/Marlin/src/lcd/language/language_fi.h index 9954f1dd8a..0d3b97cc44 100644 --- a/Marlin/src/lcd/language/language_fi.h +++ b/Marlin/src/lcd/language/language_fi.h @@ -76,6 +76,7 @@ namespace Language_fi { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Liikuta 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Liikuta 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Liikuta 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Liikuta 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Nopeus"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Suutin"); PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Suutin ~"); diff --git a/Marlin/src/lcd/language/language_fr.h b/Marlin/src/lcd/language/language_fr.h index bdd91d3b29..5dbec298d4 100644 --- a/Marlin/src/lcd/language/language_fr.h +++ b/Marlin/src/lcd/language/language_fr.h @@ -235,6 +235,7 @@ namespace Language_fr { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Déplacer 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Déplacer 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Déplacer 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Déplacer 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Vitesse"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Lit Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Buse"); diff --git a/Marlin/src/lcd/language/language_gl.h b/Marlin/src/lcd/language/language_gl.h index 5745ce1eb8..3eec75e138 100644 --- a/Marlin/src/lcd/language/language_gl.h +++ b/Marlin/src/lcd/language/language_gl.h @@ -233,6 +233,7 @@ namespace Language_gl { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Mover 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Mover 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Mover 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Mover 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Velocidade"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Cama Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Bico"); diff --git a/Marlin/src/lcd/language/language_hr.h b/Marlin/src/lcd/language/language_hr.h index 1684ad0e1b..e4cbdaed6c 100644 --- a/Marlin/src/lcd/language/language_hr.h +++ b/Marlin/src/lcd/language/language_hr.h @@ -83,6 +83,7 @@ namespace Language_hr { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Miči 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Miči 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Miči 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Miči 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Brzina"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Bed Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Dizna"); diff --git a/Marlin/src/lcd/language/language_hu.h b/Marlin/src/lcd/language/language_hu.h index f29a7b76b9..0c73d9a85a 100644 --- a/Marlin/src/lcd/language/language_hu.h +++ b/Marlin/src/lcd/language/language_hu.h @@ -266,6 +266,7 @@ namespace Language_hu { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Mozgás 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Mozgás 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Mozgás 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Mozgás 100mm"); PROGMEM Language_Str MSG_MOVE_0001IN = _UxGT("Mozgás 0.001mm"); PROGMEM Language_Str MSG_MOVE_001IN = _UxGT("Mozgás 0.01mm"); PROGMEM Language_Str MSG_MOVE_01IN = _UxGT("Mozgás 0.1mm"); diff --git a/Marlin/src/lcd/language/language_it.h b/Marlin/src/lcd/language/language_it.h index d359354932..85b9d3f399 100644 --- a/Marlin/src/lcd/language/language_it.h +++ b/Marlin/src/lcd/language/language_it.h @@ -67,9 +67,12 @@ namespace Language_it { PROGMEM Language_Str MSG_DEBUG_MENU = _UxGT("Menu di debug"); PROGMEM Language_Str MSG_PROGRESS_BAR_TEST = _UxGT("Test barra avanzam."); PROGMEM Language_Str MSG_AUTO_HOME = _UxGT("Auto Home"); - PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("Home asse X"); - PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Home asse Y"); - PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Home asse Z"); + PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("Home X"); + PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Home Y"); + PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Home Z"); + PROGMEM Language_Str MSG_AUTO_HOME_I = _UxGT("Home ") LCD_STR_I; + PROGMEM Language_Str MSG_AUTO_HOME_J = _UxGT("Home ") LCD_STR_J; + PROGMEM Language_Str MSG_AUTO_HOME_K = _UxGT("Home ") LCD_STR_K; PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Allineam.automat. Z"); PROGMEM Language_Str MSG_ITERATION = _UxGT("Iterazione G34: %i"); PROGMEM Language_Str MSG_DECREASING_ACCURACY = _UxGT("Precisione in calo!"); @@ -80,6 +83,12 @@ namespace Language_it { PROGMEM Language_Str MSG_LEVEL_BED_DONE = _UxGT("Livel. terminato!"); PROGMEM Language_Str MSG_Z_FADE_HEIGHT = _UxGT("Fade Height"); PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Imp. offset home"); + PROGMEM Language_Str MSG_HOME_OFFSET_X = _UxGT("Offset home X"); + PROGMEM Language_Str MSG_HOME_OFFSET_Y = _UxGT("Offset home Y"); + PROGMEM Language_Str MSG_HOME_OFFSET_Z = _UxGT("Offset home Z"); + PROGMEM Language_Str MSG_HOME_OFFSET_I = _UxGT("Offset home ") LCD_STR_I; + PROGMEM Language_Str MSG_HOME_OFFSET_J = _UxGT("Offset home ") LCD_STR_J; + PROGMEM Language_Str MSG_HOME_OFFSET_K = _UxGT("Offset home ") LCD_STR_K; PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Offset applicato"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Imposta Origine"); PROGMEM Language_Str MSG_ASSISTED_TRAMMING = _UxGT("Tramming assistito"); @@ -112,10 +121,13 @@ namespace Language_it { PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Potenza laser"); PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Potenza mandrino"); PROGMEM Language_Str MSG_LASER_TOGGLE = _UxGT("Alterna Laser"); + PROGMEM Language_Str MSG_LASER_EVAC_TOGGLE = _UxGT("Alterna soffiatore"); + PROGMEM Language_Str MSG_LASER_ASSIST_TOGGLE = _UxGT("Alterna aria supp."); PROGMEM Language_Str MSG_LASER_PULSE_MS = _UxGT("ms impulso di test"); PROGMEM Language_Str MSG_LASER_FIRE_PULSE = _UxGT("Spara impulso"); PROGMEM Language_Str MSG_FLOWMETER_FAULT = _UxGT("Err.flusso refrig."); PROGMEM Language_Str MSG_SPINDLE_TOGGLE = _UxGT("Alterna mandrino"); + PROGMEM Language_Str MSG_SPINDLE_EVAC_TOGGLE = _UxGT("Alterna vuoto"); PROGMEM Language_Str MSG_SPINDLE_FORWARD = _UxGT("Mandrino in avanti"); PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Inverti mandrino"); PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Accendi aliment."); @@ -158,6 +170,7 @@ namespace Language_it { PROGMEM Language_Str MSG_UBL_LEVEL_BED = _UxGT("Livel.letto unificato"); PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Punto inclinaz."); PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Mesh Manuale"); + PROGMEM Language_Str MSG_UBL_MESH_WIZARD = _UxGT("Creaz.guid.mesh UBL"); PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Metti spes. e misura"); PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("Misura"); PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Rimuovi e mis.piatto"); @@ -258,6 +271,9 @@ namespace Language_it { PROGMEM Language_Str MSG_MOVE_X = _UxGT("Muovi X"); PROGMEM Language_Str MSG_MOVE_Y = _UxGT("Muovi Y"); PROGMEM Language_Str MSG_MOVE_Z = _UxGT("Muovi Z"); + PROGMEM Language_Str MSG_MOVE_I = _UxGT("Muovi ") LCD_STR_I; + PROGMEM Language_Str MSG_MOVE_J = _UxGT("Muovi ") LCD_STR_J; + PROGMEM Language_Str MSG_MOVE_K = _UxGT("Muovi ") LCD_STR_K; PROGMEM Language_Str MSG_MOVE_E = _UxGT("Estrusore"); PROGMEM Language_Str MSG_MOVE_EN = _UxGT("Estrusore *"); PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("Ugello freddo"); @@ -265,9 +281,11 @@ namespace Language_it { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Muovi di 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Muovi di 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Muovi di 10mm"); - PROGMEM Language_Str MSG_MOVE_0001IN = _UxGT("Muovi di 0.001in"); - PROGMEM Language_Str MSG_MOVE_001IN = _UxGT("Muovi di 0.01in"); - PROGMEM Language_Str MSG_MOVE_01IN = _UxGT("Muovi di 0.1in"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Muovi di 100mm"); + PROGMEM Language_Str MSG_MOVE_0001IN = _UxGT("Muovi di 0.001\""); + PROGMEM Language_Str MSG_MOVE_001IN = _UxGT("Muovi di 0.01\""); + PROGMEM Language_Str MSG_MOVE_01IN = _UxGT("Muovi di 0.1\""); + PROGMEM Language_Str MSG_MOVE_1IN = _UxGT("Muovi di 1\""); PROGMEM Language_Str MSG_SPEED = _UxGT("Velocità"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Piatto Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Ugello"); @@ -312,12 +330,18 @@ namespace Language_it { PROGMEM Language_Str MSG_VA_JERK = _UxGT("V") LCD_STR_A _UxGT("-jerk"); PROGMEM Language_Str MSG_VB_JERK = _UxGT("V") LCD_STR_B _UxGT("-jerk"); PROGMEM Language_Str MSG_VC_JERK = _UxGT("V") LCD_STR_C _UxGT("-jerk"); + PROGMEM Language_Str MSG_VI_JERK = _UxGT("V") LCD_STR_I _UxGT("-jerk"); + PROGMEM Language_Str MSG_VJ_JERK = _UxGT("V") LCD_STR_J _UxGT("-jerk"); + PROGMEM Language_Str MSG_VK_JERK = _UxGT("V") LCD_STR_K _UxGT("-jerk"); PROGMEM Language_Str MSG_VE_JERK = _UxGT("Ve-jerk"); PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("Deviaz. giunzioni"); PROGMEM Language_Str MSG_VELOCITY = _UxGT("Velocità"); PROGMEM Language_Str MSG_VMAX_A = _UxGT("Vmax ") LCD_STR_A; PROGMEM Language_Str MSG_VMAX_B = _UxGT("Vmax ") LCD_STR_B; PROGMEM Language_Str MSG_VMAX_C = _UxGT("Vmax ") LCD_STR_C; + PROGMEM Language_Str MSG_VMAX_I = _UxGT("Vmax ") LCD_STR_I; + PROGMEM Language_Str MSG_VMAX_J = _UxGT("Vmax ") LCD_STR_J; + PROGMEM Language_Str MSG_VMAX_K = _UxGT("Vmax ") LCD_STR_K; PROGMEM Language_Str MSG_VMAX_E = _UxGT("Vmax ") LCD_STR_E; PROGMEM Language_Str MSG_VMAX_EN = _UxGT("Vmax *"); PROGMEM Language_Str MSG_VMIN = _UxGT("Vmin"); @@ -326,6 +350,9 @@ namespace Language_it { PROGMEM Language_Str MSG_AMAX_A = _UxGT("Amax ") LCD_STR_A; PROGMEM Language_Str MSG_AMAX_B = _UxGT("Amax ") LCD_STR_B; PROGMEM Language_Str MSG_AMAX_C = _UxGT("Amax ") LCD_STR_C; + PROGMEM Language_Str MSG_AMAX_I = _UxGT("Amax ") LCD_STR_I; + PROGMEM Language_Str MSG_AMAX_J = _UxGT("Amax ") LCD_STR_J; + PROGMEM Language_Str MSG_AMAX_K = _UxGT("Amax ") LCD_STR_K; PROGMEM Language_Str MSG_AMAX_E = _UxGT("Amax ") LCD_STR_E; PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Amax *"); PROGMEM Language_Str MSG_A_RETRACT = _UxGT("A-Ritrazione"); @@ -333,11 +360,14 @@ namespace Language_it { PROGMEM Language_Str MSG_XY_FREQUENCY_LIMIT = _UxGT("Frequenza max"); PROGMEM Language_Str MSG_XY_FREQUENCY_FEEDRATE = _UxGT("Feed min"); PROGMEM Language_Str MSG_STEPS_PER_MM = _UxGT("Passi/mm"); - PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT("passi/mm"); - PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT("passi/mm"); - PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT("passi/mm"); - PROGMEM Language_Str MSG_E_STEPS = _UxGT("Epassi/mm"); - PROGMEM Language_Str MSG_EN_STEPS = _UxGT("*passi/mm"); + PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT(" passi/mm"); + PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT(" passi/mm"); + PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT(" passi/mm"); + PROGMEM Language_Str MSG_I_STEPS = LCD_STR_I _UxGT(" passi/mm"); + PROGMEM Language_Str MSG_J_STEPS = LCD_STR_J _UxGT(" passi/mm"); + PROGMEM Language_Str MSG_K_STEPS = LCD_STR_K _UxGT(" passi/mm"); + PROGMEM Language_Str MSG_E_STEPS = _UxGT("E passi/mm"); + PROGMEM Language_Str MSG_EN_STEPS = _UxGT("* passi/mm"); PROGMEM Language_Str MSG_TEMPERATURE = _UxGT("Temperatura"); PROGMEM Language_Str MSG_MOTION = _UxGT("Movimento"); PROGMEM Language_Str MSG_FILAMENT = _UxGT("Filamento"); @@ -469,6 +499,9 @@ namespace Language_it { PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Babystep X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Babystep Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Babystep Z"); + PROGMEM Language_Str MSG_BABYSTEP_I = _UxGT("Babystep ") LCD_STR_I; + PROGMEM Language_Str MSG_BABYSTEP_J = _UxGT("Babystep ") LCD_STR_J; + PROGMEM Language_Str MSG_BABYSTEP_K = _UxGT("Babystep ") LCD_STR_K; PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Totali"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Finecorsa annullati"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Risc.Fallito"); // Max 12 caratteri @@ -545,10 +578,13 @@ namespace Language_it { PROGMEM Language_Str MSG_INFO_MAX_TEMP = _UxGT("Temp max"); PROGMEM Language_Str MSG_INFO_PSU = _UxGT("Alimentatore"); PROGMEM Language_Str MSG_DRIVE_STRENGTH = _UxGT("Potenza Drive"); - PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X Driver %"); - PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Driver %"); - PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z Driver %"); - PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E Driver %"); + PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("Driver X %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Driver Y %"); + PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Driver Z %"); + PROGMEM Language_Str MSG_DAC_PERCENT_I = _UxGT("Driver ") AXIS4_STR _UxGT(" %"); + PROGMEM Language_Str MSG_DAC_PERCENT_J = _UxGT("Driver ") AXIS5_STR _UxGT(" %"); + PROGMEM Language_Str MSG_DAC_PERCENT_K = _UxGT("Driver ") AXIS6_STR _UxGT(" %"); + PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("Driver E %"); PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("ERR.CONNESSIONE TMC"); PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("Scrivi DAC EEPROM"); PROGMEM Language_Str MSG_FILAMENT_CHANGE_HEADER = _UxGT("CAMBIO FILAMENTO"); @@ -681,10 +717,15 @@ namespace Language_it { PROGMEM Language_Str MSG_SOUND = _UxGT("Suoni"); - PROGMEM Language_Str MSG_TOP_LEFT = _UxGT("Alto sinistra"); + PROGMEM Language_Str MSG_TOP_LEFT = _UxGT("Alto sinistra"); PROGMEM Language_Str MSG_BOTTOM_LEFT = _UxGT("Basso sinistra"); PROGMEM Language_Str MSG_TOP_RIGHT = _UxGT("Alto destra"); PROGMEM Language_Str MSG_BOTTOM_RIGHT = _UxGT("Basso destra"); PROGMEM Language_Str MSG_CALIBRATION_COMPLETED = _UxGT("Calibrazione completata"); PROGMEM Language_Str MSG_CALIBRATION_FAILED = _UxGT("Calibrazione fallita"); + + PROGMEM Language_Str MSG_DRIVER_BACKWARD = _UxGT(" driver invertito"); + + PROGMEM Language_Str MSG_SD_CARD = _UxGT("Scheda SD"); + PROGMEM Language_Str MSG_USB_DISK = _UxGT("Disco USB"); } diff --git a/Marlin/src/lcd/language/language_jp_kana.h b/Marlin/src/lcd/language/language_jp_kana.h index e0028e22a2..61740e3b40 100644 --- a/Marlin/src/lcd/language/language_jp_kana.h +++ b/Marlin/src/lcd/language/language_jp_kana.h @@ -98,6 +98,7 @@ namespace Language_jp_kana { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("0.1mm イドウ"); // "Move 0.1mm" PROGMEM Language_Str MSG_MOVE_1MM = _UxGT(" 1mm イドウ"); // "Move 1mm" PROGMEM Language_Str MSG_MOVE_10MM = _UxGT(" 10mm イドウ"); // "Move 10mm" + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT(" 100mm イドウ"); // "Move 100mm" PROGMEM Language_Str MSG_SPEED = _UxGT("ソクド"); // "Speed" PROGMEM Language_Str MSG_BED_Z = _UxGT("Zオフセット"); // "Bed Z" PROGMEM Language_Str MSG_NOZZLE = _UxGT("ノズル"); // "Nozzle" diff --git a/Marlin/src/lcd/language/language_nl.h b/Marlin/src/lcd/language/language_nl.h index 82e5c292c6..1eef4ca424 100644 --- a/Marlin/src/lcd/language/language_nl.h +++ b/Marlin/src/lcd/language/language_nl.h @@ -91,6 +91,7 @@ namespace Language_nl { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Verplaats 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Verplaats 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Verplaats 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Verplaats 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Snelheid"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Bed Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Nozzle"); diff --git a/Marlin/src/lcd/language/language_pl.h b/Marlin/src/lcd/language/language_pl.h index 7b4733b7ba..fee627b2fe 100644 --- a/Marlin/src/lcd/language/language_pl.h +++ b/Marlin/src/lcd/language/language_pl.h @@ -270,6 +270,7 @@ namespace Language_pl { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Przesuń co .1 mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Przesuń co 1 mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Przesuń co 10 mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Przesuń co 100 mm"); PROGMEM Language_Str MSG_MOVE_0001IN = _UxGT("Przesuń co 0.001 cala"); PROGMEM Language_Str MSG_MOVE_001IN = _UxGT("Przesuń co 0.01 cala"); PROGMEM Language_Str MSG_MOVE_01IN = _UxGT("Przesuń co 0.1 cala"); diff --git a/Marlin/src/lcd/language/language_pt.h b/Marlin/src/lcd/language/language_pt.h index 60b0c55056..4bec74558e 100644 --- a/Marlin/src/lcd/language/language_pt.h +++ b/Marlin/src/lcd/language/language_pt.h @@ -85,6 +85,7 @@ namespace Language_pt { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Mover 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Mover 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Mover 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Mover 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Velocidade"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Base Z"); PROGMEM Language_Str MSG_NOZZLE = " " LCD_STR_THERMOMETER _UxGT(" Bico"); diff --git a/Marlin/src/lcd/language/language_pt_br.h b/Marlin/src/lcd/language/language_pt_br.h index 642a7d9203..88135f5e28 100644 --- a/Marlin/src/lcd/language/language_pt_br.h +++ b/Marlin/src/lcd/language/language_pt_br.h @@ -218,6 +218,7 @@ namespace Language_pt_br { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Mover 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Mover 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Mover 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Mover 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Velocidade"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Base Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Bocal"); diff --git a/Marlin/src/lcd/language/language_ro.h b/Marlin/src/lcd/language/language_ro.h index a34717acb5..9313adf3f6 100644 --- a/Marlin/src/lcd/language/language_ro.h +++ b/Marlin/src/lcd/language/language_ro.h @@ -232,6 +232,7 @@ namespace Language_ro { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Move 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Move 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Move 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Move 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Speed"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Bed Z"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Nozzle"); diff --git a/Marlin/src/lcd/language/language_ru.h b/Marlin/src/lcd/language/language_ru.h index a10f47ef8e..bf2bb02ba3 100644 --- a/Marlin/src/lcd/language/language_ru.h +++ b/Marlin/src/lcd/language/language_ru.h @@ -69,6 +69,9 @@ namespace Language_ru { PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("Парковка X"); PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Парковка Y"); PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Парковка Z"); + PROGMEM Language_Str MSG_AUTO_HOME_I = _UxGT("Парковка ") LCD_STR_I; + PROGMEM Language_Str MSG_AUTO_HOME_J = _UxGT("Парковка ") LCD_STR_J; + PROGMEM Language_Str MSG_AUTO_HOME_K = _UxGT("Парковка ") LCD_STR_K; PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Авто Z-выравнивание"); PROGMEM Language_Str MSG_ITERATION = _UxGT("G34 Итерация: %i"); PROGMEM Language_Str MSG_DECREASING_ACCURACY = _UxGT("Уменьшение точности!"); @@ -80,11 +83,29 @@ namespace Language_ru { PROGMEM Language_Str MSG_Z_FADE_HEIGHT = _UxGT("Высота спада"); #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Установ. смещения дома"); + PROGMEM Language_Str MSG_HOME_OFFSET_X = _UxGT("Смещение дома X"); + PROGMEM Language_Str MSG_HOME_OFFSET_Y = _UxGT("Смещение дома Y"); + PROGMEM Language_Str MSG_HOME_OFFSET_Z = _UxGT("Смещение дома Z"); + PROGMEM Language_Str MSG_HOME_OFFSET_I = _UxGT("Смещение дома ") LCD_STR_I; + PROGMEM Language_Str MSG_HOME_OFFSET_J = _UxGT("Смещение дома ") LCD_STR_J; + PROGMEM Language_Str MSG_HOME_OFFSET_K = _UxGT("Смещение дома ") LCD_STR_K; #else PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Установ.смещ.дома"); + PROGMEM Language_Str MSG_HOME_OFFSET_X = _UxGT("Смещ. дома X"); + PROGMEM Language_Str MSG_HOME_OFFSET_Y = _UxGT("Смещ. дома Y"); + PROGMEM Language_Str MSG_HOME_OFFSET_Z = _UxGT("Смещ. дома Z"); + PROGMEM Language_Str MSG_HOME_OFFSET_I = _UxGT("Смещ. дома ") LCD_STR_I; + PROGMEM Language_Str MSG_HOME_OFFSET_J = _UxGT("Смещ. дома ") LCD_STR_J; + PROGMEM Language_Str MSG_HOME_OFFSET_K = _UxGT("Смещ. дома ") LCD_STR_K; #endif PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Смещения применены"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Установить ноль"); + PROGMEM Language_Str MSG_SELECT_ORIGIN = _UxGT("Выберите ноль"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_LAST_VALUE_SP = _UxGT("Последнее знач. "); + #else + PROGMEM Language_Str MSG_LAST_VALUE_SP = _UxGT("Послед. знач. "); + #endif #if PREHEAT_COUNT PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Преднагрев ") PREHEAT_1_LABEL; PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Нагрев ") PREHEAT_1_LABEL " ~"; @@ -106,15 +127,28 @@ namespace Language_ru { PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Охлаждение"); PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Частота"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Управление лазером"); - PROGMEM Language_Str MSG_LASER_TOGGLE = _UxGT("Переключить лазер"); - PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Мощность лазера"); - PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Управление шпинделем"); - PROGMEM Language_Str MSG_SPINDLE_TOGGLE = _UxGT("Переключить шпиндель"); #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Управление шпинделем"); + PROGMEM Language_Str MSG_LASER_TOGGLE = _UxGT("Переключить лазер"); + PROGMEM Language_Str MSG_SPINDLE_TOGGLE = _UxGT("Переключ.шпиндель"); PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Мощность шпинделя"); + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Мощность лазера"); + PROGMEM Language_Str MSG_LASER_PULSE_MS = _UxGT("Тестовый импульс мс"); + PROGMEM Language_Str MSG_LASER_EVAC_TOGGLE = _UxGT("Переключить обдув"); + PROGMEM Language_Str MSG_SPINDLE_EVAC_TOGGLE = _UxGT("Переключить вакуум"); #else + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Управление шпинд."); + PROGMEM Language_Str MSG_LASER_TOGGLE = _UxGT("Переключ.лазер"); + PROGMEM Language_Str MSG_SPINDLE_TOGGLE = _UxGT("Переключ.шпинд"); PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Мощн.шпинделя"); + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Мощн. лазера"); + PROGMEM Language_Str MSG_LASER_PULSE_MS = _UxGT("Тест. имп. мс"); + PROGMEM Language_Str MSG_LASER_EVAC_TOGGLE = _UxGT("Переключ. обдув"); + PROGMEM Language_Str MSG_SPINDLE_EVAC_TOGGLE = _UxGT("Переключ. вакуум"); #endif + PROGMEM Language_Str MSG_LASER_ASSIST_TOGGLE = _UxGT("Управление обдувом"); + PROGMEM Language_Str MSG_FLOWMETER_FAULT = _UxGT("Ошибка обдува"); + PROGMEM Language_Str MSG_LASER_FIRE_PULSE = _UxGT("Импульс лазера"); PROGMEM Language_Str MSG_SPINDLE_FORWARD = _UxGT("Шпиндель вперёд"); PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Инверсия шпинделя"); @@ -127,6 +161,15 @@ namespace Language_ru { PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Выровнять стол"); PROGMEM Language_Str MSG_LEVEL_CORNERS = _UxGT("Выровнять углы"); PROGMEM Language_Str MSG_NEXT_CORNER = _UxGT("Следующий угол"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_LEVEL_CORNERS_RAISE = _UxGT("Вверх до срабатыв. зонда"); + PROGMEM Language_Str MSG_LEVEL_CORNERS_IN_RANGE = _UxGT("Углы в норме. Вырав.стола"); + #else + PROGMEM Language_Str MSG_LEVEL_CORNERS_RAISE = _UxGT("Вверх до сраб. зонда"); + PROGMEM Language_Str MSG_LEVEL_CORNERS_IN_RANGE = _UxGT("Углы в норме. Вырав."); + #endif + PROGMEM Language_Str MSG_LEVEL_CORNERS_GOOD_POINTS = _UxGT("Хорошие точки: "); + PROGMEM Language_Str MSG_LEVEL_CORNERS_LAST_Z = _UxGT("Последняя Z: "); #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("Смещение по Z"); PROGMEM Language_Str MSG_EDITING_STOPPED = _UxGT("Правка сетки окончена"); @@ -164,12 +207,13 @@ namespace Language_ru { PROGMEM Language_Str MSG_LCD_TILTING_MESH = _UxGT("Точка разворота"); PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Ручной ввод сетки"); #if LCD_WIDTH > 21 - PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Разместить шайбу и измерить"); + PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Разместить шайбу,измерить"); PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Убрать и замерить стол"); #else - PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Разм.шайбу,измерить"); + PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Разм.шайбу, измерить"); PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Убрать, измер. стол"); #endif + PROGMEM Language_Str MSG_UBL_MESH_WIZARD = _UxGT("Мастер сеток UBL"); PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("Измерение"); PROGMEM Language_Str MSG_UBL_MOVING_TO_NEXT = _UxGT("Двигаемся дальше"); PROGMEM Language_Str MSG_UBL_ACTIVATE_MESH = _UxGT("Активировать UBL"); @@ -185,17 +229,15 @@ namespace Language_ru { PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Правка сетки завершена"); #else PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = LCD_STR_THERMOMETER _UxGT(" стола, ") LCD_STR_DEGREE "C"; - PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = LCD_STR_THERMOMETER _UxGT(" стола, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Своя ") LCD_STR_THERMOMETER _UxGT(" стола,") LCD_STR_DEGREE "C"; PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = LCD_STR_THERMOMETER _UxGT(" сопла, ") LCD_STR_DEGREE "C"; - PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = LCD_STR_THERMOMETER _UxGT(" сопла, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Своя ") LCD_STR_THERMOMETER _UxGT(" сопла,") LCD_STR_DEGREE "C"; PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Построить свою"); PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Правка завершена"); #endif PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Точная правка сетки"); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Построить сетку"); - #if PREHEAT_COUNT - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Построить сетку $"); - #endif + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Построить сетку $"); #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Построить холодную сетку"); #else @@ -205,14 +247,10 @@ namespace Language_ru { PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Высота"); PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_MENU = _UxGT("Проверить сетку"); #if LCD_WIDTH > 21 - #if PREHEAT_COUNT - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Проверить сетку $"); - #endif + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Проверить сетку $"); PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Проверить свою сетку"); #else - #if PREHEAT_COUNT - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Провер. сетку $"); - #endif + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Провер. сетку $"); PROGMEM Language_Str MSG_UBL_VALIDATE_CUSTOM_MESH = _UxGT("Провер. свою сетку"); #endif PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 нагрев стола"); @@ -239,11 +277,12 @@ namespace Language_ru { #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Сохранить сетку снаружи"); PROGMEM Language_Str MSG_UBL_INFO_UBL = _UxGT("Вывод информации UBL"); + PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Кол-во заполнителя"); #else PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Сохранить снаружи"); PROGMEM Language_Str MSG_UBL_INFO_UBL = _UxGT("Информация UBL"); + PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Кол-во заполн."); #endif - PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Кол-во заполнителя"); PROGMEM Language_Str MSG_UBL_MANUAL_FILLIN = _UxGT("Ручное заполнение"); PROGMEM Language_Str MSG_UBL_SMART_FILLIN = _UxGT("Умное заполнение"); PROGMEM Language_Str MSG_UBL_FILLIN_MESH = _UxGT("Заполнить сетку"); @@ -303,6 +342,9 @@ namespace Language_ru { PROGMEM Language_Str MSG_MOVE_X = _UxGT("Движение по X"); PROGMEM Language_Str MSG_MOVE_Y = _UxGT("Движение по Y"); PROGMEM Language_Str MSG_MOVE_Z = _UxGT("Движение по Z"); + PROGMEM Language_Str MSG_MOVE_I = _UxGT("Движение по ") LCD_STR_I; + PROGMEM Language_Str MSG_MOVE_J = _UxGT("Движение по ") LCD_STR_J; + PROGMEM Language_Str MSG_MOVE_K = _UxGT("Движение по ") LCD_STR_K; PROGMEM Language_Str MSG_MOVE_E = _UxGT("Экструдер"); PROGMEM Language_Str MSG_MOVE_EN = _UxGT("Экструдер *"); PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("Сопло не нагрето"); @@ -310,6 +352,7 @@ namespace Language_ru { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Движение 0.1мм"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Движение 1мм"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Движение 10мм"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Движение 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Скорость"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Z стола"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Сопло, ") LCD_STR_DEGREE "C"; @@ -318,6 +361,16 @@ namespace Language_ru { PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Сопло ожидает"); PROGMEM Language_Str MSG_BED = _UxGT("Стол, ") LCD_STR_DEGREE "C"; PROGMEM Language_Str MSG_CHAMBER = _UxGT("Камера,") LCD_STR_DEGREE "C"; + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_COOLER = _UxGT("Охлаждение лазера"); + PROGMEM Language_Str MSG_COOLER_TOGGLE = _UxGT("Переключ. охлажд."); + PROGMEM Language_Str MSG_FLOWMETER_SAFETY = _UxGT("Безопасн. потока"); + #else + PROGMEM Language_Str MSG_COOLER = _UxGT("Охлажд. лазера"); + PROGMEM Language_Str MSG_COOLER_TOGGLE = _UxGT("Переключ. охл."); + PROGMEM Language_Str MSG_FLOWMETER_SAFETY = _UxGT("Безопас.потока"); + #endif + PROGMEM Language_Str MSG_LASER = _UxGT("Лазер"); PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Кулер"); PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Кулер ~"); PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Сохранённый кулер ~"); @@ -352,6 +405,9 @@ namespace Language_ru { PROGMEM Language_Str MSG_VA_JERK = _UxGT("V") LCD_STR_A _UxGT("-рывок"); PROGMEM Language_Str MSG_VB_JERK = _UxGT("V") LCD_STR_B _UxGT("-рывок"); PROGMEM Language_Str MSG_VC_JERK = _UxGT("V") LCD_STR_C _UxGT("-рывок"); + PROGMEM Language_Str MSG_VI_JERK = _UxGT("V") LCD_STR_I _UxGT("-рывок"); + PROGMEM Language_Str MSG_VJ_JERK = _UxGT("V") LCD_STR_J _UxGT("-рывок"); + PROGMEM Language_Str MSG_VK_JERK = _UxGT("V") LCD_STR_K _UxGT("-рывок"); PROGMEM Language_Str MSG_VE_JERK = _UxGT("Ve-рывок"); #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("Отклонение узла"); @@ -362,6 +418,9 @@ namespace Language_ru { PROGMEM Language_Str MSG_VMAX_A = _UxGT("Скор.макс ") LCD_STR_A; PROGMEM Language_Str MSG_VMAX_B = _UxGT("Скор.макс ") LCD_STR_B; PROGMEM Language_Str MSG_VMAX_C = _UxGT("Скор.макс ") LCD_STR_C; + PROGMEM Language_Str MSG_VMAX_I = _UxGT("Скор.макс ") LCD_STR_I; + PROGMEM Language_Str MSG_VMAX_J = _UxGT("Скор.макс ") LCD_STR_J; + PROGMEM Language_Str MSG_VMAX_K = _UxGT("Скор.макс ") LCD_STR_K; PROGMEM Language_Str MSG_VMAX_E = _UxGT("Скор.макс ") LCD_STR_E; PROGMEM Language_Str MSG_VMAX_EN = _UxGT("Скор.макс *"); PROGMEM Language_Str MSG_VMIN = _UxGT("Скор.мин"); @@ -370,6 +429,9 @@ namespace Language_ru { PROGMEM Language_Str MSG_AMAX_A = _UxGT("Ускор.макс ") LCD_STR_A; PROGMEM Language_Str MSG_AMAX_B = _UxGT("Ускор.макс ") LCD_STR_B; PROGMEM Language_Str MSG_AMAX_C = _UxGT("Ускор.макс ") LCD_STR_C; + PROGMEM Language_Str MSG_AMAX_I = _UxGT("Ускор.макс ") LCD_STR_I; + PROGMEM Language_Str MSG_AMAX_J = _UxGT("Ускор.макс ") LCD_STR_J; + PROGMEM Language_Str MSG_AMAX_K = _UxGT("Ускор.макс ") LCD_STR_K; PROGMEM Language_Str MSG_AMAX_E = _UxGT("Ускор.макс ") LCD_STR_E; PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Ускор.макс *"); PROGMEM Language_Str MSG_A_RETRACT = _UxGT("Ускор.втягив."); @@ -380,6 +442,9 @@ namespace Language_ru { PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT(" шаг/мм"); PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT(" шаг/мм"); PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT(" шаг/мм"); + PROGMEM Language_Str MSG_I_STEPS = LCD_STR_I _UxGT(" шаг/мм"); + PROGMEM Language_Str MSG_J_STEPS = LCD_STR_J _UxGT(" шаг/мм"); + PROGMEM Language_Str MSG_K_STEPS = LCD_STR_K _UxGT(" шаг/мм"); PROGMEM Language_Str MSG_E_STEPS = _UxGT("E шаг/мм"); PROGMEM Language_Str MSG_EN_STEPS = _UxGT("* шаг/мм"); PROGMEM Language_Str MSG_TEMPERATURE = _UxGT("Температура"); @@ -402,10 +467,11 @@ namespace Language_ru { PROGMEM Language_Str MSG_CONTRAST = _UxGT("Контраст экрана"); PROGMEM Language_Str MSG_STORE_EEPROM = _UxGT("Сохранить настройки"); PROGMEM Language_Str MSG_LOAD_EEPROM = _UxGT("Загрузить настройки"); - PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("На базовые параметры"); #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("На базовые параметры"); PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Инициализация EEPROM"); #else + PROGMEM Language_Str MSG_RESTORE_DEFAULTS = _UxGT("На базовые парам."); PROGMEM Language_Str MSG_INIT_EEPROM = _UxGT("Инициализ. EEPROM"); #endif PROGMEM Language_Str MSG_ERR_EEPROM_CRC = _UxGT("Сбой EEPROM: CRC"); @@ -414,7 +480,7 @@ namespace Language_ru { PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Параметры сохранены"); PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("Обновление прошивки"); PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Сброс принтера"); - PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT(" Обновить"); + PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT(" Обновить"); PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Главный экран"); PROGMEM Language_Str MSG_PREPARE = _UxGT("Подготовить"); PROGMEM Language_Str MSG_TUNE = _UxGT("Настроить"); @@ -541,10 +607,17 @@ namespace Language_ru { PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Смещение X"); PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Смещение Y"); PROGMEM Language_Str MSG_ZPROBE_ZOFFSET = _UxGT("Смещение Z"); - PROGMEM Language_Str MSG_MOVE_NOZZLE_TO_BED = _UxGT("Двигать сопло к столу"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_MOVE_NOZZLE_TO_BED = _UxGT("Двигать сопло к столу"); + #else + PROGMEM Language_Str MSG_MOVE_NOZZLE_TO_BED = _UxGT("Двиг. сопло к столу"); + #endif PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Микрошаг X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Микрошаг Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Микрошаг Z"); + PROGMEM Language_Str MSG_BABYSTEP_I = _UxGT("Микрошаг ") LCD_STR_I; + PROGMEM Language_Str MSG_BABYSTEP_J = _UxGT("Микрошаг ") LCD_STR_J; + PROGMEM Language_Str MSG_BABYSTEP_K = _UxGT("Микрошаг ") LCD_STR_K; PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Сумарно"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Сработал концевик"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Разогрев не удался"); @@ -552,6 +625,8 @@ namespace Language_ru { PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("УТЕЧКА ТЕПЛА"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("УТЕЧКА ТЕПЛА СТОЛА"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("УТЕЧКА ТЕПЛА КАМЕРЫ"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_COOLER = _UxGT("УТЕЧКА ОХЛАЖДЕНИЯ"); + PROGMEM Language_Str MSG_COOLING_FAILED = _UxGT("ОХЛАДИТЬ НЕ УДАЛОСЬ"); PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("Ошибка: Т макс."); PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("Ошибка: Т мин."); PROGMEM Language_Str MSG_HALTED = _UxGT("ПРИНТЕР ОСТАНОВЛЕН"); @@ -567,6 +642,7 @@ namespace Language_ru { PROGMEM Language_Str MSG_PROBE_COOLING = _UxGT("Охлаждение зонда..."); PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Нагрев камеры..."); PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Охладжение камеры..."); + PROGMEM Language_Str MSG_LASER_COOLING = _UxGT("Охлаждение лазера..."); PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Калибровка Delta"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("Калибровать X"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("Калибровать Y"); @@ -575,13 +651,12 @@ namespace Language_ru { PROGMEM Language_Str MSG_DELTA_SETTINGS = _UxGT("Настройки Delta"); PROGMEM Language_Str MSG_DELTA_AUTO_CALIBRATE = _UxGT("Авто калибровка"); PROGMEM Language_Str MSG_DELTA_HEIGHT_CALIBRATE = _UxGT("Высота Delta"); - #if LCD_WIDTH >= 20 - PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Зондировать Z-смещение"); - PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Стержень диагонали"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Зондировать Z-смещения"); #else PROGMEM Language_Str MSG_DELTA_Z_OFFSET_CALIBRATE = _UxGT("Зондир. Z-смещения"); - PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Стержень диаг."); #endif + PROGMEM Language_Str MSG_DELTA_DIAG_ROD = _UxGT("Стержень диаг."); PROGMEM Language_Str MSG_DELTA_HEIGHT = _UxGT("Высота"); PROGMEM Language_Str MSG_DELTA_RADIUS = _UxGT("Радиус"); PROGMEM Language_Str MSG_INFO_MENU = _UxGT("О принтере"); @@ -597,6 +672,11 @@ namespace Language_ru { #endif PROGMEM Language_Str MSG_UBL_LEVELING = _UxGT("Управление UBL"); PROGMEM Language_Str MSG_MESH_LEVELING = _UxGT("Выравнивание сетки"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_MESH_DONE = _UxGT("Зондирование выполнено"); + #else + PROGMEM Language_Str MSG_MESH_DONE = _UxGT("Зондиров. выполнено"); + #endif PROGMEM Language_Str MSG_INFO_STATS_MENU = _UxGT("Статистика принтера"); PROGMEM Language_Str MSG_INFO_BOARD_MENU = _UxGT("Данные платы"); @@ -617,14 +697,14 @@ namespace Language_ru { PROGMEM Language_Str MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Яркость подсветки"); PROGMEM Language_Str MSG_KILL_EXPECTED_PRINTER = _UxGT("Неверный принтер"); - #if LCD_WIDTH >= 20 + #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Счётчик печати"); PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Общее время печати"); PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Наидольшее задание"); PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Длина филамента"); #else - PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Отпечатков"); - PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Всего"); + PROGMEM Language_Str MSG_INFO_PRINT_COUNT = _UxGT("Напечатано"); + PROGMEM Language_Str MSG_INFO_PRINT_TIME = _UxGT("Общее время"); PROGMEM Language_Str MSG_INFO_PRINT_LONGEST = _UxGT("Наидольшее"); PROGMEM Language_Str MSG_INFO_PRINT_FILAMENT = _UxGT("Выдавлено"); #endif @@ -637,6 +717,9 @@ namespace Language_ru { PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("X Привод, %"); PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Y Привод, %"); PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Z Привод, %"); + PROGMEM Language_Str MSG_DAC_PERCENT_I = LCD_STR_I _UxGT(" Привод, %"); + PROGMEM Language_Str MSG_DAC_PERCENT_J = LCD_STR_J _UxGT(" Привод, %"); + PROGMEM Language_Str MSG_DAC_PERCENT_K = LCD_STR_K _UxGT(" Привод, %"); PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("E Привод, %"); PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("СБОЙ СВЯЗИ С TMC"); PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("Запись DAC в EEPROM"); @@ -749,11 +832,11 @@ namespace Language_ru { #endif PROGMEM Language_Str MSG_PASSWORD_REMOVED = _UxGT("Пароль удалён"); - PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Парковка...")); // // Filament Change screens show up to 3 lines on a 4-line display // ...or up to 2 lines on a 3-line display // + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Парковка...")); #if LCD_HEIGHT >= 4 PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_3_LINE("Нажмите кнопку", "для продолжения", "печати")); PROGMEM Language_Str MSG_FILAMENT_CHANGE_INIT = _UxGT(MSG_2_LINE("Ожидайте начала", "смены филамента")); @@ -803,8 +886,8 @@ namespace Language_ru { PROGMEM Language_Str MSG_PROBE_WIZARD = _UxGT("Мастер Z-зонда"); #if LCD_WIDTH > 21 - PROGMEM Language_Str MSG_PROBE_WIZARD_PROBING = _UxGT("Зондиров. контрольной точки Z"); - PROGMEM Language_Str MSG_PROBE_WIZARD_MOVING = _UxGT("Движение к точке зондирования"); + PROGMEM Language_Str MSG_PROBE_WIZARD_PROBING = _UxGT("Зондиров. контр. точки Z"); + PROGMEM Language_Str MSG_PROBE_WIZARD_MOVING = _UxGT("Движение к точке зондиров."); #else PROGMEM Language_Str MSG_PROBE_WIZARD_PROBING = _UxGT("Зондир.контр.точки Z"); PROGMEM Language_Str MSG_PROBE_WIZARD_MOVING = _UxGT("Движ. к точке зондир."); @@ -818,6 +901,11 @@ namespace Language_ru { PROGMEM Language_Str MSG_BOTTOM_RIGHT = _UxGT("Нижний правый"); PROGMEM Language_Str MSG_CALIBRATION_COMPLETED = _UxGT("Калибровка успешна"); PROGMEM Language_Str MSG_CALIBRATION_FAILED = _UxGT("Ошибка калибровки"); + + PROGMEM Language_Str MSG_DRIVER_BACKWARD = _UxGT(" драйвер назад"); + + PROGMEM Language_Str MSG_SD_CARD = _UxGT("SD Карта"); + PROGMEM Language_Str MSG_USB_DISK = _UxGT("USB Диск"); } #if FAN_COUNT == 1 diff --git a/Marlin/src/lcd/language/language_sk.h b/Marlin/src/lcd/language/language_sk.h index 4b3ce5aa96..96f1bc7ee5 100644 --- a/Marlin/src/lcd/language/language_sk.h +++ b/Marlin/src/lcd/language/language_sk.h @@ -272,6 +272,7 @@ namespace Language_sk { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Posunúť o 0,1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Posunúť o 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Posunúť o 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Posunúť o 100mm"); PROGMEM Language_Str MSG_MOVE_0001IN = _UxGT("Posunúť o 0,001in"); PROGMEM Language_Str MSG_MOVE_001IN = _UxGT("Posunúť o 0,01in"); PROGMEM Language_Str MSG_MOVE_01IN = _UxGT("Posunúť o 0,1in"); diff --git a/Marlin/src/lcd/language/language_sv.h b/Marlin/src/lcd/language/language_sv.h index 722443fb21..f7b0f06769 100644 --- a/Marlin/src/lcd/language/language_sv.h +++ b/Marlin/src/lcd/language/language_sv.h @@ -260,6 +260,7 @@ namespace Language_sv { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Flytta 0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Flytta 1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Flytta 10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Flytta 100mm"); PROGMEM Language_Str MSG_MOVE_0001IN = _UxGT("Flytta 0.001tum"); PROGMEM Language_Str MSG_MOVE_001IN = _UxGT("Flytta 0.01tum"); PROGMEM Language_Str MSG_MOVE_01IN = _UxGT("Flytta 0.1tum"); diff --git a/Marlin/src/lcd/language/language_tr.h b/Marlin/src/lcd/language/language_tr.h index 9d711ff376..6858616b4d 100644 --- a/Marlin/src/lcd/language/language_tr.h +++ b/Marlin/src/lcd/language/language_tr.h @@ -235,6 +235,7 @@ namespace Language_tr { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("0.1mm"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("1mm"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("10mm"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Hız"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Z Mesafesi"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Nozul"); diff --git a/Marlin/src/lcd/language/language_uk.h b/Marlin/src/lcd/language/language_uk.h index be0e420a42..cee795745c 100644 --- a/Marlin/src/lcd/language/language_uk.h +++ b/Marlin/src/lcd/language/language_uk.h @@ -34,7 +34,7 @@ namespace Language_uk { using namespace Language_en; // Inherit undefined strings from English constexpr uint8_t CHARSIZE = 2; - PROGMEM Language_Str LANGUAGE = _UxGT("Ukranian"); + PROGMEM Language_Str LANGUAGE = _UxGT("Ukrainian"); PROGMEM Language_Str WELCOME_MSG = MACHINE_NAME _UxGT(" Готовий."); PROGMEM Language_Str MSG_YES = _UxGT("ТАК"); @@ -71,6 +71,9 @@ namespace Language_uk { PROGMEM Language_Str MSG_AUTO_HOME_X = _UxGT("Паркування X"); PROGMEM Language_Str MSG_AUTO_HOME_Y = _UxGT("Паркування Y"); PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Паркування Z"); + PROGMEM Language_Str MSG_AUTO_HOME_I = _UxGT("Паркування ") LCD_STR_I; + PROGMEM Language_Str MSG_AUTO_HOME_J = _UxGT("Паркування ") LCD_STR_J; + PROGMEM Language_Str MSG_AUTO_HOME_K = _UxGT("Паркування ") LCD_STR_K; PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Авто Z-вирівнювання"); PROGMEM Language_Str MSG_ITERATION = _UxGT("G34 Ітерація: %i"); PROGMEM Language_Str MSG_DECREASING_ACCURACY = _UxGT("Зменьшення точності!"); @@ -82,11 +85,29 @@ namespace Language_uk { PROGMEM Language_Str MSG_Z_FADE_HEIGHT = _UxGT("Висота спаду"); #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Встанов. зміщення дому"); + PROGMEM Language_Str MSG_HOME_OFFSET_X = _UxGT("Зміщення дому X"); + PROGMEM Language_Str MSG_HOME_OFFSET_Y = _UxGT("Зміщення дому Y"); + PROGMEM Language_Str MSG_HOME_OFFSET_Z = _UxGT("Зміщення дому Z"); + PROGMEM Language_Str MSG_HOME_OFFSET_I = _UxGT("Зміщення дому ") LCD_STR_I; + PROGMEM Language_Str MSG_HOME_OFFSET_J = _UxGT("Зміщення дому ") LCD_STR_J; + PROGMEM Language_Str MSG_HOME_OFFSET_K = _UxGT("Зміщення дому ") LCD_STR_K; #else - PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Встанов. зміщ. дому"); + PROGMEM Language_Str MSG_SET_HOME_OFFSETS = _UxGT("Встан. зміщ. дому"); + PROGMEM Language_Str MSG_HOME_OFFSET_X = _UxGT("Зміщ. дому X"); + PROGMEM Language_Str MSG_HOME_OFFSET_Y = _UxGT("Зміщ. дому Y"); + PROGMEM Language_Str MSG_HOME_OFFSET_Z = _UxGT("Зміщ. дому Z"); + PROGMEM Language_Str MSG_HOME_OFFSET_I = _UxGT("Зміщ. дому ") LCD_STR_I; + PROGMEM Language_Str MSG_HOME_OFFSET_J = _UxGT("Зміщ. дому ") LCD_STR_J; + PROGMEM Language_Str MSG_HOME_OFFSET_K = _UxGT("Зміщ. дому ") LCD_STR_K; #endif PROGMEM Language_Str MSG_HOME_OFFSETS_APPLIED = _UxGT("Зміщення прийняті"); PROGMEM Language_Str MSG_SET_ORIGIN = _UxGT("Встановити нуль"); + PROGMEM Language_Str MSG_SELECT_ORIGIN = _UxGT("Оберіть нуль"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_LAST_VALUE_SP = _UxGT("Останнє значення "); + #else + PROGMEM Language_Str MSG_LAST_VALUE_SP = _UxGT("Останнє знач. "); + #endif #if PREHEAT_COUNT PROGMEM Language_Str MSG_PREHEAT_1 = _UxGT("Нагрів ") PREHEAT_1_LABEL; PROGMEM Language_Str MSG_PREHEAT_1_H = _UxGT("Нагрів ") PREHEAT_1_LABEL " ~"; @@ -106,22 +127,30 @@ namespace Language_uk { #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Нагрів свого"); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Вимкнути нагрів"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Частота"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Керування лазером"); + PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Керування шпінделем"); #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Потужність лазера"); - PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Керування шпінделем"); + PROGMEM Language_Str MSG_SPINDLE_TOGGLE = _UxGT("Перемкн. шпіндель"); + PROGMEM Language_Str MSG_SPINDLE_EVAC_TOGGLE = _UxGT("Перемкнути вакуум"); + PROGMEM Language_Str MSG_LASER_TOGGLE = _UxGT("Перемкнути лазер"); + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Потужн. шпінделя"); + PROGMEM Language_Str MSG_LASER_PULSE_MS = _UxGT("Тестовий імпульс мс"); + PROGMEM Language_Str MSG_LASER_EVAC_TOGGLE = _UxGT("Перемкнути обдув"); #else - PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Потуж.лазера"); - PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Керув. шпінделем"); - #endif - PROGMEM Language_Str MSG_SPINDLE_TOGGLE = _UxGT("Перемкнути шпіндель"); - PROGMEM Language_Str MSG_LASER_TOGGLE = _UxGT("Перемкнути лазер"); - #if LCD_WIDTH > 21 - PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Потуж. шпінделя"); - #else - PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Потуж. шпінд."); + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Потужн. лазера"); + PROGMEM Language_Str MSG_SPINDLE_TOGGLE = _UxGT("Перемк. шпінд."); + PROGMEM Language_Str MSG_SPINDLE_EVAC_TOGGLE = _UxGT("Перемк. вакуум"); + PROGMEM Language_Str MSG_LASER_TOGGLE = _UxGT("Перемкн. лазер"); + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Потужн. шпінд."); + PROGMEM Language_Str MSG_LASER_PULSE_MS = _UxGT("Тест. імп., мс"); + PROGMEM Language_Str MSG_LASER_EVAC_TOGGLE = _UxGT("Перемкн. обдув"); #endif + PROGMEM Language_Str MSG_LASER_ASSIST_TOGGLE = _UxGT("Керування обдувом"); + PROGMEM Language_Str MSG_FLOWMETER_FAULT = _UxGT("Помилка обдуву"); + PROGMEM Language_Str MSG_LASER_FIRE_PULSE = _UxGT("Імпульс лазеру"); PROGMEM Language_Str MSG_SPINDLE_FORWARD = _UxGT("Шпіндель вперед"); PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Шпіндель назад"); @@ -134,11 +163,14 @@ namespace Language_uk { PROGMEM Language_Str MSG_LEVEL_BED = _UxGT("Вирівняти стіл"); PROGMEM Language_Str MSG_LEVEL_CORNERS = _UxGT("Вирівняти кути"); #if LCD_WIDTH > 21 - PROGMEM Language_Str MSG_LEVEL_CORNERS_RAISE = _UxGT("Вгору до спрацювання зонду"); // not sure about this one - #else PROGMEM Language_Str MSG_LEVEL_CORNERS_RAISE = _UxGT("Вгору до спрацюв. зонду"); + PROGMEM Language_Str MSG_LEVEL_CORNERS_IN_RANGE = _UxGT("Кути в межах. Вирів.столу"); + #else + PROGMEM Language_Str MSG_LEVEL_CORNERS_RAISE = _UxGT("Вгору до спрац.зонду"); + PROGMEM Language_Str MSG_LEVEL_CORNERS_IN_RANGE = _UxGT("Кути в межах. Вирівн"); #endif - PROGMEM Language_Str MSG_LEVEL_CORNERS_IN_RANGE = _UxGT("Кути в межах. Вирівнювання столу"); // Too long? + PROGMEM Language_Str MSG_LEVEL_CORNERS_GOOD_POINTS = _UxGT("Хороші точки: "); + PROGMEM Language_Str MSG_LEVEL_CORNERS_LAST_Z = _UxGT("Остання Z: "); PROGMEM Language_Str MSG_NEXT_CORNER = _UxGT("Наступний кут"); #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_MESH_EDITOR = _UxGT("Зміщення по Z"); @@ -181,24 +213,25 @@ namespace Language_uk { PROGMEM Language_Str MSG_UBL_MANUAL_MESH = _UxGT("Ручне введ. сітки"); PROGMEM Language_Str MSG_UBL_BC_INSERT = _UxGT("Розм. шайбу і вимір."); #endif + PROGMEM Language_Str MSG_UBL_MESH_WIZARD = _UxGT("Майстер сіток UBL"); PROGMEM Language_Str MSG_UBL_BC_INSERT2 = _UxGT("Вимірювання"); - PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Видалити і виміряти стіл"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Видалити і виміряти стіл"); + #else + PROGMEM Language_Str MSG_UBL_BC_REMOVE = _UxGT("Видали і вимір. стіл"); + #endif PROGMEM Language_Str MSG_UBL_MOVING_TO_NEXT = _UxGT("Рух до наступної"); PROGMEM Language_Str MSG_UBL_ACTIVATE_MESH = _UxGT("Активувати UBL"); PROGMEM Language_Str MSG_UBL_DEACTIVATE_MESH = _UxGT("Деактивувати UBL"); + PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = LCD_STR_THERMOMETER _UxGT(" столу, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Своя ") LCD_STR_THERMOMETER _UxGT(" столу,") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = LCD_STR_THERMOMETER _UxGT(" сопла, ") LCD_STR_DEGREE "C"; + PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Своя ") LCD_STR_THERMOMETER _UxGT(" сопла,") LCD_STR_DEGREE "C"; #if LCD_WIDTH > 21 - PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = _UxGT("Температура столу"); - PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = _UxGT("Температура свого столу"); - PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = _UxGT("Температура сопла"); - PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = _UxGT("Температура свого сопла"); PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("Редагувати свою сітку"); PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Точне редагування сітки"); PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Будувати свою сітку"); #else - PROGMEM Language_Str MSG_UBL_SET_TEMP_BED = LCD_STR_THERMOMETER _UxGT(" столу, ") LCD_STR_DEGREE "C"; - PROGMEM Language_Str MSG_UBL_BED_TEMP_CUSTOM = LCD_STR_THERMOMETER _UxGT(" столу, ") LCD_STR_DEGREE "C"; - PROGMEM Language_Str MSG_UBL_SET_TEMP_HOTEND = LCD_STR_THERMOMETER _UxGT(" сопла, ") LCD_STR_DEGREE "C"; - PROGMEM Language_Str MSG_UBL_HOTEND_TEMP_CUSTOM = LCD_STR_THERMOMETER _UxGT(" сопла, ") LCD_STR_DEGREE "C"; PROGMEM Language_Str MSG_UBL_EDIT_CUSTOM_MESH = _UxGT("Редагувати свою"); PROGMEM Language_Str MSG_UBL_FINE_TUNE_MESH = _UxGT("Точне редаг. сітки"); PROGMEM Language_Str MSG_UBL_BUILD_CUSTOM_MESH = _UxGT("Будувати свою"); @@ -206,10 +239,8 @@ namespace Language_uk { PROGMEM Language_Str MSG_UBL_MESH_EDIT = _UxGT("Редагування сітки"); PROGMEM Language_Str MSG_UBL_DONE_EDITING_MESH = _UxGT("Сітка побудована"); PROGMEM Language_Str MSG_UBL_BUILD_MESH_MENU = _UxGT("Будувати сітку"); - #if PREHEAT_COUNT - PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Будувати сітку ($)"); - PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Підтвердити ($)"); - #endif + PROGMEM Language_Str MSG_UBL_BUILD_MESH_M = _UxGT("Будувати сітку ($)"); + PROGMEM Language_Str MSG_UBL_VALIDATE_MESH_M = _UxGT("Підтвердити ($)"); PROGMEM Language_Str MSG_UBL_BUILD_COLD_MESH = _UxGT("Буд. холодну сітку"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_ADJUST = _UxGT("Встан.висоту сітки"); PROGMEM Language_Str MSG_UBL_MESH_HEIGHT_AMOUNT = _UxGT("Висота"); @@ -219,7 +250,7 @@ namespace Language_uk { PROGMEM Language_Str MSG_G26_HEATING_BED = _UxGT("G26 нагрів столу"); PROGMEM Language_Str MSG_G26_HEATING_NOZZLE = _UxGT("G26 нагрів сопла"); PROGMEM Language_Str MSG_G26_MANUAL_PRIME = _UxGT("Ручне грунтування"); - PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("Фікс. довж. грунт."); // ґ is not supported + PROGMEM Language_Str MSG_G26_FIXED_LENGTH = _UxGT("Фікс. довж. грунт."); PROGMEM Language_Str MSG_G26_PRIME_DONE = _UxGT("Грунтув. виконане"); PROGMEM Language_Str MSG_G26_CANCELED = _UxGT("G26 скасовано"); PROGMEM Language_Str MSG_G26_LEAVING = _UxGT("Вийти з G26"); @@ -240,7 +271,7 @@ namespace Language_uk { PROGMEM Language_Str MSG_UBL_OUTPUT_MAP_BACKUP = _UxGT("Зберегти зовні"); PROGMEM Language_Str MSG_UBL_INFO_UBL = _UxGT("Інформація по UBL"); #if LCD_WIDTH > 21 - PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Обсяг заповнювача"); + PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Обсяг заповнюв."); #else PROGMEM Language_Str MSG_UBL_FILLIN_AMOUNT = _UxGT("Обсяг заповн."); #endif @@ -251,12 +282,9 @@ namespace Language_uk { PROGMEM Language_Str MSG_UBL_INVALIDATE_CLOSEST = _UxGT("Анулювати найближчу"); #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_UBL_FINE_TUNE_ALL = _UxGT("Точно налаштувати все"); - #else - PROGMEM Language_Str MSG_UBL_FINE_TUNE_ALL = _UxGT("Точно налашт. все"); - #endif - #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_UBL_FINE_TUNE_CLOSEST = _UxGT("Точно налашт.найближчу"); #else + PROGMEM Language_Str MSG_UBL_FINE_TUNE_ALL = _UxGT("Точно налашт. все"); PROGMEM Language_Str MSG_UBL_FINE_TUNE_CLOSEST = _UxGT("Точно найближчу"); #endif PROGMEM Language_Str MSG_UBL_STORAGE_MESH_MENU = _UxGT("Збереження сітки"); @@ -300,7 +328,7 @@ namespace Language_uk { #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_NEO2_PRESETS = _UxGT("Передустановка світла #2"); #else - PROGMEM Language_Str MSG_NEO2_PRESETS = _UxGT("Передустан. світла #2"); + PROGMEM Language_Str MSG_NEO2_PRESETS = _UxGT("Передуст. світла #2"); #endif PROGMEM Language_Str MSG_NEO2_BRIGHTNESS = _UxGT("Яскравість"); PROGMEM Language_Str MSG_CUSTOM_LEDS = _UxGT("Своє світло"); @@ -315,6 +343,9 @@ namespace Language_uk { PROGMEM Language_Str MSG_MOVE_X = _UxGT("Рух по X"); PROGMEM Language_Str MSG_MOVE_Y = _UxGT("Рух по Y"); PROGMEM Language_Str MSG_MOVE_Z = _UxGT("Рух по Z"); + PROGMEM Language_Str MSG_MOVE_I = _UxGT("Рух по ") LCD_STR_I; + PROGMEM Language_Str MSG_MOVE_J = _UxGT("Рух по ") LCD_STR_J; + PROGMEM Language_Str MSG_MOVE_K = _UxGT("Рух по ") LCD_STR_K; PROGMEM Language_Str MSG_MOVE_E = _UxGT("Екструдер"); PROGMEM Language_Str MSG_MOVE_EN = _UxGT("Екструдер *"); PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("Сопло дуже холодне"); @@ -322,6 +353,7 @@ namespace Language_uk { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Рух 0.1мм"); PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Рух 1мм"); PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Рух 10мм"); + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Рух 100mm"); PROGMEM Language_Str MSG_SPEED = _UxGT("Швидкість"); PROGMEM Language_Str MSG_BED_Z = _UxGT("Z Столу"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Сопло, ") LCD_STR_DEGREE "C"; @@ -330,17 +362,26 @@ namespace Language_uk { PROGMEM Language_Str MSG_NOZZLE_STANDBY = _UxGT("Сопло очікує"); PROGMEM Language_Str MSG_BED = _UxGT("Стіл, ") LCD_STR_DEGREE "C"; PROGMEM Language_Str MSG_CHAMBER = _UxGT("Камера,") LCD_STR_DEGREE "C"; + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_COOLER = _UxGT("Охолодження лазеру"); + PROGMEM Language_Str MSG_COOLER_TOGGLE = _UxGT("Перемк. охолодж."); + #else + PROGMEM Language_Str MSG_COOLER = _UxGT("Охолодж. лазеру"); + PROGMEM Language_Str MSG_COOLER_TOGGLE = _UxGT("Перемк.охолод"); + #endif + PROGMEM Language_Str MSG_FLOWMETER_SAFETY = _UxGT("Безпека потоку"); + PROGMEM Language_Str MSG_LASER = _UxGT("Лазер"); PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Швидк. вент."); PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Швидк. вент. ~"); #if LCD_WIDTH > 21 - PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Збереж. швидк. вент. ~"); + PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Збереж.швидк.вент. ~"); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Дод. швидк. вент. ~"); #else PROGMEM Language_Str MSG_STORED_FAN_N = _UxGT("Збереж. вент. ~"); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED_N = _UxGT("Додат.вент. ~"); #endif - PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Вент. контролера"); PROGMEM Language_Str MSG_EXTRA_FAN_SPEED = _UxGT("Дод. швидк. вент."); + PROGMEM Language_Str MSG_CONTROLLER_FAN = _UxGT("Вент. контролера"); PROGMEM Language_Str MSG_CONTROLLER_FAN_IDLE_SPEED = _UxGT("Холості оберти"); PROGMEM Language_Str MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Авто-режим"); PROGMEM Language_Str MSG_CONTROLLER_FAN_SPEED = _UxGT("Робочі оберти"); @@ -352,8 +393,8 @@ namespace Language_uk { PROGMEM Language_Str MSG_MAX = " " LCD_STR_THERMOMETER ", " LCD_STR_DEGREE _UxGT("С макс"); PROGMEM Language_Str MSG_FACTOR = " " LCD_STR_THERMOMETER _UxGT(" Фактор"); PROGMEM Language_Str MSG_AUTOTEMP = _UxGT("Автотемпер."); - PROGMEM Language_Str MSG_LCD_ON = _UxGT("Увімк"); - PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Вимк."); + PROGMEM Language_Str MSG_LCD_ON = _UxGT("Увім"); + PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Вимк"); PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("Автопідбір PID"); PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("Автопідбір PID *"); @@ -369,6 +410,9 @@ namespace Language_uk { PROGMEM Language_Str MSG_VA_JERK = _UxGT("V") LCD_STR_A _UxGT("-ривок"); PROGMEM Language_Str MSG_VB_JERK = _UxGT("V") LCD_STR_B _UxGT("-ривок"); PROGMEM Language_Str MSG_VC_JERK = _UxGT("V") LCD_STR_C _UxGT("-ривок"); + PROGMEM Language_Str MSG_VI_JERK = _UxGT("V") LCD_STR_I _UxGT("-ривок"); + PROGMEM Language_Str MSG_VJ_JERK = _UxGT("V") LCD_STR_J _UxGT("-ривок"); + PROGMEM Language_Str MSG_VK_JERK = _UxGT("V") LCD_STR_K _UxGT("-ривок"); PROGMEM Language_Str MSG_VE_JERK = _UxGT("Ve-ривок"); #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_JUNCTION_DEVIATION = _UxGT("Відхилення вузла"); @@ -379,14 +423,24 @@ namespace Language_uk { PROGMEM Language_Str MSG_VMAX_A = _UxGT("Швидк.макс ") LCD_STR_A; PROGMEM Language_Str MSG_VMAX_B = _UxGT("Швидк.макс ") LCD_STR_B; PROGMEM Language_Str MSG_VMAX_C = _UxGT("Швидк.макс ") LCD_STR_C; + PROGMEM Language_Str MSG_VMAX_I = _UxGT("Швидк.макс ") LCD_STR_I; + PROGMEM Language_Str MSG_VMAX_J = _UxGT("Швидк.макс ") LCD_STR_J; + PROGMEM Language_Str MSG_VMAX_K = _UxGT("Швидк.макс ") LCD_STR_K; PROGMEM Language_Str MSG_VMAX_E = _UxGT("Швидк.макс ") LCD_STR_E; PROGMEM Language_Str MSG_VMAX_EN = _UxGT("Швидк.макс *"); - PROGMEM Language_Str MSG_VMIN = _UxGT("Швидк.мін"); - PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("Переміщення мін"); + PROGMEM Language_Str MSG_VMIN = _UxGT("Швидк. мін"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("Переміщення мін"); + #else + PROGMEM Language_Str MSG_VTRAV_MIN = _UxGT("Переміщ. мін"); + #endif PROGMEM Language_Str MSG_ACCELERATION = _UxGT("Прискорення, мм/с2"); PROGMEM Language_Str MSG_AMAX_A = _UxGT("Приск.макс ") LCD_STR_A; PROGMEM Language_Str MSG_AMAX_B = _UxGT("Приск.макс ") LCD_STR_B; PROGMEM Language_Str MSG_AMAX_C = _UxGT("Приск.макс ") LCD_STR_C; + PROGMEM Language_Str MSG_AMAX_I = _UxGT("Приск.макс ") LCD_STR_I; + PROGMEM Language_Str MSG_AMAX_J = _UxGT("Приск.макс ") LCD_STR_J; + PROGMEM Language_Str MSG_AMAX_K = _UxGT("Приск.макс ") LCD_STR_K; PROGMEM Language_Str MSG_AMAX_E = _UxGT("Приск.макс ") LCD_STR_E; PROGMEM Language_Str MSG_AMAX_EN = _UxGT("Приск.макс *"); PROGMEM Language_Str MSG_A_RETRACT = _UxGT("Приск.втягув."); @@ -397,6 +451,9 @@ namespace Language_uk { PROGMEM Language_Str MSG_A_STEPS = LCD_STR_A _UxGT(" кроків/мм"); PROGMEM Language_Str MSG_B_STEPS = LCD_STR_B _UxGT(" кроків/мм"); PROGMEM Language_Str MSG_C_STEPS = LCD_STR_C _UxGT(" кроків/мм"); + PROGMEM Language_Str MSG_I_STEPS = LCD_STR_I _UxGT(" кроків/мм"); + PROGMEM Language_Str MSG_J_STEPS = LCD_STR_J _UxGT(" кроків/мм"); + PROGMEM Language_Str MSG_K_STEPS = LCD_STR_K _UxGT(" кроків/мм"); PROGMEM Language_Str MSG_E_STEPS = _UxGT("E кроків/мм"); PROGMEM Language_Str MSG_EN_STEPS = _UxGT("* кроків/мм"); PROGMEM Language_Str MSG_TEMPERATURE = _UxGT("Температура"); @@ -426,7 +483,7 @@ namespace Language_uk { PROGMEM Language_Str MSG_SETTINGS_STORED = _UxGT("Параметри збережені"); PROGMEM Language_Str MSG_MEDIA_UPDATE = _UxGT("Оновити SD-картку"); PROGMEM Language_Str MSG_RESET_PRINTER = _UxGT("Зкинути принтер"); - PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT(" Поновити"); + PROGMEM Language_Str MSG_REFRESH = LCD_STR_REFRESH _UxGT(" Поновити"); PROGMEM Language_Str MSG_INFO_SCREEN = _UxGT("Головний екран"); PROGMEM Language_Str MSG_PREPARE = _UxGT("Підготувати"); PROGMEM Language_Str MSG_TUNE = _UxGT("Підлаштування"); @@ -472,8 +529,6 @@ namespace Language_uk { #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_CONTROL_RETRACT = _UxGT("Втягування, мм"); PROGMEM Language_Str MSG_CONTROL_RETRACT_SWAP = _UxGT("Зміна втягув.,мм"); - PROGMEM Language_Str MSG_CONTROL_RETRACTF = _UxGT("Ретракт V"); - PROGMEM Language_Str MSG_CONTROL_RETRACT_ZHOP = _UxGT("Стрибок, мм"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER = _UxGT("Повернення, мм"); PROGMEM Language_Str MSG_CONTROL_RETRACT_RECOVER_SWAP = _UxGT("Поверн.зміни, мм"); PROGMEM Language_Str MSG_AUTORETRACT = _UxGT("Автовтягування"); @@ -556,6 +611,9 @@ namespace Language_uk { PROGMEM Language_Str MSG_BABYSTEP_X = _UxGT("Мікрокрок X"); PROGMEM Language_Str MSG_BABYSTEP_Y = _UxGT("Мікрокрок Y"); PROGMEM Language_Str MSG_BABYSTEP_Z = _UxGT("Мікрокрок Z"); + PROGMEM Language_Str MSG_BABYSTEP_I = _UxGT("Мікрокрок ") LCD_STR_I; + PROGMEM Language_Str MSG_BABYSTEP_J = _UxGT("Мікрокрок ") LCD_STR_J; + PROGMEM Language_Str MSG_BABYSTEP_K = _UxGT("Мікрокрок ") LCD_STR_K; PROGMEM Language_Str MSG_BABYSTEP_TOTAL = _UxGT("Сумарно"); PROGMEM Language_Str MSG_ENDSTOP_ABORT = _UxGT("Кінцевик спрацював"); PROGMEM Language_Str MSG_HEATING_FAILED_LCD = _UxGT("Збій нагріву"); @@ -563,7 +621,13 @@ namespace Language_uk { PROGMEM Language_Str MSG_THERMAL_RUNAWAY = _UxGT("ВИТІК ТЕПЛА"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED = _UxGT("ВИТІК ТЕПЛА СТОЛУ"); PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER = _UxGT("ВИТІК ТЕПЛА КАМЕРИ"); - PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("МАКСИМАЛЬНА Т"); + PROGMEM Language_Str MSG_THERMAL_RUNAWAY_COOLER = _UxGT("ВИТІК ОХОЛОДЖЕННЯ"); + #if LCD_WIDTH >= 20 + PROGMEM Language_Str MSG_COOLING_FAILED = _UxGT("ОХОЛОДЖЕННЯ НЕ ВДАЛОСЬ"); + #else + PROGMEM Language_Str MSG_COOLING_FAILED = _UxGT("ОХОЛОДЖ. НЕ ВДАЛОСЬ"); + #endif + PROGMEM Language_Str MSG_ERR_MAXTEMP = _UxGT("МАКСИМАЛЬНА Т") LCD_STR_DEGREE; PROGMEM Language_Str MSG_ERR_MINTEMP = _UxGT("МІНІМАЛЬНА Т") LCD_STR_DEGREE; PROGMEM Language_Str MSG_HALTED = _UxGT("ПРИНТЕР ЗУПИНЕНО"); PROGMEM Language_Str MSG_PLEASE_RESET = _UxGT("Перезавантажте"); @@ -573,18 +637,20 @@ namespace Language_uk { PROGMEM Language_Str MSG_HEATING = _UxGT("Нагрівання..."); PROGMEM Language_Str MSG_COOLING = _UxGT("Охолодження..."); PROGMEM Language_Str MSG_BED_HEATING = _UxGT("Нагрів столу..."); - PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Нагрів камери..."); PROGMEM Language_Str MSG_PROBE_HEATING = _UxGT("Нагрів зонду..."); - PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Калібрування Delta"); + PROGMEM Language_Str MSG_CHAMBER_HEATING = _UxGT("Нагрів камери..."); #if LCD_WIDTH >= 20 PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Охолодження столу..."); - PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Охолодження камери..."); PROGMEM Language_Str MSG_PROBE_COOLING = _UxGT("Охолодження зонду..."); + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Охолодження камери..."); + PROGMEM Language_Str MSG_LASER_COOLING = _UxGT("Охолодження лазеру..."); #else - PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Охол. столу..."); - PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Охол. камери..."); - PROGMEM Language_Str MSG_PROBE_COOLING = _UxGT("Охол. зонду..."); + PROGMEM Language_Str MSG_BED_COOLING = _UxGT("Охолодж. столу..."); + PROGMEM Language_Str MSG_PROBE_COOLING = _UxGT("Охолодж. зонду..."); + PROGMEM Language_Str MSG_CHAMBER_COOLING = _UxGT("Охолодж. камери..."); + PROGMEM Language_Str MSG_LASER_COOLING = _UxGT("Охолодж. лазеру..."); #endif + PROGMEM Language_Str MSG_DELTA_CALIBRATE = _UxGT("Калібрування Delta"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_X = _UxGT("Калібрувати X"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_Y = _UxGT("Калібрувати Y"); PROGMEM Language_Str MSG_DELTA_CALIBRATE_Z = _UxGT("Калібрувати Z"); @@ -611,6 +677,11 @@ namespace Language_uk { #endif PROGMEM Language_Str MSG_UBL_LEVELING = _UxGT("UBL"); PROGMEM Language_Str MSG_MESH_LEVELING = _UxGT("Вирівнювання сітки"); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_MESH_DONE = _UxGT("Зондування сітки виконано"); + #else + PROGMEM Language_Str MSG_MESH_DONE = _UxGT("Зондування виконано"); + #endif PROGMEM Language_Str MSG_INFO_STATS_MENU = _UxGT("Статистика принтера"); PROGMEM Language_Str MSG_INFO_BOARD_MENU = _UxGT("Про плату"); @@ -651,6 +722,9 @@ namespace Language_uk { PROGMEM Language_Str MSG_DAC_PERCENT_X = _UxGT("Драйвер X, %"); PROGMEM Language_Str MSG_DAC_PERCENT_Y = _UxGT("Драйвер Y, %"); PROGMEM Language_Str MSG_DAC_PERCENT_Z = _UxGT("Драйвер Z, %"); + PROGMEM Language_Str MSG_DAC_PERCENT_I = _UxGT("Драйвер ") AXIS4_STR _UxGT(", %"); + PROGMEM Language_Str MSG_DAC_PERCENT_J = _UxGT("Драйвер ") AXIS5_STR _UxGT(", %"); + PROGMEM Language_Str MSG_DAC_PERCENT_K = _UxGT("Драйвер ") AXIS6_STR _UxGT(", %"); PROGMEM Language_Str MSG_DAC_PERCENT_E = _UxGT("Драйвер E, %"); PROGMEM Language_Str MSG_ERROR_TMC = _UxGT("ЗБІЙ ЗВ'ЯЗКУ З TMC"); PROGMEM Language_Str MSG_DAC_EEPROM_WRITE = _UxGT("Запис ЦАП у EEPROM"); @@ -687,19 +761,19 @@ namespace Language_uk { #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("MMU Завантажити в сопло"); #else - PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("MMU Завантаж. в сопло"); + PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE = _UxGT("MMU Завант. в сопло"); #endif PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT = _UxGT("MMU Звільнити"); PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N = _UxGT("MMU Звільнити ~"); PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT = _UxGT("MMU Вивантажити"); - PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("MMU Завантаж. %i..."); - PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("MMU Звільнення..."); - PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("MMU Вивантаження..."); - PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("MMU Все"); - PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("MMU Пруток ~"); - PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("MMU Перезапуск"); + PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT = _UxGT("Завантаж. %i..."); + PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT = _UxGT("Викидання прутка..."); + PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT = _UxGT("Вивантаження..."); + PROGMEM Language_Str MSG_MMU2_ALL = _UxGT("Все"); + PROGMEM Language_Str MSG_MMU2_FILAMENT_N = _UxGT("Пруток ~"); + PROGMEM Language_Str MSG_MMU2_RESET = _UxGT("Перезапуск MMU"); PROGMEM Language_Str MSG_MMU2_RESETTING = _UxGT("MMU Перезапуск..."); - PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("MMU Видаліть, натисніть"); + PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER = _UxGT("Видаліть, натисніть"); #if LCD_WIDTH > 21 PROGMEM Language_Str MSG_MIX = _UxGT("Змішування"); @@ -710,7 +784,11 @@ namespace Language_uk { PROGMEM Language_Str MSG_MIXER = _UxGT("Змішувач"); PROGMEM Language_Str MSG_GRADIENT = _UxGT("Градієнт"); PROGMEM Language_Str MSG_FULL_GRADIENT = _UxGT("Повний градієнт"); - PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("Змішування переключ."); + #if LCD_WIDTH > 21 + PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("Переключити змішування"); + #else + PROGMEM Language_Str MSG_TOGGLE_MIX = _UxGT("Переключ.змішування"); + #endif PROGMEM Language_Str MSG_CYCLE_MIX = _UxGT("Циклічне змішування"); PROGMEM Language_Str MSG_GRADIENT_MIX = _UxGT("Градієнт змішування"); PROGMEM Language_Str MSG_REVERSE_GRADIENT = _UxGT("Змінити градієнт"); @@ -721,14 +799,13 @@ namespace Language_uk { PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("Зкидання В-інструментів"); #else PROGMEM Language_Str MSG_ACTIVE_VTOOL = _UxGT("Актив. В-інструм."); - PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("Псевдонім В-інструм."); + PROGMEM Language_Str MSG_GRADIENT_ALIAS = _UxGT("Псевдонім В-інструм"); PROGMEM Language_Str MSG_RESET_VTOOLS = _UxGT("Зкидання В-інструм."); #endif PROGMEM Language_Str MSG_START_VTOOL = _UxGT("Початок В-інструменту"); PROGMEM Language_Str MSG_END_VTOOL = _UxGT("Кінець В-інструменту"); PROGMEM Language_Str MSG_COMMIT_VTOOL = _UxGT("Змішати В-інструменти"); PROGMEM Language_Str MSG_VTOOLS_RESET = _UxGT("В-інструменти зкинуті"); - PROGMEM Language_Str MSG_START_Z = _UxGT("Початок Z:"); PROGMEM Language_Str MSG_END_Z = _UxGT(" Кінець Z:"); @@ -756,12 +833,12 @@ namespace Language_uk { PROGMEM Language_Str MSG_REMINDER_SAVE_SETTINGS = _UxGT("Не забудь зберегти!"); PROGMEM Language_Str MSG_PASSWORD_REMOVED = _UxGT("Пароль видалений"); - PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Паркування...")); // // Filament Change screens show up to 3 lines on a 4-line display // ...or up to 2 lines on a 3-line display // + PROGMEM Language_Str MSG_PAUSE_PRINT_PARKING = _UxGT(MSG_1_LINE("Паркування...")); #if LCD_HEIGHT >= 4 // Up to 3 lines allowed PROGMEM Language_Str MSG_ADVANCED_PAUSE_WAITING = _UxGT(MSG_3_LINE("Натисніть кнопку", "для продовження", "друку")); @@ -828,6 +905,11 @@ namespace Language_uk { PROGMEM Language_Str MSG_BOTTOM_RIGHT = _UxGT("Нижній правий"); PROGMEM Language_Str MSG_CALIBRATION_COMPLETED = _UxGT("Калібрування успішне"); PROGMEM Language_Str MSG_CALIBRATION_FAILED = _UxGT("Збій калібрування"); + + PROGMEM Language_Str MSG_DRIVER_BACKWARD = _UxGT(" драйвер назад"); + + PROGMEM Language_Str MSG_SD_CARD = _UxGT("SD Картка"); + PROGMEM Language_Str MSG_USB_DISK = _UxGT("USB Диск"); } #if FAN_COUNT == 1 diff --git a/Marlin/src/lcd/language/language_vi.h b/Marlin/src/lcd/language/language_vi.h index f0b7f732ed..825666d1e1 100644 --- a/Marlin/src/lcd/language/language_vi.h +++ b/Marlin/src/lcd/language/language_vi.h @@ -205,6 +205,7 @@ namespace Language_vi { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("Di chuyển 0.1mm"); // Move 0.1mm PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("Di chuyển 1mm"); // Move 1mm PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("Di chuyển 10mm"); // Move 10mm + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("Di chuyển 100mm"); // Move 100mm PROGMEM Language_Str MSG_SPEED = _UxGT("Tốc độ"); // Speed PROGMEM Language_Str MSG_BED_Z = _UxGT("Z Bàn"); PROGMEM Language_Str MSG_NOZZLE = _UxGT("Đầu phun"); // Nozzle diff --git a/Marlin/src/lcd/language/language_zh_CN.h b/Marlin/src/lcd/language/language_zh_CN.h index 98f7704efc..39093a7c6c 100644 --- a/Marlin/src/lcd/language/language_zh_CN.h +++ b/Marlin/src/lcd/language/language_zh_CN.h @@ -230,6 +230,7 @@ namespace Language_zh_CN { PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("移动 0.1 mm"); //"Move 0.1mm" PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("移动 1 mm"); //"Move 1mm" PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("移动 10 mm"); //"Move 10mm" + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("移动 100 mm"); //"Move 100mm" PROGMEM Language_Str MSG_SPEED = _UxGT("速率"); //"Speed" PROGMEM Language_Str MSG_BED_Z = _UxGT("热床Z"); //"Bed Z" PROGMEM Language_Str MSG_NOZZLE = _UxGT("喷嘴"); //"Nozzle" 噴嘴 diff --git a/Marlin/src/lcd/language/language_zh_TW.h b/Marlin/src/lcd/language/language_zh_TW.h index 0ada34a476..2061a66ad8 100644 --- a/Marlin/src/lcd/language/language_zh_TW.h +++ b/Marlin/src/lcd/language/language_zh_TW.h @@ -223,11 +223,12 @@ namespace Language_zh_TW { PROGMEM Language_Str MSG_MOVE_Z = _UxGT("移動Z"); //"Move Z" PROGMEM Language_Str MSG_MOVE_E = _UxGT("擠出機"); //"Extruder" PROGMEM Language_Str MSG_MOVE_EN = _UxGT("擠出機 *"); //"Extruder *" - PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("噴嘴溫度不夠"); //"Hotend too cold" + PROGMEM Language_Str MSG_HOTEND_TOO_COLD = _UxGT("噴嘴溫度不夠"); //"Hotend too cold" PROGMEM Language_Str MSG_MOVE_N_MM = _UxGT("移動 %s mm"); //"Move 0.025mm" - PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("移動 0.1 mm"); //"Move 0.1mm" - PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("移動 1 mm"); //"Move 1mm" + PROGMEM Language_Str MSG_MOVE_01MM = _UxGT("移動 0.1 mm"); //"Move 0.1mm" + PROGMEM Language_Str MSG_MOVE_1MM = _UxGT("移動 1 mm"); //"Move 1mm" PROGMEM Language_Str MSG_MOVE_10MM = _UxGT("移動 10 mm"); //"Move 10mm" + PROGMEM Language_Str MSG_MOVE_100MM = _UxGT("移動 100 mm"); //"Move 100mm" PROGMEM Language_Str MSG_SPEED = _UxGT("速率"); //"Speed" PROGMEM Language_Str MSG_BED_Z = _UxGT("熱床Z"); //"Bed Z" PROGMEM Language_Str MSG_NOZZLE = " " LCD_STR_THERMOMETER _UxGT(" 噴嘴"); //"Nozzle" 噴嘴 diff --git a/Marlin/src/lcd/lcdprint.cpp b/Marlin/src/lcd/lcdprint.cpp index 32f425168f..c421ef1a03 100644 --- a/Marlin/src/lcd/lcdprint.cpp +++ b/Marlin/src/lcd/lcdprint.cpp @@ -41,6 +41,7 @@ * * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL) */ lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const inStr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) { + const uint8_t prop = USE_WIDE_GLYPH ? 2 : 1; uint8_t *p = (uint8_t*)pstr; int8_t n = maxlen; while (n > 0) { @@ -73,10 +74,27 @@ lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const i } else { lcd_put_wchar(ch); - n--; + n -= ch > 255 ? prop : 1; } } return n; } +// Calculate UTF8 width with a simple check +int calculateWidth(PGM_P const pstr) { + if (!USE_WIDE_GLYPH) return utf8_strlen_P(pstr) * MENU_FONT_WIDTH; + const uint8_t prop = 2; + uint8_t *p = (uint8_t*)pstr; + int n = 0; + + do { + wchar_t ch; + p = get_utf8_value_cb(p, read_byte_rom, &ch); + if (!ch) break; + n += (ch > 255) ? prop : 1; + } while (1); + + return n * MENU_FONT_WIDTH; +} + #endif // HAS_WIRED_LCD diff --git a/Marlin/src/lcd/lcdprint.h b/Marlin/src/lcd/lcdprint.h index fe856535b0..105a66085f 100644 --- a/Marlin/src/lcd/lcdprint.h +++ b/Marlin/src/lcd/lcdprint.h @@ -172,3 +172,5 @@ inline int lcd_put_wchar(const lcd_uint_t col, const lcd_uint_t row, const wchar lcd_moveto(col, row); return lcd_put_wchar(c); } + +int calculateWidth(PGM_P const pstr); diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index b66bff6682..727b64b36b 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -120,1173 +120,1169 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; } #endif +#if EITHER(HAS_LCD_MENU, EXTENSIBLE_UI) + bool MarlinUI::lcd_clicked; +#endif + #if HAS_WIRED_LCD -#if HAS_MARLINUI_U8GLIB - #include "dogm/marlinui_DOGM.h" -#endif - -#include "lcdprint.h" - -#include "../sd/cardreader.h" - -#include "../module/temperature.h" -#include "../module/planner.h" -#include "../module/motion.h" - -#if HAS_LCD_MENU - #include "../module/settings.h" -#endif - -#if ENABLED(AUTO_BED_LEVELING_UBL) - #include "../feature/bedlevel/bedlevel.h" -#endif - -#if HAS_TRINAMIC_CONFIG - #include "../feature/tmc_util.h" -#endif - -#if HAS_ADC_BUTTONS - #include "../module/thermistor/thermistors.h" -#endif - -#if HAS_POWER_MONITOR - #include "../feature/power_monitor.h" -#endif - -#if HAS_ENCODER_ACTION - volatile uint8_t MarlinUI::buttons; - #if HAS_SLOW_BUTTONS - volatile uint8_t MarlinUI::slow_buttons; + #if HAS_MARLINUI_U8GLIB + #include "dogm/marlinui_DOGM.h" #endif - #if HAS_TOUCH_BUTTONS - #include "touch/touch_buttons.h" - bool MarlinUI::on_edit_screen = false; - #endif -#endif -#if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS > 0 - bool MarlinUI::defer_return_to_status; -#endif - -uint8_t MarlinUI::lcd_status_update_delay = 1; // First update one loop delayed - -#if BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) - millis_t MarlinUI::next_filament_display; // = 0 -#endif - -millis_t MarlinUI::next_button_update_ms; // = 0 - -#if HAS_MARLINUI_U8GLIB - bool MarlinUI::drawing_screen, MarlinUI::first_page; // = false -#endif - -// Encoder Handling -#if HAS_ENCODER_ACTION - uint32_t MarlinUI::encoderPosition; - volatile int8_t encoderDiff; // Updated in update_buttons, added to encoderPosition every LCD update -#endif - -#if ENABLED(SDSUPPORT) + #include "lcdprint.h" #include "../sd/cardreader.h" - #if MARLINUI_SCROLL_NAME - uint8_t MarlinUI::filename_scroll_pos, MarlinUI::filename_scroll_max; + #include "../module/temperature.h" + #include "../module/planner.h" + #include "../module/motion.h" + + #if HAS_LCD_MENU + #include "../module/settings.h" #endif - const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll) { - const char *outstr = theCard.longest_filename(); - if (theCard.longFilename[0]) { - #if MARLINUI_SCROLL_NAME - if (doScroll) { - for (uint8_t l = FILENAME_LENGTH; l--;) - hash = ((hash << 1) | (hash >> 7)) ^ theCard.filename[l]; // rotate, xor - static uint8_t filename_scroll_hash; - if (filename_scroll_hash != hash) { // If the hash changed... - filename_scroll_hash = hash; // Save the new hash - filename_scroll_max = _MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit - filename_scroll_pos = 0; // Reset scroll to the start - lcd_status_update_delay = 8; // Don't scroll right away - } - // Advance byte position corresponding to filename_scroll_pos char position - outstr += TERN(UTF_FILENAME_SUPPORT, utf8_byte_pos_by_char_num(outstr, filename_scroll_pos), filename_scroll_pos); - } - #else - theCard.longFilename[ - TERN(UTF_FILENAME_SUPPORT, utf8_byte_pos_by_char_num(theCard.longFilename, maxlen), maxlen) - ] = '\0'; // cutoff at screen edge - #endif - } - return outstr; - } - -#endif - -#if HAS_LCD_MENU - #include "menu/menu.h" - - screenFunc_t MarlinUI::currentScreen; // Initialized in CTOR - bool MarlinUI::screen_changed; - - #if ENABLED(ENCODER_RATE_MULTIPLIER) - bool MarlinUI::encoderRateMultiplierEnabled; - millis_t MarlinUI::lastEncoderMovementMillis = 0; - void MarlinUI::enable_encoder_multiplier(const bool onoff) { - encoderRateMultiplierEnabled = onoff; - lastEncoderMovementMillis = 0; - } + #if ENABLED(AUTO_BED_LEVELING_UBL) + #include "../feature/bedlevel/bedlevel.h" #endif - #if EITHER(REVERSE_MENU_DIRECTION, REVERSE_SELECT_DIRECTION) - int8_t MarlinUI::encoderDirection = ENCODERBASE; + #if HAS_TRINAMIC_CONFIG + #include "../feature/tmc_util.h" #endif - #if HAS_TOUCH_BUTTONS - uint8_t MarlinUI::touch_buttons; - uint8_t MarlinUI::repeat_delay; + #if HAS_ADC_BUTTONS + #include "../module/thermistor/thermistors.h" #endif - #if EITHER(AUTO_BED_LEVELING_UBL, G26_MESH_VALIDATION) - - bool MarlinUI::external_control; // = false - - void MarlinUI::wait_for_release() { - while (button_pressed()) safe_delay(50); - safe_delay(50); - } - + #if HAS_POWER_MONITOR + #include "../feature/power_monitor.h" #endif - #if !HAS_GRAPHICAL_TFT + #if HAS_ENCODER_ACTION + volatile uint8_t MarlinUI::buttons; + #if HAS_SLOW_BUTTONS + volatile uint8_t MarlinUI::slow_buttons; + #endif + #if HAS_TOUCH_BUTTONS + #include "touch/touch_buttons.h" + bool MarlinUI::on_edit_screen = false; + #endif + #endif - void _wrap_string(uint8_t &col, uint8_t &row, const char * const string, read_byte_cb_t cb_read_byte, bool wordwrap/*=false*/) { - SETCURSOR(col, row); - if (!string) return; + #if SCREENS_CAN_TIME_OUT + bool MarlinUI::defer_return_to_status; + millis_t MarlinUI::return_to_status_ms = 0; + #endif - auto _newline = [&col, &row]{ - col = 0; row++; // Move col to string len (plus space) - SETCURSOR(0, row); // Simulate carriage return - }; + uint8_t MarlinUI::lcd_status_update_delay = 1; // First update one loop delayed - uint8_t *p = (uint8_t*)string; - wchar_t ch; - if (wordwrap) { - uint8_t *wrd = nullptr, c = 0; - // find the end of the part - for (;;) { - if (!wrd) wrd = p; // Get word start /before/ advancing - p = get_utf8_value_cb(p, cb_read_byte, &ch); - const bool eol = !ch; // zero ends the string - // End or a break between phrases? - if (eol || ch == ' ' || ch == '-' || ch == '+' || ch == '.') { - if (!c && ch == ' ') { if (wrd) wrd++; continue; } // collapse extra spaces - // Past the right and the word is not too long? - if (col + c > LCD_WIDTH && col >= (LCD_WIDTH) / 4) _newline(); // should it wrap? - c += !eol; // +1 so the space will be printed - col += c; // advance col to new position - while (c) { // character countdown - --c; // count down to zero - wrd = get_utf8_value_cb(wrd, cb_read_byte, &ch); // get characters again - lcd_put_wchar(ch); // character to the LCD + #if BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) + millis_t MarlinUI::next_filament_display; // = 0 + #endif + + millis_t MarlinUI::next_button_update_ms; // = 0 + + #if HAS_MARLINUI_U8GLIB + bool MarlinUI::drawing_screen, MarlinUI::first_page; // = false + #endif + + // Encoder Handling + #if HAS_ENCODER_ACTION + uint32_t MarlinUI::encoderPosition; + volatile int8_t encoderDiff; // Updated in update_buttons, added to encoderPosition every LCD update + #endif + + #if ENABLED(SDSUPPORT) + + #include "../sd/cardreader.h" + + #if MARLINUI_SCROLL_NAME + uint8_t MarlinUI::filename_scroll_pos, MarlinUI::filename_scroll_max; + #endif + + const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll) { + const char *outstr = theCard.longest_filename(); + if (theCard.longFilename[0]) { + #if MARLINUI_SCROLL_NAME + if (doScroll) { + for (uint8_t l = FILENAME_LENGTH; l--;) + hash = ((hash << 1) | (hash >> 7)) ^ theCard.filename[l]; // rotate, xor + static uint8_t filename_scroll_hash; + if (filename_scroll_hash != hash) { // If the hash changed... + filename_scroll_hash = hash; // Save the new hash + filename_scroll_max = _MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit + filename_scroll_pos = 0; // Reset scroll to the start + lcd_status_update_delay = 8; // Don't scroll right away } - if (eol) break; // all done! - wrd = nullptr; // set up for next word - } - else c++; // count word characters - } - } - else { - for (;;) { - p = get_utf8_value_cb(p, cb_read_byte, &ch); - if (!ch) break; - lcd_put_wchar(ch); - col++; - if (col >= LCD_WIDTH) _newline(); - } - } - } - - void MarlinUI::draw_select_screen_prompt(PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { - const uint8_t plen = utf8_strlen_P(pref), slen = suff ? utf8_strlen_P(suff) : 0; - uint8_t col = 0, row = 0; - if (!string && plen + slen <= LCD_WIDTH) { - col = (LCD_WIDTH - plen - slen) / 2; - row = LCD_HEIGHT > 3 ? 1 : 0; - } - wrap_string_P(col, row, pref, true); - if (string) { - if (col) { col = 0; row++; } // Move to the start of the next line - wrap_string(col, row, string); - } - if (suff) wrap_string_P(col, row, suff); - } - - #endif // !HAS_GRAPHICAL_TFT - -#endif // HAS_LCD_MENU - -void MarlinUI::init() { - - init_lcd(); - - #if HAS_DIGITAL_BUTTONS - #if BUTTON_EXISTS(EN1) - SET_INPUT_PULLUP(BTN_EN1); - #endif - #if BUTTON_EXISTS(EN2) - SET_INPUT_PULLUP(BTN_EN2); - #endif - #if BUTTON_EXISTS(ENC) - SET_INPUT_PULLUP(BTN_ENC); - #endif - #if BUTTON_EXISTS(ENC_EN) - SET_INPUT_PULLUP(BTN_ENC_EN); - #endif - #if BUTTON_EXISTS(BACK) - SET_INPUT_PULLUP(BTN_BACK); - #endif - #if BUTTON_EXISTS(UP) - SET_INPUT(BTN_UP); - #endif - #if BUTTON_EXISTS(DWN) - SET_INPUT(BTN_DWN); - #endif - #if BUTTON_EXISTS(LFT) - SET_INPUT(BTN_LFT); - #endif - #if BUTTON_EXISTS(RT) - SET_INPUT(BTN_RT); - #endif - #endif - - #if HAS_SHIFT_ENCODER - - #if ENABLED(SR_LCD_2W_NL) // Non latching 2 wire shift register - - SET_OUTPUT(SR_DATA_PIN); - SET_OUTPUT(SR_CLK_PIN); - - #elif PIN_EXISTS(SHIFT_CLK) - - SET_OUTPUT(SHIFT_CLK_PIN); - OUT_WRITE(SHIFT_LD_PIN, HIGH); - #if PIN_EXISTS(SHIFT_EN) - OUT_WRITE(SHIFT_EN_PIN, LOW); - #endif - SET_INPUT_PULLUP(SHIFT_OUT_PIN); - - #endif - - #endif // HAS_SHIFT_ENCODER - - #if BOTH(HAS_ENCODER_ACTION, HAS_SLOW_BUTTONS) - slow_buttons = 0; - #endif - - update_buttons(); - - TERN_(HAS_ENCODER_ACTION, encoderDiff = 0); -} - -bool MarlinUI::get_blink() { - static uint8_t blink = 0; - static millis_t next_blink_ms = 0; - millis_t ms = millis(); - if (ELAPSED(ms, next_blink_ms)) { - blink ^= 0xFF; - next_blink_ms = ms + 1000 - (LCD_UPDATE_INTERVAL) / 2; - } - return blink != 0; -} - -//////////////////////////////////////////// -///////////// Keypad Handling ////////////// -//////////////////////////////////////////// - -#if IS_RRW_KEYPAD && HAS_ENCODER_ACTION - - volatile uint8_t MarlinUI::keypad_buttons; - - #if HAS_LCD_MENU && !HAS_ADC_BUTTONS - - void lcd_move_x(); - void lcd_move_y(); - void lcd_move_z(); - - void _reprapworld_keypad_move(const AxisEnum axis, const int16_t dir) { - ui.manual_move.menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP; - ui.encoderPosition = dir; - switch (axis) { - case X_AXIS: lcd_move_x(); break; - case Y_AXIS: lcd_move_y(); break; - case Z_AXIS: lcd_move_z(); - default: break; - } - } - - #endif - - bool MarlinUI::handle_keypad() { - - #if HAS_ADC_BUTTONS - - #define ADC_MIN_KEY_DELAY 100 - if (keypad_buttons) { - #if HAS_ENCODER_ACTION - refresh(LCDVIEW_REDRAW_NOW); - #if HAS_LCD_MENU - if (encoderDirection == -(ENCODERBASE)) { // HAS_ADC_BUTTONS forces REVERSE_MENU_DIRECTION, so this indicates menu navigation - if (RRK(EN_KEYPAD_UP)) encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; - else if (RRK(EN_KEYPAD_DOWN)) encoderPosition -= ENCODER_STEPS_PER_MENU_ITEM; - else if (RRK(EN_KEYPAD_LEFT)) { MenuItem_back::action(); quick_feedback(); } - else if (RRK(EN_KEYPAD_RIGHT)) { return_to_status(); quick_feedback(); } - } - else - #endif - { - #if HAS_LCD_MENU - if (RRK(EN_KEYPAD_UP)) encoderPosition -= epps; - else if (RRK(EN_KEYPAD_DOWN)) encoderPosition += epps; - else if (RRK(EN_KEYPAD_LEFT)) { MenuItem_back::action(); quick_feedback(); } - else if (RRK(EN_KEYPAD_RIGHT)) encoderPosition = 0; - #else - if (RRK(EN_KEYPAD_UP) || RRK(EN_KEYPAD_LEFT)) encoderPosition -= epps; - else if (RRK(EN_KEYPAD_DOWN) || RRK(EN_KEYPAD_RIGHT)) encoderPosition += epps; - #endif + // Advance byte position corresponding to filename_scroll_pos char position + outstr += TERN(UTF_FILENAME_SUPPORT, utf8_byte_pos_by_char_num(outstr, filename_scroll_pos), filename_scroll_pos); } + #else + theCard.longFilename[ + TERN(UTF_FILENAME_SUPPORT, utf8_byte_pos_by_char_num(theCard.longFilename, maxlen), maxlen) + ] = '\0'; // cutoff at screen edge #endif - next_button_update_ms = millis() + ADC_MIN_KEY_DELAY; - return true; } + return outstr; + } - #else // !HAS_ADC_BUTTONS - - static uint8_t keypad_debounce = 0; - - if (!RRK( EN_KEYPAD_F1 | EN_KEYPAD_F2 - | EN_KEYPAD_F3 | EN_KEYPAD_DOWN - | EN_KEYPAD_RIGHT | EN_KEYPAD_MIDDLE - | EN_KEYPAD_UP | EN_KEYPAD_LEFT ) - ) { - if (keypad_debounce > 0) keypad_debounce--; - } - else if (!keypad_debounce) { - keypad_debounce = 2; - - const bool homed = all_axes_homed(); - - #if HAS_LCD_MENU - - if (RRK(EN_KEYPAD_MIDDLE)) goto_screen(menu_move); - - #if NONE(DELTA, Z_HOME_TO_MAX) - if (RRK(EN_KEYPAD_F2)) _reprapworld_keypad_move(Z_AXIS, 1); - #endif - - if (homed) { - #if EITHER(DELTA, Z_HOME_TO_MAX) - if (RRK(EN_KEYPAD_F2)) _reprapworld_keypad_move(Z_AXIS, 1); - #endif - if (RRK(EN_KEYPAD_F3)) _reprapworld_keypad_move(Z_AXIS, -1); - if (RRK(EN_KEYPAD_LEFT)) _reprapworld_keypad_move(X_AXIS, -1); - if (RRK(EN_KEYPAD_RIGHT)) _reprapworld_keypad_move(X_AXIS, 1); - if (RRK(EN_KEYPAD_DOWN)) _reprapworld_keypad_move(Y_AXIS, 1); - if (RRK(EN_KEYPAD_UP)) _reprapworld_keypad_move(Y_AXIS, -1); - } - - #endif // HAS_LCD_MENU - - if (!homed && RRK(EN_KEYPAD_F1)) queue.inject_P(G28_STR); - return true; - } - - #endif // !HAS_ADC_BUTTONS - - return false; - } - -#endif // IS_RRW_KEYPAD && HAS_ENCODER_ACTION - -/** - * Status Screen - * - * This is very display-dependent, so the lcd implementation draws this. - */ - -#if BASIC_PROGRESS_BAR - millis_t MarlinUI::progress_bar_ms; // = 0 - #if PROGRESS_MSG_EXPIRE > 0 - millis_t MarlinUI::expire_status_ms; // = 0 #endif -#endif -void MarlinUI::status_screen() { + #if HAS_LCD_MENU + #include "menu/menu.h" - TERN_(HAS_LCD_MENU, ENCODER_RATE_MULTIPLY(false)); + screenFunc_t MarlinUI::currentScreen; // Initialized in CTOR + bool MarlinUI::screen_changed; - #if BASIC_PROGRESS_BAR - - // - // HD44780 implements the following message blinking and - // message expiration because Status Line and Progress Bar - // share the same line on the display. - // - - #if DISABLED(PROGRESS_MSG_ONCE) || (PROGRESS_MSG_EXPIRE > 0) - #define GOT_MS - const millis_t ms = millis(); + #if ENABLED(ENCODER_RATE_MULTIPLIER) + bool MarlinUI::encoderRateMultiplierEnabled; + millis_t MarlinUI::lastEncoderMovementMillis = 0; + void MarlinUI::enable_encoder_multiplier(const bool onoff) { + encoderRateMultiplierEnabled = onoff; + lastEncoderMovementMillis = 0; + } #endif - // If the message will blink rather than expire... - #if DISABLED(PROGRESS_MSG_ONCE) - if (ELAPSED(ms, progress_bar_ms + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME)) - progress_bar_ms = ms; + #if EITHER(REVERSE_MENU_DIRECTION, REVERSE_SELECT_DIRECTION) + int8_t MarlinUI::encoderDirection = ENCODERBASE; #endif - #if PROGRESS_MSG_EXPIRE > 0 + #if HAS_TOUCH_BUTTONS + uint8_t MarlinUI::touch_buttons; + uint8_t MarlinUI::repeat_delay; + #endif - // Handle message expire - if (expire_status_ms) { + #if EITHER(AUTO_BED_LEVELING_UBL, G26_MESH_VALIDATION) - // Expire the message if a job is active and the bar has ticks - if (get_progress_percent() > 2 && !print_job_timer.isPaused()) { - if (ELAPSED(ms, expire_status_ms)) { - status_message[0] = '\0'; - expire_status_ms = 0; + bool MarlinUI::external_control; // = false + + void MarlinUI::wait_for_release() { + while (button_pressed()) safe_delay(50); + safe_delay(50); + } + + #endif + + #if !HAS_GRAPHICAL_TFT + + void _wrap_string(uint8_t &col, uint8_t &row, const char * const string, read_byte_cb_t cb_read_byte, bool wordwrap/*=false*/) { + SETCURSOR(col, row); + if (!string) return; + + auto _newline = [&col, &row]{ + col = 0; row++; // Move col to string len (plus space) + SETCURSOR(0, row); // Simulate carriage return + }; + + uint8_t *p = (uint8_t*)string; + wchar_t ch; + if (wordwrap) { + uint8_t *wrd = nullptr, c = 0; + // find the end of the part + for (;;) { + if (!wrd) wrd = p; // Get word start /before/ advancing + p = get_utf8_value_cb(p, cb_read_byte, &ch); + const bool eol = !ch; // zero ends the string + // End or a break between phrases? + if (eol || ch == ' ' || ch == '-' || ch == '+' || ch == '.') { + if (!c && ch == ' ') { if (wrd) wrd++; continue; } // collapse extra spaces + // Past the right and the word is not too long? + if (col + c > LCD_WIDTH && col >= (LCD_WIDTH) / 4) _newline(); // should it wrap? + c += !eol; // +1 so the space will be printed + col += c; // advance col to new position + while (c) { // character countdown + --c; // count down to zero + wrd = get_utf8_value_cb(wrd, cb_read_byte, &ch); // get characters again + lcd_put_wchar(ch); // character to the LCD + } + if (eol) break; // all done! + wrd = nullptr; // set up for next word + } + else c++; // count word characters } } else { - // Defer message expiration before bar appears - // and during any pause (not just SD) - expire_status_ms += LCD_UPDATE_INTERVAL; - } - } - - #endif // PROGRESS_MSG_EXPIRE - - #endif // BASIC_PROGRESS_BAR - - #if HAS_LCD_MENU - if (use_click()) { - #if BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) - next_filament_display = millis() + 5000UL; // Show status message for 5s - #endif - goto_screen(menu_main); - #if DISABLED(NO_LCD_REINIT) - init_lcd(); // May revive the LCD if static electricity killed it - #endif - return; - } - - #endif - - #if ENABLED(ULTIPANEL_FEEDMULTIPLY) - - const int16_t old_frm = feedrate_percentage; - int16_t new_frm = old_frm + int16_t(encoderPosition); - - // Dead zone at 100% feedrate - if (old_frm == 100) { - if (int16_t(encoderPosition) > ENCODER_FEEDRATE_DEADZONE) - new_frm -= ENCODER_FEEDRATE_DEADZONE; - else if (int16_t(encoderPosition) < -(ENCODER_FEEDRATE_DEADZONE)) - new_frm += ENCODER_FEEDRATE_DEADZONE; - else - new_frm = old_frm; - } - else if ((old_frm < 100 && new_frm > 100) || (old_frm > 100 && new_frm < 100)) - new_frm = 100; - - LIMIT(new_frm, 10, 999); - - if (old_frm != new_frm) { - feedrate_percentage = new_frm; - encoderPosition = 0; - #if BOTH(HAS_BUZZER, BEEP_ON_FEEDRATE_CHANGE) - static millis_t next_beep; - #ifndef GOT_MS - const millis_t ms = millis(); - #endif - if (ELAPSED(ms, next_beep)) { - buzz(FEEDRATE_CHANGE_BEEP_DURATION, FEEDRATE_CHANGE_BEEP_FREQUENCY); - next_beep = ms + 500UL; - } - #endif - } - - #endif // ULTIPANEL_FEEDMULTIPLY - - draw_status_screen(); -} - -void MarlinUI::kill_screen(PGM_P lcd_error, PGM_P lcd_component) { - init(); - status_printf_P(1, PSTR(S_FMT ": " S_FMT), lcd_error, lcd_component); - TERN_(HAS_LCD_MENU, return_to_status()); - - // RED ALERT. RED ALERT. - #ifdef LED_BACKLIGHT_TIMEOUT - leds.set_color(LEDColorRed()); - #ifdef NEOPIXEL_BKGD_INDEX_FIRST - neo.set_background_color(255, 0, 0, 0); - neo.show(); - #endif - #endif - - draw_kill_screen(); -} - -void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) { - - TERN_(HAS_LCD_MENU, refresh()); - - #if HAS_ENCODER_ACTION - if (clear_buttons) buttons = 0; - next_button_update_ms = millis() + 500; - #else - UNUSED(clear_buttons); - #endif - - #if HAS_CHIRP - chirp(); // Buzz and wait. Is the delay needed for buttons to settle? - #if BOTH(HAS_LCD_MENU, USE_BEEPER) - for (int8_t i = 5; i--;) { buzzer.tick(); delay(2); } - #elif HAS_LCD_MENU - delay(10); - #endif - #endif -} - -//////////////////////////////////////////// -/////////////// Manual Move //////////////// -//////////////////////////////////////////// - -#if HAS_LCD_MENU - - ManualMove MarlinUI::manual_move{}; - - millis_t ManualMove::start_time = 0; - float ManualMove::menu_scale = 1; - #if IS_KINEMATIC - float ManualMove::offset = 0; - xyze_pos_t ManualMove::all_axes_destination = { 0 }; - bool ManualMove::processing = false; - #endif - #if MULTI_E_MANUAL - int8_t ManualMove::e_index = 0; - #endif - AxisEnum ManualMove::axis = NO_AXIS_ENUM; - - /** - * If a manual move has been posted and its time has arrived, and if the planner - * has a space for it, then add a linear move to current_position the planner. - * - * If any manual move needs to be interrupted, make sure to force a manual move - * by setting manual_move.start_time to millis() after updating current_position. - * - * To post a manual move: - * - Update current_position to the new place you want to go. - * - Set manual_move.axis to an axis like X_AXIS. Use ALL_AXES_ENUM for diagonal moves. - * - Set manual_move.start_time to a point in the future (in ms) when the move should be done. - * - * For kinematic machines: - * - Set manual_move.offset to modify one axis and post the move. - * This is used to achieve more rapid stepping on kinematic machines. - * - * Currently used by the _lcd_move_xyz function in menu_motion.cpp - * and the ubl_map_move_to_xy funtion in menu_ubl.cpp. - */ - void ManualMove::task() { - - if (processing) return; // Prevent re-entry from idle() calls - - // Add a manual move to the queue? - if (axis != NO_AXIS_ENUM && ELAPSED(millis(), start_time) && !planner.is_full()) { - - const feedRate_t fr_mm_s = (axis <= LOGICAL_AXES) ? manual_feedrate_mm_s[axis] : XY_PROBE_FEEDRATE_MM_S; - - #if IS_KINEMATIC - - #if HAS_MULTI_EXTRUDER - REMEMBER(ae, active_extruder); - #if MULTI_E_MANUAL - if (axis == E_AXIS) active_extruder = e_index; - #endif - #endif - - // Apply a linear offset to a single axis - if (axis == ALL_AXES_ENUM) - destination = all_axes_destination; - else if (axis <= XYZE) { - destination = current_position; - destination[axis] += offset; - } - - // Reset for the next move - offset = 0; - axis = NO_AXIS_ENUM; - - // DELTA and SCARA machines use segmented moves, which could fill the planner during the call to - // move_to_destination. This will cause idle() to be called, which can then call this function while the - // previous invocation is being blocked. Modifications to offset shouldn't be made while - // processing is true or the planner will get out of sync. - processing = true; - prepare_internal_move_to_destination(fr_mm_s); // will set current_position from destination - processing = false; - - #else - - // For Cartesian / Core motion simply move to the current_position - planner.buffer_line(current_position, fr_mm_s, - TERN_(MULTI_E_MANUAL, axis == E_AXIS ? e_index :) active_extruder - ); - - //SERIAL_ECHOLNPAIR("Add planner.move with Axis ", AS_CHAR(axis_codes[axis]), " at FR ", fr_mm_s); - - axis = NO_AXIS_ENUM; - - #endif - } - } - - // - // Tell ui.update() to start a move to current_position after a short delay. - // - void ManualMove::soon(const AxisEnum move_axis - OPTARG(MULTI_E_MANUAL, const int8_t eindex/*=active_extruder*/) - ) { - TERN_(MULTI_E_MANUAL, if (move_axis == E_AXIS) e_index = eindex); - start_time = millis() + (menu_scale < 0.99f ? 0UL : 250UL); // delay for bigger moves - axis = move_axis; - //SERIAL_ECHOLNPAIR("Post Move with Axis ", AS_CHAR(axis_codes[axis]), " soon."); - } - - #if ENABLED(AUTO_BED_LEVELING_UBL) - - void MarlinUI::external_encoder() { - if (external_control && encoderDiff) { - ubl.encoder_diff += encoderDiff; // Encoder for UBL G29 mesh editing - encoderDiff = 0; // Hide encoder events from the screen handler - refresh(LCDVIEW_REDRAW_NOW); // ...but keep the refresh. - } - } - - #endif - -#endif // HAS_LCD_MENU - -/** - * Update the LCD, read encoder buttons, etc. - * - Read button states - * - Check the SD Card slot state - * - Act on RepRap World keypad input - * - Update the encoder position - * - Apply acceleration to the encoder position - * - Do refresh(LCDVIEW_CALL_REDRAW_NOW) on controller events - * - Reset the Info Screen timeout if there's any input - * - Update status indicators, if any - * - * Run the current LCD menu handler callback function: - * - Call the handler only if lcdDrawUpdate != LCDVIEW_NONE - * - Before calling the handler, LCDVIEW_CALL_NO_REDRAW => LCDVIEW_NONE - * - Call the menu handler. Menu handlers should do the following: - * - If a value changes, set lcdDrawUpdate to LCDVIEW_REDRAW_NOW and draw the value - * (Encoder events automatically set lcdDrawUpdate for you.) - * - if (should_draw()) { redraw } - * - Before exiting the handler set lcdDrawUpdate to: - * - LCDVIEW_CLEAR_CALL_REDRAW to clear screen and set LCDVIEW_CALL_REDRAW_NEXT. - * - LCDVIEW_REDRAW_NOW to draw now (including remaining stripes). - * - LCDVIEW_CALL_REDRAW_NEXT to draw now and get LCDVIEW_REDRAW_NOW on the next loop. - * - LCDVIEW_CALL_NO_REDRAW to draw now and get LCDVIEW_NONE on the next loop. - * - NOTE: For graphical displays menu handlers may be called 2 or more times per loop, - * so don't change lcdDrawUpdate without considering this. - * - * After the menu handler callback runs (or not): - * - Clear the LCD if lcdDrawUpdate == LCDVIEW_CLEAR_CALL_REDRAW - * - Update lcdDrawUpdate for the next loop (i.e., move one state down, usually) - * - * This function is only called from the main thread. - */ - -LCDViewAction MarlinUI::lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; -millis_t next_lcd_update_ms; -#if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS - millis_t MarlinUI::return_to_status_ms = 0; -#endif - -inline bool can_encode() { - return !BUTTON_PRESSED(ENC_EN); // Update encoder only when ENC_EN is not LOW (pressed) -} - -void MarlinUI::update() { - - static uint16_t max_display_update_time = 0; - millis_t ms = millis(); - - #if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS > 0 - #define RESET_STATUS_TIMEOUT() (return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS) - #else - #define RESET_STATUS_TIMEOUT() NOOP - #endif - - #ifdef LED_BACKLIGHT_TIMEOUT - leds.update_timeout(powersupply_on); - #endif - - #if HAS_LCD_MENU - - // Handle any queued Move Axis motion - manual_move.task(); - - // Update button states for button_pressed(), etc. - // If the state changes the next update may be delayed 300-500ms. - update_buttons(); - - // If the action button is pressed... - static bool wait_for_unclick; // = false - - auto do_click = [&]{ - wait_for_unclick = true; // - Set debounce flag to ignore continuous clicks - lcd_clicked = !wait_for_user; // - Keep the click if not waiting for a user-click - wait_for_user = false; // - Any click clears wait for user - quick_feedback(); // - Always make a click sound - }; - - #if HAS_TOUCH_BUTTONS - if (touch_buttons) { - RESET_STATUS_TIMEOUT(); - if (touch_buttons & (EN_A | EN_B)) { // Menu arrows, in priority - if (ELAPSED(ms, next_button_update_ms)) { - encoderDiff = (ENCODER_STEPS_PER_MENU_ITEM) * epps * encoderDirection; - if (touch_buttons & EN_A) encoderDiff *= -1; - TERN_(AUTO_BED_LEVELING_UBL, external_encoder()); - next_button_update_ms = ms + repeat_delay; // Assume the repeat delay - if (!wait_for_unclick) { - next_button_update_ms += 250; // Longer delay on first press - wait_for_unclick = true; // Avoid Back/Select click while repeating - chirp(); - } + for (;;) { + p = get_utf8_value_cb(p, cb_read_byte, &ch); + if (!ch) break; + lcd_put_wchar(ch); + col++; + if (col >= LCD_WIDTH) _newline(); } } - else if (!wait_for_unclick && (buttons & EN_C)) // OK button, if not waiting for a debounce release: - do_click(); } - // keep wait_for_unclick value - #endif - if (!touch_buttons) { - // Integrated LCD click handling via button_pressed - if (!external_control && button_pressed()) { - if (!wait_for_unclick) do_click(); // Handle the click + void MarlinUI::draw_select_screen_prompt(PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { + const uint8_t plen = utf8_strlen_P(pref), slen = suff ? utf8_strlen_P(suff) : 0; + uint8_t col = 0, row = 0; + if (!string && plen + slen <= LCD_WIDTH) { + col = (LCD_WIDTH - plen - slen) / 2; + row = LCD_HEIGHT > 3 ? 1 : 0; + } + wrap_string_P(col, row, pref, true); + if (string) { + if (col) { col = 0; row++; } // Move to the start of the next line + wrap_string(col, row, string); + } + if (suff) wrap_string_P(col, row, suff); } - else - wait_for_unclick = false; - } - if (LCD_BACK_CLICKED()) { - quick_feedback(); - goto_previous_screen(); - } + #endif // !HAS_GRAPHICAL_TFT #endif // HAS_LCD_MENU - if (ELAPSED(ms, next_lcd_update_ms) || TERN0(HAS_MARLINUI_U8GLIB, drawing_screen)) { + void MarlinUI::init() { - next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL; + init_lcd(); - #if HAS_TOUCH_BUTTONS + #if HAS_DIGITAL_BUTTONS + #if BUTTON_EXISTS(EN1) + SET_INPUT_PULLUP(BTN_EN1); + #endif + #if BUTTON_EXISTS(EN2) + SET_INPUT_PULLUP(BTN_EN2); + #endif + #if BUTTON_EXISTS(ENC) + SET_INPUT_PULLUP(BTN_ENC); + #endif + #if BUTTON_EXISTS(ENC_EN) + SET_INPUT_PULLUP(BTN_ENC_EN); + #endif + #if BUTTON_EXISTS(BACK) + SET_INPUT_PULLUP(BTN_BACK); + #endif + #if BUTTON_EXISTS(UP) + SET_INPUT(BTN_UP); + #endif + #if BUTTON_EXISTS(DWN) + SET_INPUT(BTN_DWN); + #endif + #if BUTTON_EXISTS(LFT) + SET_INPUT(BTN_LFT); + #endif + #if BUTTON_EXISTS(RT) + SET_INPUT(BTN_RT); + #endif + #endif - if (on_status_screen()) next_lcd_update_ms += (LCD_UPDATE_INTERVAL) * 2; + #if HAS_SHIFT_ENCODER - TERN_(HAS_ENCODER_ACTION, touch_buttons = touch.read_buttons()); + #if ENABLED(SR_LCD_2W_NL) // Non latching 2 wire shift register + + SET_OUTPUT(SR_DATA_PIN); + SET_OUTPUT(SR_CLK_PIN); + + #elif PIN_EXISTS(SHIFT_CLK) + + SET_OUTPUT(SHIFT_CLK_PIN); + OUT_WRITE(SHIFT_LD_PIN, HIGH); + #if PIN_EXISTS(SHIFT_EN) + OUT_WRITE(SHIFT_EN_PIN, LOW); + #endif + SET_INPUT_PULLUP(SHIFT_OUT_PIN); + + #endif + + #endif // HAS_SHIFT_ENCODER + + #if BOTH(HAS_ENCODER_ACTION, HAS_SLOW_BUTTONS) + slow_buttons = 0; + #endif + + update_buttons(); + + TERN_(HAS_ENCODER_ACTION, encoderDiff = 0); + } + + bool MarlinUI::get_blink() { + static uint8_t blink = 0; + static millis_t next_blink_ms = 0; + millis_t ms = millis(); + if (ELAPSED(ms, next_blink_ms)) { + blink ^= 0xFF; + next_blink_ms = ms + 1000 - (LCD_UPDATE_INTERVAL) / 2; + } + return blink != 0; + } + + //////////////////////////////////////////// + ///////////// Keypad Handling ////////////// + //////////////////////////////////////////// + + #if IS_RRW_KEYPAD && HAS_ENCODER_ACTION + + volatile uint8_t MarlinUI::keypad_buttons; + + #if HAS_LCD_MENU && !HAS_ADC_BUTTONS + + void lcd_move_x(); + void lcd_move_y(); + void lcd_move_z(); + + void _reprapworld_keypad_move(const AxisEnum axis, const int16_t dir) { + ui.manual_move.menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP; + ui.encoderPosition = dir; + switch (axis) { + case X_AXIS: lcd_move_x(); break; + case Y_AXIS: lcd_move_y(); break; + case Z_AXIS: lcd_move_z(); + default: break; + } + } #endif - TERN_(LCD_HAS_STATUS_INDICATORS, update_indicators()); + bool MarlinUI::handle_keypad() { - #if HAS_ENCODER_ACTION + #if HAS_ADC_BUTTONS - TERN_(HAS_SLOW_BUTTONS, slow_buttons = read_slow_buttons()); // Buttons that take too long to read in interrupt context - - if (TERN0(IS_RRW_KEYPAD, handle_keypad())) - RESET_STATUS_TIMEOUT(); - - uint8_t abs_diff = ABS(encoderDiff); - - #if ENCODER_PULSES_PER_STEP > 1 - // When reversing the encoder direction, a movement step can be missed because - // encoderDiff has a non-zero residual value, making the controller unresponsive. - // The fix clears the residual value when the encoder is idle. - // Also check if past half the threshold to compensate for missed single steps. - static int8_t lastEncoderDiff; - - // Timeout? No decoder change since last check. 10 or 20 times per second. - if (encoderDiff == lastEncoderDiff && abs_diff <= epps / 2) // Same direction & size but not over a half-step? - encoderDiff = 0; // Clear residual pulses. - else if (WITHIN(abs_diff, epps / 2 + 1, epps - 1)) { // Past half of threshold? - abs_diff = epps; // Treat as a full step size - encoderDiff = (encoderDiff < 0 ? -1 : 1) * abs_diff; // ...in the spin direction. + #define ADC_MIN_KEY_DELAY 100 + if (keypad_buttons) { + #if HAS_ENCODER_ACTION + refresh(LCDVIEW_REDRAW_NOW); + #if HAS_LCD_MENU + if (encoderDirection == -(ENCODERBASE)) { // HAS_ADC_BUTTONS forces REVERSE_MENU_DIRECTION, so this indicates menu navigation + if (RRK(EN_KEYPAD_UP)) encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; + else if (RRK(EN_KEYPAD_DOWN)) encoderPosition -= ENCODER_STEPS_PER_MENU_ITEM; + else if (RRK(EN_KEYPAD_LEFT)) { MenuItem_back::action(); quick_feedback(); } + else if (RRK(EN_KEYPAD_RIGHT)) { return_to_status(); quick_feedback(); } + } + else + #endif + { + #if HAS_LCD_MENU + if (RRK(EN_KEYPAD_UP)) encoderPosition -= epps; + else if (RRK(EN_KEYPAD_DOWN)) encoderPosition += epps; + else if (RRK(EN_KEYPAD_LEFT)) { MenuItem_back::action(); quick_feedback(); } + else if (RRK(EN_KEYPAD_RIGHT)) encoderPosition = 0; + #else + if (RRK(EN_KEYPAD_UP) || RRK(EN_KEYPAD_LEFT)) encoderPosition -= epps; + else if (RRK(EN_KEYPAD_DOWN) || RRK(EN_KEYPAD_RIGHT)) encoderPosition += epps; + #endif + } + #endif + next_button_update_ms = millis() + ADC_MIN_KEY_DELAY; + return true; } - lastEncoderDiff = encoderDiff; + + #else // !HAS_ADC_BUTTONS + + static uint8_t keypad_debounce = 0; + + if (!RRK( EN_KEYPAD_F1 | EN_KEYPAD_F2 + | EN_KEYPAD_F3 | EN_KEYPAD_DOWN + | EN_KEYPAD_RIGHT | EN_KEYPAD_MIDDLE + | EN_KEYPAD_UP | EN_KEYPAD_LEFT ) + ) { + if (keypad_debounce > 0) keypad_debounce--; + } + else if (!keypad_debounce) { + keypad_debounce = 2; + + const bool homed = all_axes_homed(); + + #if HAS_LCD_MENU + + if (RRK(EN_KEYPAD_MIDDLE)) goto_screen(menu_move); + + #if NONE(DELTA, Z_HOME_TO_MAX) + if (RRK(EN_KEYPAD_F2)) _reprapworld_keypad_move(Z_AXIS, 1); + #endif + + if (homed) { + #if EITHER(DELTA, Z_HOME_TO_MAX) + if (RRK(EN_KEYPAD_F2)) _reprapworld_keypad_move(Z_AXIS, 1); + #endif + if (RRK(EN_KEYPAD_F3)) _reprapworld_keypad_move(Z_AXIS, -1); + if (RRK(EN_KEYPAD_LEFT)) _reprapworld_keypad_move(X_AXIS, -1); + if (RRK(EN_KEYPAD_RIGHT)) _reprapworld_keypad_move(X_AXIS, 1); + if (RRK(EN_KEYPAD_DOWN)) _reprapworld_keypad_move(Y_AXIS, 1); + if (RRK(EN_KEYPAD_UP)) _reprapworld_keypad_move(Y_AXIS, -1); + } + + #endif // HAS_LCD_MENU + + if (!homed && RRK(EN_KEYPAD_F1)) queue.inject_P(G28_STR); + return true; + } + + #endif // !HAS_ADC_BUTTONS + + return false; + } + + #endif // IS_RRW_KEYPAD && HAS_ENCODER_ACTION + + /** + * Status Screen + * + * This is very display-dependent, so the lcd implementation draws this. + */ + + #if BASIC_PROGRESS_BAR + millis_t MarlinUI::progress_bar_ms; // = 0 + #if PROGRESS_MSG_EXPIRE > 0 + millis_t MarlinUI::expire_status_ms; // = 0 + #endif + #endif + + void MarlinUI::status_screen() { + + TERN_(HAS_LCD_MENU, ENCODER_RATE_MULTIPLY(false)); + + #if BASIC_PROGRESS_BAR + + // + // HD44780 implements the following message blinking and + // message expiration because Status Line and Progress Bar + // share the same line on the display. + // + + #if DISABLED(PROGRESS_MSG_ONCE) || (PROGRESS_MSG_EXPIRE > 0) + #define GOT_MS + const millis_t ms = millis(); #endif - const bool encoderPastThreshold = (abs_diff >= epps); - if (encoderPastThreshold || lcd_clicked) { - if (encoderPastThreshold && TERN1(IS_TFTGLCD_PANEL, !external_control)) { + // If the message will blink rather than expire... + #if DISABLED(PROGRESS_MSG_ONCE) + if (ELAPSED(ms, progress_bar_ms + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME)) + progress_bar_ms = ms; + #endif - #if BOTH(HAS_LCD_MENU, ENCODER_RATE_MULTIPLIER) + #if PROGRESS_MSG_EXPIRE > 0 - int32_t encoderMultiplier = 1; + // Handle message expire + if (expire_status_ms) { - if (encoderRateMultiplierEnabled) { - const float encoderMovementSteps = float(abs_diff) / epps; - - if (lastEncoderMovementMillis) { - // Note that the rate is always calculated between two passes through the - // loop and that the abs of the encoderDiff value is tracked. - const float encoderStepRate = encoderMovementSteps / float(ms - lastEncoderMovementMillis) * 1000; - - if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100; - else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10; - - // Enable to output the encoder steps per second value - //#define ENCODER_RATE_MULTIPLIER_DEBUG - #if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG) - SERIAL_ECHO_START(); - SERIAL_ECHOPAIR("Enc Step Rate: ", encoderStepRate); - SERIAL_ECHOPAIR(" Multiplier: ", encoderMultiplier); - SERIAL_ECHOPAIR(" ENCODER_10X_STEPS_PER_SEC: ", ENCODER_10X_STEPS_PER_SEC); - SERIAL_ECHOPAIR(" ENCODER_100X_STEPS_PER_SEC: ", ENCODER_100X_STEPS_PER_SEC); - SERIAL_EOL(); - #endif - } - - lastEncoderMovementMillis = ms; - } // encoderRateMultiplierEnabled - - #else - - constexpr int32_t encoderMultiplier = 1; - - #endif // ENCODER_RATE_MULTIPLIER - - if (can_encode()) encoderPosition += (encoderDiff * encoderMultiplier) / epps; - - encoderDiff = 0; + // Expire the message if a job is active and the bar has ticks + if (get_progress_percent() > 2 && !print_job_timer.isPaused()) { + if (ELAPSED(ms, expire_status_ms)) { + status_message[0] = '\0'; + expire_status_ms = 0; + } + } + else { + // Defer message expiration before bar appears + // and during any pause (not just SD) + expire_status_ms += LCD_UPDATE_INTERVAL; + } } - RESET_STATUS_TIMEOUT(); + #endif // PROGRESS_MSG_EXPIRE - refresh(LCDVIEW_REDRAW_NOW); + #endif // BASIC_PROGRESS_BAR - #ifdef LED_BACKLIGHT_TIMEOUT - if (!powersupply_on) leds.reset_timeout(ms); + #if HAS_LCD_MENU + if (use_click()) { + #if BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) + next_filament_display = millis() + 5000UL; // Show status message for 5s + #endif + goto_screen(menu_main); + #if DISABLED(NO_LCD_REINIT) + init_lcd(); // May revive the LCD if static electricity killed it + #endif + return; + } + + #endif + + #if ENABLED(ULTIPANEL_FEEDMULTIPLY) + + const int16_t old_frm = feedrate_percentage; + int16_t new_frm = old_frm + int16_t(encoderPosition); + + // Dead zone at 100% feedrate + if (old_frm == 100) { + if (int16_t(encoderPosition) > ENCODER_FEEDRATE_DEADZONE) + new_frm -= ENCODER_FEEDRATE_DEADZONE; + else if (int16_t(encoderPosition) < -(ENCODER_FEEDRATE_DEADZONE)) + new_frm += ENCODER_FEEDRATE_DEADZONE; + else + new_frm = old_frm; + } + else if ((old_frm < 100 && new_frm > 100) || (old_frm > 100 && new_frm < 100)) + new_frm = 100; + + LIMIT(new_frm, 10, 999); + + if (old_frm != new_frm) { + feedrate_percentage = new_frm; + encoderPosition = 0; + #if BOTH(HAS_BUZZER, BEEP_ON_FEEDRATE_CHANGE) + static millis_t next_beep; + #ifndef GOT_MS + const millis_t ms = millis(); + #endif + if (ELAPSED(ms, next_beep)) { + buzz(FEEDRATE_CHANGE_BEEP_DURATION, FEEDRATE_CHANGE_BEEP_FREQUENCY); + next_beep = ms + 500UL; + } #endif } + #endif // ULTIPANEL_FEEDMULTIPLY + + draw_status_screen(); + } + + void MarlinUI::kill_screen(PGM_P lcd_error, PGM_P lcd_component) { + init(); + status_printf_P(1, PSTR(S_FMT ": " S_FMT), lcd_error, lcd_component); + TERN_(HAS_LCD_MENU, return_to_status()); + + // RED ALERT. RED ALERT. + #ifdef LED_BACKLIGHT_TIMEOUT + leds.set_color(LEDColorRed()); + #ifdef NEOPIXEL_BKGD_INDEX_FIRST + neo.set_background_color(255, 0, 0, 0); + neo.show(); + #endif #endif - // This runs every ~100ms when idling often enough. - // Instead of tracking changes just redraw the Status Screen once per second. - if (on_status_screen() && !lcd_status_update_delay--) { - lcd_status_update_delay = TERN(HAS_MARLINUI_U8GLIB, 12, 9); - if (max_display_update_time) max_display_update_time--; // Be sure never go to a very big number - refresh(LCDVIEW_REDRAW_NOW); + draw_kill_screen(); + } + + void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) { + + TERN_(HAS_LCD_MENU, refresh()); + + #if HAS_ENCODER_ACTION + if (clear_buttons) buttons = 0; + next_button_update_ms = millis() + 500; + #else + UNUSED(clear_buttons); + #endif + + #if HAS_CHIRP + chirp(); // Buzz and wait. Is the delay needed for buttons to settle? + #if BOTH(HAS_LCD_MENU, USE_BEEPER) + for (int8_t i = 5; i--;) { buzzer.tick(); delay(2); } + #elif HAS_LCD_MENU + delay(10); + #endif + #endif + } + + //////////////////////////////////////////// + /////////////// Manual Move //////////////// + //////////////////////////////////////////// + + #if HAS_LCD_MENU + + ManualMove MarlinUI::manual_move{}; + + millis_t ManualMove::start_time = 0; + float ManualMove::menu_scale = 1; + #if IS_KINEMATIC + float ManualMove::offset = 0; + xyze_pos_t ManualMove::all_axes_destination = { 0 }; + bool ManualMove::processing = false; + #endif + #if MULTI_E_MANUAL + int8_t ManualMove::e_index = 0; + #endif + AxisEnum ManualMove::axis = NO_AXIS_ENUM; + + /** + * If a manual move has been posted and its time has arrived, and if the planner + * has a space for it, then add a linear move to current_position the planner. + * + * If any manual move needs to be interrupted, make sure to force a manual move + * by setting manual_move.start_time to millis() after updating current_position. + * + * To post a manual move: + * - Update current_position to the new place you want to go. + * - Set manual_move.axis to an axis like X_AXIS. Use ALL_AXES_ENUM for diagonal moves. + * - Set manual_move.start_time to a point in the future (in ms) when the move should be done. + * + * For kinematic machines: + * - Set manual_move.offset to modify one axis and post the move. + * This is used to achieve more rapid stepping on kinematic machines. + * + * Currently used by the _lcd_move_xyz function in menu_motion.cpp + * and the ubl_map_move_to_xy funtion in menu_ubl.cpp. + */ + void ManualMove::task() { + + if (processing) return; // Prevent re-entry from idle() calls + + // Add a manual move to the queue? + if (axis != NO_AXIS_ENUM && ELAPSED(millis(), start_time) && !planner.is_full()) { + + const feedRate_t fr_mm_s = (axis <= LOGICAL_AXES) ? manual_feedrate_mm_s[axis] : XY_PROBE_FEEDRATE_MM_S; + + #if IS_KINEMATIC + + #if HAS_MULTI_EXTRUDER + REMEMBER(ae, active_extruder); + #if MULTI_E_MANUAL + if (axis == E_AXIS) active_extruder = e_index; + #endif + #endif + + // Apply a linear offset to a single axis + if (axis == ALL_AXES_ENUM) + destination = all_axes_destination; + else if (axis <= XYZE) { + destination = current_position; + destination[axis] += offset; + } + + // Reset for the next move + offset = 0; + axis = NO_AXIS_ENUM; + + // DELTA and SCARA machines use segmented moves, which could fill the planner during the call to + // move_to_destination. This will cause idle() to be called, which can then call this function while the + // previous invocation is being blocked. Modifications to offset shouldn't be made while + // processing is true or the planner will get out of sync. + processing = true; + prepare_internal_move_to_destination(fr_mm_s); // will set current_position from destination + processing = false; + + #else + + // For Cartesian / Core motion simply move to the current_position + planner.buffer_line(current_position, fr_mm_s, + TERN_(MULTI_E_MANUAL, axis == E_AXIS ? e_index :) active_extruder + ); + + //SERIAL_ECHOLNPAIR("Add planner.move with Axis ", AS_CHAR(axis_codes[axis]), " at FR ", fr_mm_s); + + axis = NO_AXIS_ENUM; + + #endif + } } - #if BOTH(HAS_LCD_MENU, SCROLL_LONG_FILENAMES) - // If scrolling of long file names is enabled and we are in the sd card menu, - // cause a refresh to occur until all the text has scrolled into view. - if (currentScreen == menu_media && !lcd_status_update_delay--) { - lcd_status_update_delay = ++filename_scroll_pos >= filename_scroll_max ? 12 : 4; // Long delay at end and start - if (filename_scroll_pos > filename_scroll_max) filename_scroll_pos = 0; - refresh(LCDVIEW_REDRAW_NOW); - RESET_STATUS_TIMEOUT(); + // + // Tell ui.update() to start a move to current_position after a short delay. + // + void ManualMove::soon(const AxisEnum move_axis + OPTARG(MULTI_E_MANUAL, const int8_t eindex/*=active_extruder*/) + ) { + TERN_(MULTI_E_MANUAL, if (move_axis == E_AXIS) e_index = eindex); + start_time = millis() + (menu_scale < 0.99f ? 0UL : 250UL); // delay for bigger moves + axis = move_axis; + //SERIAL_ECHOLNPAIR("Post Move with Axis ", AS_CHAR(axis_codes[axis]), " soon."); + } + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + void MarlinUI::external_encoder() { + if (external_control && encoderDiff) { + ubl.encoder_diff += encoderDiff; // Encoder for UBL G29 mesh editing + encoderDiff = 0; // Hide encoder events from the screen handler + refresh(LCDVIEW_REDRAW_NOW); // ...but keep the refresh. + } } + #endif - // Then we want to use only 50% of the time - const uint16_t bbr2 = planner.block_buffer_runtime() >> 1; + #endif // HAS_LCD_MENU - if ((should_draw() || drawing_screen) && (!bbr2 || bbr2 > max_display_update_time)) { + /** + * Update the LCD, read encoder buttons, etc. + * - Read button states + * - Check the SD Card slot state + * - Act on RepRap World keypad input + * - Update the encoder position + * - Apply acceleration to the encoder position + * - Do refresh(LCDVIEW_CALL_REDRAW_NOW) on controller events + * - Reset the Info Screen timeout if there's any input + * - Update status indicators, if any + * + * Run the current LCD menu handler callback function: + * - Call the handler only if lcdDrawUpdate != LCDVIEW_NONE + * - Before calling the handler, LCDVIEW_CALL_NO_REDRAW => LCDVIEW_NONE + * - Call the menu handler. Menu handlers should do the following: + * - If a value changes, set lcdDrawUpdate to LCDVIEW_REDRAW_NOW and draw the value + * (Encoder events automatically set lcdDrawUpdate for you.) + * - if (should_draw()) { redraw } + * - Before exiting the handler set lcdDrawUpdate to: + * - LCDVIEW_CLEAR_CALL_REDRAW to clear screen and set LCDVIEW_CALL_REDRAW_NEXT. + * - LCDVIEW_REDRAW_NOW to draw now (including remaining stripes). + * - LCDVIEW_CALL_REDRAW_NEXT to draw now and get LCDVIEW_REDRAW_NOW on the next loop. + * - LCDVIEW_CALL_NO_REDRAW to draw now and get LCDVIEW_NONE on the next loop. + * - NOTE: For graphical displays menu handlers may be called 2 or more times per loop, + * so don't change lcdDrawUpdate without considering this. + * + * After the menu handler callback runs (or not): + * - Clear the LCD if lcdDrawUpdate == LCDVIEW_CLEAR_CALL_REDRAW + * - Update lcdDrawUpdate for the next loop (i.e., move one state down, usually) + * + * This function is only called from the main thread. + */ + + LCDViewAction MarlinUI::lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; + millis_t next_lcd_update_ms; + + inline bool can_encode() { + return !BUTTON_PRESSED(ENC_EN); // Update encoder only when ENC_EN is not LOW (pressed) + } + + void MarlinUI::update() { + + static uint16_t max_display_update_time = 0; + millis_t ms = millis(); + + #ifdef LED_BACKLIGHT_TIMEOUT + leds.update_timeout(powersupply_on); + #endif + + #if HAS_LCD_MENU + + // Handle any queued Move Axis motion + manual_move.task(); + + // Update button states for button_pressed(), etc. + // If the state changes the next update may be delayed 300-500ms. + update_buttons(); + + // If the action button is pressed... + static bool wait_for_unclick; // = false + + auto do_click = [&]{ + wait_for_unclick = true; // - Set debounce flag to ignore continuous clicks + lcd_clicked = !wait_for_user; // - Keep the click if not waiting for a user-click + wait_for_user = false; // - Any click clears wait for user + quick_feedback(); // - Always make a click sound + }; + + #if HAS_TOUCH_BUTTONS + if (touch_buttons) { + reset_status_timeout(ms); + if (touch_buttons & (EN_A | EN_B)) { // Menu arrows, in priority + if (ELAPSED(ms, next_button_update_ms)) { + encoderDiff = (ENCODER_STEPS_PER_MENU_ITEM) * epps * encoderDirection; + if (touch_buttons & EN_A) encoderDiff *= -1; + TERN_(AUTO_BED_LEVELING_UBL, external_encoder()); + next_button_update_ms = ms + repeat_delay; // Assume the repeat delay + if (!wait_for_unclick) { + next_button_update_ms += 250; // Longer delay on first press + wait_for_unclick = true; // Avoid Back/Select click while repeating + chirp(); + } + } + } + else if (!wait_for_unclick && (buttons & EN_C)) // OK button, if not waiting for a debounce release: + do_click(); + } + // keep wait_for_unclick value + #endif + + if (!touch_buttons) { + // Integrated LCD click handling via button_pressed + if (!external_control && button_pressed()) { + if (!wait_for_unclick) do_click(); // Handle the click + } + else + wait_for_unclick = false; + } + + if (LCD_BACK_CLICKED()) { + quick_feedback(); + goto_previous_screen(); + } + + #endif // HAS_LCD_MENU + + if (ELAPSED(ms, next_lcd_update_ms) || TERN0(HAS_MARLINUI_U8GLIB, drawing_screen)) { + + next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL; + + #if HAS_TOUCH_BUTTONS + + if (on_status_screen()) next_lcd_update_ms += (LCD_UPDATE_INTERVAL) * 2; + + TERN_(HAS_ENCODER_ACTION, touch_buttons = touch.read_buttons()); + + #endif + + TERN_(LCD_HAS_STATUS_INDICATORS, update_indicators()); + + #if HAS_ENCODER_ACTION + + TERN_(HAS_SLOW_BUTTONS, slow_buttons = read_slow_buttons()); // Buttons that take too long to read in interrupt context + + if (TERN0(IS_RRW_KEYPAD, handle_keypad())) + reset_status_timeout(ms); + + uint8_t abs_diff = ABS(encoderDiff); + + #if ENCODER_PULSES_PER_STEP > 1 + // When reversing the encoder direction, a movement step can be missed because + // encoderDiff has a non-zero residual value, making the controller unresponsive. + // The fix clears the residual value when the encoder is idle. + // Also check if past half the threshold to compensate for missed single steps. + static int8_t lastEncoderDiff; + + // Timeout? No decoder change since last check. 10 or 20 times per second. + if (encoderDiff == lastEncoderDiff && abs_diff <= epps / 2) // Same direction & size but not over a half-step? + encoderDiff = 0; // Clear residual pulses. + else if (WITHIN(abs_diff, epps / 2 + 1, epps - 1)) { // Past half of threshold? + abs_diff = epps; // Treat as a full step size + encoderDiff = (encoderDiff < 0 ? -1 : 1) * abs_diff; // ...in the spin direction. + } + lastEncoderDiff = encoderDiff; + #endif + + const bool encoderPastThreshold = (abs_diff >= epps); + if (encoderPastThreshold || lcd_clicked) { + if (encoderPastThreshold && TERN1(IS_TFTGLCD_PANEL, !external_control)) { + + #if BOTH(HAS_LCD_MENU, ENCODER_RATE_MULTIPLIER) + + int32_t encoderMultiplier = 1; + + if (encoderRateMultiplierEnabled) { + const float encoderMovementSteps = float(abs_diff) / epps; + + if (lastEncoderMovementMillis) { + // Note that the rate is always calculated between two passes through the + // loop and that the abs of the encoderDiff value is tracked. + const float encoderStepRate = encoderMovementSteps / float(ms - lastEncoderMovementMillis) * 1000; + + if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100; + else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10; + + // Enable to output the encoder steps per second value + //#define ENCODER_RATE_MULTIPLIER_DEBUG + #if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG) + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR("Enc Step Rate: ", encoderStepRate); + SERIAL_ECHOPAIR(" Multiplier: ", encoderMultiplier); + SERIAL_ECHOPAIR(" ENCODER_10X_STEPS_PER_SEC: ", ENCODER_10X_STEPS_PER_SEC); + SERIAL_ECHOPAIR(" ENCODER_100X_STEPS_PER_SEC: ", ENCODER_100X_STEPS_PER_SEC); + SERIAL_EOL(); + #endif + } + + lastEncoderMovementMillis = ms; + } // encoderRateMultiplierEnabled + + #else + + constexpr int32_t encoderMultiplier = 1; + + #endif // ENCODER_RATE_MULTIPLIER + + if (can_encode()) encoderPosition += (encoderDiff * encoderMultiplier) / epps; + + encoderDiff = 0; + } + + reset_status_timeout(ms); + + refresh(LCDVIEW_REDRAW_NOW); + + #ifdef LED_BACKLIGHT_TIMEOUT + if (!powersupply_on) leds.reset_timeout(ms); + #endif + } + + #endif + + // This runs every ~100ms when idling often enough. + // Instead of tracking changes just redraw the Status Screen once per second. + if (on_status_screen() && !lcd_status_update_delay--) { + lcd_status_update_delay = TERN(HAS_MARLINUI_U8GLIB, 12, 9); + if (max_display_update_time) max_display_update_time--; // Be sure never go to a very big number + refresh(LCDVIEW_REDRAW_NOW); + } + + #if BOTH(HAS_LCD_MENU, SCROLL_LONG_FILENAMES) + // If scrolling of long file names is enabled and we are in the sd card menu, + // cause a refresh to occur until all the text has scrolled into view. + if (currentScreen == menu_media && !lcd_status_update_delay--) { + lcd_status_update_delay = ++filename_scroll_pos >= filename_scroll_max ? 12 : 4; // Long delay at end and start + if (filename_scroll_pos > filename_scroll_max) filename_scroll_pos = 0; + refresh(LCDVIEW_REDRAW_NOW); + reset_status_timeout(ms); + } + #endif + + // Then we want to use only 50% of the time + const uint16_t bbr2 = planner.block_buffer_runtime() >> 1; + + if ((should_draw() || drawing_screen) && (!bbr2 || bbr2 > max_display_update_time)) { + + // Change state of drawing flag between screen updates + if (!drawing_screen) switch (lcdDrawUpdate) { + case LCDVIEW_CALL_NO_REDRAW: + refresh(LCDVIEW_NONE); + break; + case LCDVIEW_CLEAR_CALL_REDRAW: + case LCDVIEW_CALL_REDRAW_NEXT: + refresh(LCDVIEW_REDRAW_NOW); + case LCDVIEW_REDRAW_NOW: // set above, or by a handler through LCDVIEW_CALL_REDRAW_NEXT + case LCDVIEW_NONE: + break; + } // switch + + TERN_(HAS_ADC_BUTTONS, keypad_buttons = 0); + + #if HAS_MARLINUI_U8GLIB + + #if ENABLED(LIGHTWEIGHT_UI) + const bool in_status = on_status_screen(), + do_u8g_loop = !in_status; + lcd_in_status(in_status); + if (in_status) status_screen(); + #else + constexpr bool do_u8g_loop = true; + #endif + + if (do_u8g_loop) { + if (!drawing_screen) { // If not already drawing pages + u8g.firstPage(); // Start the first page + drawing_screen = first_page = true; // Flag as drawing pages + } + set_font(FONT_MENU); // Setup font for every page draw + u8g.setColorIndex(1); // And reset the color + run_current_screen(); // Draw and process the current screen + first_page = false; + + // The screen handler can clear drawing_screen for an action that changes the screen. + // If still drawing and there's another page, update max-time and return now. + // The nextPage will already be set up on the next call. + if (drawing_screen && (drawing_screen = u8g.nextPage())) { + if (on_status_screen()) + NOLESS(max_display_update_time, millis() - ms); + return; + } + } + + #else + + run_current_screen(); + + #endif + + TERN_(HAS_LCD_MENU, lcd_clicked = false); + + // Keeping track of the longest time for an individual LCD update. + // Used to do screen throttling when the planner starts to fill up. + if (on_status_screen()) + NOLESS(max_display_update_time, millis() - ms); + } + + #if SCREENS_CAN_TIME_OUT + // Return to Status Screen after a timeout + if (on_status_screen() || defer_return_to_status) + reset_status_timeout(ms); + else if (ELAPSED(ms, return_to_status_ms)) + return_to_status(); + #endif // Change state of drawing flag between screen updates if (!drawing_screen) switch (lcdDrawUpdate) { - case LCDVIEW_CALL_NO_REDRAW: - refresh(LCDVIEW_NONE); - break; case LCDVIEW_CLEAR_CALL_REDRAW: - case LCDVIEW_CALL_REDRAW_NEXT: - refresh(LCDVIEW_REDRAW_NOW); - case LCDVIEW_REDRAW_NOW: // set above, or by a handler through LCDVIEW_CALL_REDRAW_NEXT + clear_lcd(); break; + case LCDVIEW_REDRAW_NOW: + refresh(LCDVIEW_NONE); case LCDVIEW_NONE: - break; + case LCDVIEW_CALL_REDRAW_NEXT: + case LCDVIEW_CALL_NO_REDRAW: + default: break; } // switch - TERN_(HAS_ADC_BUTTONS, keypad_buttons = 0); + } // ELAPSED(ms, next_lcd_update_ms) - #if HAS_MARLINUI_U8GLIB + TERN_(HAS_GRAPHICAL_TFT, tft_idle()); + } - #if ENABLED(LIGHTWEIGHT_UI) - const bool in_status = on_status_screen(), - do_u8g_loop = !in_status; - lcd_in_status(in_status); - if (in_status) status_screen(); - #else - constexpr bool do_u8g_loop = true; - #endif + #if HAS_ADC_BUTTONS - if (do_u8g_loop) { - if (!drawing_screen) { // If not already drawing pages - u8g.firstPage(); // Start the first page - drawing_screen = first_page = true; // Flag as drawing pages - } - set_font(FONT_MENU); // Setup font for every page draw - u8g.setColorIndex(1); // And reset the color - run_current_screen(); // Draw and process the current screen - first_page = false; + typedef struct { + uint16_t ADCKeyValueMin, ADCKeyValueMax; + uint8_t ADCKeyNo; + } _stADCKeypadTable_; - // The screen handler can clear drawing_screen for an action that changes the screen. - // If still drawing and there's another page, update max-time and return now. - // The nextPage will already be set up on the next call. - if (drawing_screen && (drawing_screen = u8g.nextPage())) { - if (on_status_screen()) - NOLESS(max_display_update_time, millis() - ms); - return; - } - } - - #else - - run_current_screen(); - - #endif - - TERN_(HAS_LCD_MENU, lcd_clicked = false); - - // Keeping track of the longest time for an individual LCD update. - // Used to do screen throttling when the planner starts to fill up. - if (on_status_screen()) - NOLESS(max_display_update_time, millis() - ms); - } - - #if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS > 0 - // Return to Status Screen after a timeout - if (on_status_screen() || defer_return_to_status) - RESET_STATUS_TIMEOUT(); - else if (ELAPSED(ms, return_to_status_ms)) - return_to_status(); + #ifndef ADC_BUTTONS_VALUE_SCALE + #define ADC_BUTTONS_VALUE_SCALE 1.0 // for the power voltage equal to the reference voltage + #endif + #ifndef ADC_BUTTONS_R_PULLUP + #define ADC_BUTTONS_R_PULLUP 4.7 // common pull-up resistor in the voltage divider + #endif + #ifndef ADC_BUTTONS_LEFT_R_PULLDOWN + #define ADC_BUTTONS_LEFT_R_PULLDOWN 0.47 // pull-down resistor for LEFT button voltage divider + #endif + #ifndef ADC_BUTTONS_RIGHT_R_PULLDOWN + #define ADC_BUTTONS_RIGHT_R_PULLDOWN 4.7 // pull-down resistor for RIGHT button voltage divider + #endif + #ifndef ADC_BUTTONS_UP_R_PULLDOWN + #define ADC_BUTTONS_UP_R_PULLDOWN 1.0 // pull-down resistor for UP button voltage divider + #endif + #ifndef ADC_BUTTONS_DOWN_R_PULLDOWN + #define ADC_BUTTONS_DOWN_R_PULLDOWN 10.0 // pull-down resistor for DOWN button voltage divider + #endif + #ifndef ADC_BUTTONS_MIDDLE_R_PULLDOWN + #define ADC_BUTTONS_MIDDLE_R_PULLDOWN 2.2 // pull-down resistor for MIDDLE button voltage divider #endif - // Change state of drawing flag between screen updates - if (!drawing_screen) switch (lcdDrawUpdate) { - case LCDVIEW_CLEAR_CALL_REDRAW: - clear_lcd(); break; - case LCDVIEW_REDRAW_NOW: - refresh(LCDVIEW_NONE); - case LCDVIEW_NONE: - case LCDVIEW_CALL_REDRAW_NEXT: - case LCDVIEW_CALL_NO_REDRAW: - default: break; - } // switch + // Calculate the ADC value for the voltage divider with specified pull-down resistor value + #define ADC_BUTTON_VALUE(r) int(HAL_ADC_RANGE * (ADC_BUTTONS_VALUE_SCALE) * r / (r + ADC_BUTTONS_R_PULLUP)) - } // ELAPSED(ms, next_lcd_update_ms) + static constexpr uint16_t adc_button_tolerance = HAL_ADC_RANGE * 25 / 1024, + adc_other_button = HAL_ADC_RANGE * 1000 / 1024; + static const _stADCKeypadTable_ stADCKeyTable[] PROGMEM = { + // VALUE_MIN, VALUE_MAX, KEY + { adc_other_button, HAL_ADC_RANGE, 1 + BLEN_KEYPAD_F1 }, // F1 + { adc_other_button, HAL_ADC_RANGE, 1 + BLEN_KEYPAD_F2 }, // F2 + { adc_other_button, HAL_ADC_RANGE, 1 + BLEN_KEYPAD_F3 }, // F3 + { ADC_BUTTON_VALUE(ADC_BUTTONS_LEFT_R_PULLDOWN) - adc_button_tolerance, + ADC_BUTTON_VALUE(ADC_BUTTONS_LEFT_R_PULLDOWN) + adc_button_tolerance, 1 + BLEN_KEYPAD_LEFT }, // LEFT ( 272 ... 472) + { ADC_BUTTON_VALUE(ADC_BUTTONS_RIGHT_R_PULLDOWN) - adc_button_tolerance, + ADC_BUTTON_VALUE(ADC_BUTTONS_RIGHT_R_PULLDOWN) + adc_button_tolerance, 1 + BLEN_KEYPAD_RIGHT }, // RIGHT (1948 ... 2148) + { ADC_BUTTON_VALUE(ADC_BUTTONS_UP_R_PULLDOWN) - adc_button_tolerance, + ADC_BUTTON_VALUE(ADC_BUTTONS_UP_R_PULLDOWN) + adc_button_tolerance, 1 + BLEN_KEYPAD_UP }, // UP ( 618 ... 818) + { ADC_BUTTON_VALUE(ADC_BUTTONS_DOWN_R_PULLDOWN) - adc_button_tolerance, + ADC_BUTTON_VALUE(ADC_BUTTONS_DOWN_R_PULLDOWN) + adc_button_tolerance, 1 + BLEN_KEYPAD_DOWN }, // DOWN (2686 ... 2886) + { ADC_BUTTON_VALUE(ADC_BUTTONS_MIDDLE_R_PULLDOWN) - adc_button_tolerance, + ADC_BUTTON_VALUE(ADC_BUTTONS_MIDDLE_R_PULLDOWN) + adc_button_tolerance, 1 + BLEN_KEYPAD_MIDDLE }, // ENTER (1205 ... 1405) + }; - TERN_(HAS_GRAPHICAL_TFT, tft_idle()); -} - -#if HAS_ADC_BUTTONS - - typedef struct { - uint16_t ADCKeyValueMin, ADCKeyValueMax; - uint8_t ADCKeyNo; - } _stADCKeypadTable_; - - #ifndef ADC_BUTTONS_VALUE_SCALE - #define ADC_BUTTONS_VALUE_SCALE 1.0 // for the power voltage equal to the reference voltage - #endif - #ifndef ADC_BUTTONS_R_PULLUP - #define ADC_BUTTONS_R_PULLUP 4.7 // common pull-up resistor in the voltage divider - #endif - #ifndef ADC_BUTTONS_LEFT_R_PULLDOWN - #define ADC_BUTTONS_LEFT_R_PULLDOWN 0.47 // pull-down resistor for LEFT button voltage divider - #endif - #ifndef ADC_BUTTONS_RIGHT_R_PULLDOWN - #define ADC_BUTTONS_RIGHT_R_PULLDOWN 4.7 // pull-down resistor for RIGHT button voltage divider - #endif - #ifndef ADC_BUTTONS_UP_R_PULLDOWN - #define ADC_BUTTONS_UP_R_PULLDOWN 1.0 // pull-down resistor for UP button voltage divider - #endif - #ifndef ADC_BUTTONS_DOWN_R_PULLDOWN - #define ADC_BUTTONS_DOWN_R_PULLDOWN 10.0 // pull-down resistor for DOWN button voltage divider - #endif - #ifndef ADC_BUTTONS_MIDDLE_R_PULLDOWN - #define ADC_BUTTONS_MIDDLE_R_PULLDOWN 2.2 // pull-down resistor for MIDDLE button voltage divider - #endif - - // Calculate the ADC value for the voltage divider with specified pull-down resistor value - #define ADC_BUTTON_VALUE(r) int(HAL_ADC_RANGE * (ADC_BUTTONS_VALUE_SCALE) * r / (r + ADC_BUTTONS_R_PULLUP)) - - static constexpr uint16_t adc_button_tolerance = HAL_ADC_RANGE * 25 / 1024, - adc_other_button = HAL_ADC_RANGE * 1000 / 1024; - static const _stADCKeypadTable_ stADCKeyTable[] PROGMEM = { - // VALUE_MIN, VALUE_MAX, KEY - { adc_other_button, HAL_ADC_RANGE, 1 + BLEN_KEYPAD_F1 }, // F1 - { adc_other_button, HAL_ADC_RANGE, 1 + BLEN_KEYPAD_F2 }, // F2 - { adc_other_button, HAL_ADC_RANGE, 1 + BLEN_KEYPAD_F3 }, // F3 - { ADC_BUTTON_VALUE(ADC_BUTTONS_LEFT_R_PULLDOWN) - adc_button_tolerance, - ADC_BUTTON_VALUE(ADC_BUTTONS_LEFT_R_PULLDOWN) + adc_button_tolerance, 1 + BLEN_KEYPAD_LEFT }, // LEFT ( 272 ... 472) - { ADC_BUTTON_VALUE(ADC_BUTTONS_RIGHT_R_PULLDOWN) - adc_button_tolerance, - ADC_BUTTON_VALUE(ADC_BUTTONS_RIGHT_R_PULLDOWN) + adc_button_tolerance, 1 + BLEN_KEYPAD_RIGHT }, // RIGHT (1948 ... 2148) - { ADC_BUTTON_VALUE(ADC_BUTTONS_UP_R_PULLDOWN) - adc_button_tolerance, - ADC_BUTTON_VALUE(ADC_BUTTONS_UP_R_PULLDOWN) + adc_button_tolerance, 1 + BLEN_KEYPAD_UP }, // UP ( 618 ... 818) - { ADC_BUTTON_VALUE(ADC_BUTTONS_DOWN_R_PULLDOWN) - adc_button_tolerance, - ADC_BUTTON_VALUE(ADC_BUTTONS_DOWN_R_PULLDOWN) + adc_button_tolerance, 1 + BLEN_KEYPAD_DOWN }, // DOWN (2686 ... 2886) - { ADC_BUTTON_VALUE(ADC_BUTTONS_MIDDLE_R_PULLDOWN) - adc_button_tolerance, - ADC_BUTTON_VALUE(ADC_BUTTONS_MIDDLE_R_PULLDOWN) + adc_button_tolerance, 1 + BLEN_KEYPAD_MIDDLE }, // ENTER (1205 ... 1405) - }; - - uint8_t get_ADC_keyValue() { - if (thermalManager.ADCKey_count >= 16) { - const uint16_t currentkpADCValue = thermalManager.current_ADCKey_raw; - thermalManager.current_ADCKey_raw = HAL_ADC_RANGE; - thermalManager.ADCKey_count = 0; - if (currentkpADCValue < adc_other_button) - LOOP_L_N(i, ADC_KEY_NUM) { - const uint16_t lo = pgm_read_word(&stADCKeyTable[i].ADCKeyValueMin), - hi = pgm_read_word(&stADCKeyTable[i].ADCKeyValueMax); - if (WITHIN(currentkpADCValue, lo, hi)) return pgm_read_byte(&stADCKeyTable[i].ADCKeyNo); - } - } - return 0; - } - -#endif // HAS_ADC_BUTTONS - -#if HAS_ENCODER_ACTION - - /** - * Read encoder buttons from the hardware registers - * Warning: This function is called from interrupt context! - */ - void MarlinUI::update_buttons() { - const millis_t now = millis(); - if (ELAPSED(now, next_button_update_ms)) { - - #if HAS_DIGITAL_BUTTONS - - #if ANY_BUTTON(EN1, EN2, ENC, BACK) - - uint8_t newbutton = 0; - if (BUTTON_PRESSED(EN1)) newbutton |= EN_A; - if (BUTTON_PRESSED(EN2)) newbutton |= EN_B; - if (can_encode() && BUTTON_PRESSED(ENC)) newbutton |= EN_C; - if (BUTTON_PRESSED(BACK)) newbutton |= EN_D; - - #else - - constexpr uint8_t newbutton = 0; - - #endif - - // - // Directional buttons - // - #if ANY_BUTTON(UP, DWN, LFT, RT) - - const int8_t pulses = epps * encoderDirection; - - if (BUTTON_PRESSED(UP)) { - encoderDiff = (ENCODER_STEPS_PER_MENU_ITEM) * pulses; - next_button_update_ms = now + 300; + uint8_t get_ADC_keyValue() { + if (thermalManager.ADCKey_count >= 16) { + const uint16_t currentkpADCValue = thermalManager.current_ADCKey_raw; + thermalManager.current_ADCKey_raw = HAL_ADC_RANGE; + thermalManager.ADCKey_count = 0; + if (currentkpADCValue < adc_other_button) + LOOP_L_N(i, ADC_KEY_NUM) { + const uint16_t lo = pgm_read_word(&stADCKeyTable[i].ADCKeyValueMin), + hi = pgm_read_word(&stADCKeyTable[i].ADCKeyValueMax); + if (WITHIN(currentkpADCValue, lo, hi)) return pgm_read_byte(&stADCKeyTable[i].ADCKeyNo); } - else if (BUTTON_PRESSED(DWN)) { - encoderDiff = -(ENCODER_STEPS_PER_MENU_ITEM) * pulses; - next_button_update_ms = now + 300; - } - else if (BUTTON_PRESSED(LFT)) { - encoderDiff = -pulses; - next_button_update_ms = now + 300; - } - else if (BUTTON_PRESSED(RT)) { - encoderDiff = pulses; - next_button_update_ms = now + 300; - } - - #endif // UP || DWN || LFT || RT - - buttons = (newbutton | TERN0(HAS_SLOW_BUTTONS, slow_buttons) - #if BOTH(HAS_TOUCH_BUTTONS, HAS_ENCODER_ACTION) - | (touch_buttons & TERN(HAS_ENCODER_WHEEL, ~(EN_A | EN_B), 0xFF)) - #endif - ); - - #elif HAS_ADC_BUTTONS - - buttons = 0; - - #endif - - #if HAS_ADC_BUTTONS - if (keypad_buttons == 0) { - const uint8_t b = get_ADC_keyValue(); - if (WITHIN(b, 1, 8)) keypad_buttons = _BV(b - 1); - } - #endif - - #if HAS_SHIFT_ENCODER - /** - * Set up Rotary Encoder bit values (for two pin encoders to indicate movement). - * These values are independent of which pins are used for EN_A / EN_B indications. - * The rotary encoder part is also independent of the LCD chipset. - */ - uint8_t val = 0; - WRITE(SHIFT_LD_PIN, LOW); - WRITE(SHIFT_LD_PIN, HIGH); - LOOP_L_N(i, 8) { - val >>= 1; - if (READ(SHIFT_OUT_PIN)) SBI(val, 7); - WRITE(SHIFT_CLK_PIN, HIGH); - WRITE(SHIFT_CLK_PIN, LOW); - } - TERN(REPRAPWORLD_KEYPAD, keypad_buttons, buttons) = ~val; - #endif - - #if IS_TFTGLCD_PANEL - next_button_update_ms = now + (LCD_UPDATE_INTERVAL / 2); - buttons = slow_buttons; - TERN_(AUTO_BED_LEVELING_UBL, external_encoder()); - #endif - - } // next_button_update_ms - - #if HAS_ENCODER_WHEEL - static uint8_t lastEncoderBits; - - // Manage encoder rotation - #define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: encoderDiff += encoderDirection; break; case _E2: encoderDiff -= encoderDirection; } - - uint8_t enc = 0; - if (buttons & EN_A) enc |= B01; - if (buttons & EN_B) enc |= B10; - if (enc != lastEncoderBits) { - switch (enc) { - case ENCODER_PHASE_0: ENCODER_SPIN(ENCODER_PHASE_3, ENCODER_PHASE_1); break; - case ENCODER_PHASE_1: ENCODER_SPIN(ENCODER_PHASE_0, ENCODER_PHASE_2); break; - case ENCODER_PHASE_2: ENCODER_SPIN(ENCODER_PHASE_1, ENCODER_PHASE_3); break; - case ENCODER_PHASE_3: ENCODER_SPIN(ENCODER_PHASE_2, ENCODER_PHASE_0); break; - } - #if BOTH(HAS_LCD_MENU, AUTO_BED_LEVELING_UBL) - external_encoder(); - #endif - lastEncoderBits = enc; } + return 0; + } - #endif // HAS_ENCODER_WHEEL - } + #endif // HAS_ADC_BUTTONS -#endif // HAS_ENCODER_ACTION + #if HAS_ENCODER_ACTION + + /** + * Read encoder buttons from the hardware registers + * Warning: This function is called from interrupt context! + */ + void MarlinUI::update_buttons() { + const millis_t now = millis(); + if (ELAPSED(now, next_button_update_ms)) { + + #if HAS_DIGITAL_BUTTONS + + #if ANY_BUTTON(EN1, EN2, ENC, BACK) + + uint8_t newbutton = 0; + if (BUTTON_PRESSED(EN1)) newbutton |= EN_A; + if (BUTTON_PRESSED(EN2)) newbutton |= EN_B; + if (can_encode() && BUTTON_PRESSED(ENC)) newbutton |= EN_C; + if (BUTTON_PRESSED(BACK)) newbutton |= EN_D; + + #else + + constexpr uint8_t newbutton = 0; + + #endif + + // + // Directional buttons + // + #if ANY_BUTTON(UP, DWN, LFT, RT) + + const int8_t pulses = epps * encoderDirection; + + if (BUTTON_PRESSED(UP)) { + encoderDiff = (ENCODER_STEPS_PER_MENU_ITEM) * pulses; + next_button_update_ms = now + 300; + } + else if (BUTTON_PRESSED(DWN)) { + encoderDiff = -(ENCODER_STEPS_PER_MENU_ITEM) * pulses; + next_button_update_ms = now + 300; + } + else if (BUTTON_PRESSED(LFT)) { + encoderDiff = -pulses; + next_button_update_ms = now + 300; + } + else if (BUTTON_PRESSED(RT)) { + encoderDiff = pulses; + next_button_update_ms = now + 300; + } + + #endif // UP || DWN || LFT || RT + + buttons = (newbutton | TERN0(HAS_SLOW_BUTTONS, slow_buttons) + #if BOTH(HAS_TOUCH_BUTTONS, HAS_ENCODER_ACTION) + | (touch_buttons & TERN(HAS_ENCODER_WHEEL, ~(EN_A | EN_B), 0xFF)) + #endif + ); + + #elif HAS_ADC_BUTTONS + + buttons = 0; + + #endif + + #if HAS_ADC_BUTTONS + if (keypad_buttons == 0) { + const uint8_t b = get_ADC_keyValue(); + if (WITHIN(b, 1, 8)) keypad_buttons = _BV(b - 1); + } + #endif + + #if HAS_SHIFT_ENCODER + /** + * Set up Rotary Encoder bit values (for two pin encoders to indicate movement). + * These values are independent of which pins are used for EN_A / EN_B indications. + * The rotary encoder part is also independent of the LCD chipset. + */ + uint8_t val = 0; + WRITE(SHIFT_LD_PIN, LOW); + WRITE(SHIFT_LD_PIN, HIGH); + LOOP_L_N(i, 8) { + val >>= 1; + if (READ(SHIFT_OUT_PIN)) SBI(val, 7); + WRITE(SHIFT_CLK_PIN, HIGH); + WRITE(SHIFT_CLK_PIN, LOW); + } + TERN(REPRAPWORLD_KEYPAD, keypad_buttons, buttons) = ~val; + #endif + + #if IS_TFTGLCD_PANEL + next_button_update_ms = now + (LCD_UPDATE_INTERVAL / 2); + buttons = slow_buttons; + TERN_(AUTO_BED_LEVELING_UBL, external_encoder()); + #endif + + } // next_button_update_ms + + #if HAS_ENCODER_WHEEL + static uint8_t lastEncoderBits; + + // Manage encoder rotation + #define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: encoderDiff += encoderDirection; break; case _E2: encoderDiff -= encoderDirection; } + + uint8_t enc = 0; + if (buttons & EN_A) enc |= B01; + if (buttons & EN_B) enc |= B10; + if (enc != lastEncoderBits) { + switch (enc) { + case ENCODER_PHASE_0: ENCODER_SPIN(ENCODER_PHASE_3, ENCODER_PHASE_1); break; + case ENCODER_PHASE_1: ENCODER_SPIN(ENCODER_PHASE_0, ENCODER_PHASE_2); break; + case ENCODER_PHASE_2: ENCODER_SPIN(ENCODER_PHASE_1, ENCODER_PHASE_3); break; + case ENCODER_PHASE_3: ENCODER_SPIN(ENCODER_PHASE_2, ENCODER_PHASE_0); break; + } + #if BOTH(HAS_LCD_MENU, AUTO_BED_LEVELING_UBL) + external_encoder(); + #endif + lastEncoderBits = enc; + } + + #endif // HAS_ENCODER_WHEEL + } + + #endif // HAS_ENCODER_ACTION #endif // HAS_WIRED_LCD @@ -1494,6 +1490,13 @@ void MarlinUI::update() { TERN_(HAS_LCD_MENU, return_to_status()); } + #if BOTH(PSU_CONTROL, PS_OFF_CONFIRM) + void MarlinUI::poweroff() { + queue.inject_P(PSTR("M81")); + goto_previous_screen(); + } + #endif + void MarlinUI::flow_fault() { LCD_ALERTMESSAGEPGM(MSG_FLOWMETER_FAULT); TERN_(HAS_BUZZER, buzz(1000, 440)); @@ -1609,8 +1612,9 @@ void MarlinUI::update() { if (status) { if (old_status < 2) { - TERN_(EXTENSIBLE_UI, ExtUI::onMediaInserted()); // ExtUI response - #if ENABLED(BROWSE_MEDIA_ON_INSERT) + #if ENABLED(EXTENSIBLE_UI) + ExtUI::onMediaInserted(); + #elif ENABLED(BROWSE_MEDIA_ON_INSERT) clear_menu_history(); quick_feedback(); goto_screen(MEDIA_MENU_GATEWAY); @@ -1621,8 +1625,9 @@ void MarlinUI::update() { } else { if (old_status < 2) { - TERN_(EXTENSIBLE_UI, ExtUI::onMediaRemoved()); // ExtUI response - #if PIN_EXISTS(SD_DETECT) + #if ENABLED(EXTENSIBLE_UI) + ExtUI::onMediaRemoved(); + #elif PIN_EXISTS(SD_DETECT) LCD_MESSAGEPGM(MSG_MEDIA_REMOVED); #if HAS_LCD_MENU if (!defer_return_to_status) return_to_status(); diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index 9ac77fa070..228edc4cf2 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -334,6 +334,10 @@ public: static void resume_print(); static void flow_fault(); + #if BOTH(PSU_CONTROL, PS_OFF_CONFIRM) + static void poweroff(); + #endif + #if HAS_WIRED_LCD static millis_t next_button_update_ms; @@ -445,10 +449,13 @@ public: static PGM_P get_preheat_label(const uint8_t m); #endif + #if SCREENS_CAN_TIME_OUT + static inline void reset_status_timeout(const millis_t ms) { return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS; } + #else + static inline void reset_status_timeout(const millis_t) {} + #endif + #if HAS_LCD_MENU - #if LCD_TIMEOUT_TO_STATUS - static millis_t return_to_status_ms; - #endif #if HAS_TOUCH_BUTTONS static uint8_t touch_buttons; @@ -479,7 +486,7 @@ public: static screenFunc_t currentScreen; static bool screen_changed; static void goto_screen(const screenFunc_t screen, const uint16_t encoder=0, const uint8_t top=0, const uint8_t items=0); - static void save_previous_screen(); + static void push_current_screen(); // goto_previous_screen and go_back may also be used as menu item callbacks static void _goto_previous_screen(TERN_(TURBO_BACK_MENU_ITEM, const bool is_back)); @@ -494,12 +501,12 @@ public: static void lcd_in_status(const bool inStatus); #endif + FORCE_INLINE static bool screen_is_sticky() { + return TERN1(SCREENS_CAN_TIME_OUT, defer_return_to_status); + } + FORCE_INLINE static void defer_status_screen(const bool defer=true) { - #if LCD_TIMEOUT_TO_STATUS > 0 - defer_return_to_status = defer; - #else - UNUSED(defer); - #endif + TERN(SCREENS_CAN_TIME_OUT, defer_return_to_status = defer, UNUSED(defer)); } static inline void goto_previous_screen_no_defer() { @@ -522,10 +529,13 @@ public: static void draw_select_screen_prompt(PGM_P const pref, const char * const string=nullptr, PGM_P const suff=nullptr); - #elif HAS_WIRED_LCD + #else static constexpr bool on_status_screen() { return true; } - FORCE_INLINE static void run_current_screen() { status_screen(); } + + #if HAS_WIRED_LCD + FORCE_INLINE static void run_current_screen() { status_screen(); } + #endif #endif @@ -651,16 +661,18 @@ public: private: + #if SCREENS_CAN_TIME_OUT + static millis_t return_to_status_ms; + static bool defer_return_to_status; + #else + static constexpr bool defer_return_to_status = false; + #endif + #if HAS_STATUS_MESSAGE static void finish_status(const bool persist); #endif #if HAS_WIRED_LCD - #if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS > 0 - static bool defer_return_to_status; - #else - static constexpr bool defer_return_to_status = false; - #endif static void draw_status_screen(); #if HAS_GRAPHICAL_TFT static void tft_idle(); diff --git a/Marlin/src/lcd/menu/menu.cpp b/Marlin/src/lcd/menu/menu.cpp index 6143e8da1e..01c8bb80c0 100644 --- a/Marlin/src/lcd/menu/menu.cpp +++ b/Marlin/src/lcd/menu/menu.cpp @@ -50,9 +50,12 @@ int8_t encoderTopLine, encoderLine, screen_items; typedef struct { - screenFunc_t menu_function; - uint32_t encoder_position; - int8_t top_line, items; + screenFunc_t menu_function; // The screen's function + uint32_t encoder_position; // The position of the encoder + int8_t top_line, items; // The amount of scroll, and the number of items + #if SCREENS_CAN_TIME_OUT + bool sticky; // The screen is sticky + #endif } menuPosition; menuPosition screen_history[6]; uint8_t screen_history_depth = 0; @@ -75,9 +78,9 @@ bool MenuEditItemBase::liveEdit; void MarlinUI::return_to_status() { goto_screen(status_screen); } -void MarlinUI::save_previous_screen() { +void MarlinUI::push_current_screen() { if (screen_history_depth < COUNT(screen_history)) - screen_history[screen_history_depth++] = { currentScreen, encoderPosition, encoderTopLine, screen_items }; + screen_history[screen_history_depth++] = { currentScreen, encoderPosition, encoderTopLine, screen_items OPTARG(SCREENS_CAN_TIME_OUT, screen_is_sticky()) }; } void MarlinUI::_goto_previous_screen(TERN_(TURBO_BACK_MENU_ITEM, const bool is_back/*=false*/)) { @@ -90,6 +93,7 @@ void MarlinUI::_goto_previous_screen(TERN_(TURBO_BACK_MENU_ITEM, const bool is_b is_back ? 0 : sh.top_line, sh.items ); + defer_status_screen(TERN_(SCREENS_CAN_TIME_OUT, sh.sticky)); } else return_to_status(); @@ -147,7 +151,7 @@ void MenuEditItemBase::goto_edit_screen( ) { TERN_(HAS_TOUCH_BUTTONS, ui.on_edit_screen = true); ui.screen_changed = true; - ui.save_previous_screen(); + ui.push_current_screen(); ui.refresh(); editLabel = el; editValue = ev; @@ -237,7 +241,7 @@ void MarlinUI::goto_screen(screenFunc_t screen, const uint16_t encoder/*=0*/, co // void MarlinUI::synchronize(PGM_P const msg/*=nullptr*/) { static PGM_P sync_message = msg ?: GET_TEXT(MSG_MOVING); - save_previous_screen(); + push_current_screen(); goto_screen([]{ if (should_draw()) MenuItem_static::draw(LCD_HEIGHT >= 4, sync_message); }); @@ -371,6 +375,7 @@ void MenuItem_confirm::select_screen( selectFunc_t yesFunc, selectFunc_t noFunc, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/ ) { + ui.defer_status_screen(); const bool ui_selection = ui.update_selection(), got_click = ui.use_click(); if (got_click || ui.should_draw()) { draw_select_screen(yes, no, ui_selection, pref, string, suff); @@ -378,7 +383,6 @@ void MenuItem_confirm::select_screen( selectFunc_t callFunc = ui_selection ? yesFunc : noFunc; if (callFunc) callFunc(); else ui.goto_previous_screen(); } - ui.defer_status_screen(); } } diff --git a/Marlin/src/lcd/menu/menu.h b/Marlin/src/lcd/menu/menu.h index 290832c49c..28d377da0c 100644 --- a/Marlin/src/lcd/menu/menu.h +++ b/Marlin/src/lcd/menu/menu.h @@ -132,14 +132,15 @@ class MenuItem_confirm : public MenuItemBase { // The Menu Edit shadow value typedef union { - bool state; - float decimal; - int8_t int8; - int16_t int16; - int32_t int32; - uint8_t uint8; - uint16_t uint16; - uint32_t uint32; + bool state; + float decimal; + int8_t int8; + int16_t int16; + int32_t int32; + uint8_t uint8; + uint16_t uint16; + uint32_t uint32; + celsius_t celsius; } chimera_t; extern chimera_t editable; diff --git a/Marlin/src/lcd/menu/menu_filament.cpp b/Marlin/src/lcd/menu/menu_filament.cpp index c6b8568085..d70ed98aa8 100644 --- a/Marlin/src/lcd/menu/menu_filament.cpp +++ b/Marlin/src/lcd/menu/menu_filament.cpp @@ -106,10 +106,11 @@ void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) { * "Change Filament" submenu */ #if E_STEPPERS > 1 || ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) - bool printingIsPaused(); +#endif - void menu_change_filament() { +void menu_change_filament() { + #if E_STEPPERS > 1 || ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) // Say "filament change" when no print is active editable.int8 = printingIsPaused() ? PAUSE_MODE_PAUSE_PRINT : PAUSE_MODE_CHANGE_FILAMENT; @@ -204,8 +205,16 @@ void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) { #endif END_MENU(); - } -#endif + + #else + + if (thermalManager.targetHotEnoughToExtrude(active_extruder)) + queue.inject_P(PSTR("M600B0")); + else + _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, 0); + + #endif +} static uint8_t hotend_status_extruder = 0; diff --git a/Marlin/src/lcd/menu/menu_item.h b/Marlin/src/lcd/menu/menu_item.h index bcd93e11f8..0a4f4bb7d1 100644 --- a/Marlin/src/lcd/menu/menu_item.h +++ b/Marlin/src/lcd/menu/menu_item.h @@ -39,7 +39,7 @@ class MenuItem_submenu : public MenuItemBase { FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { _draw(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]); } - static inline void action(PGM_P const, const screenFunc_t func) { ui.save_previous_screen(); ui.goto_screen(func); } + static inline void action(PGM_P const, const screenFunc_t func) { ui.push_current_screen(); ui.goto_screen(func); } }; // Any menu item that invokes an immediate action @@ -406,7 +406,7 @@ class MenuItem_bool : public MenuEditItemBase { #define _CONFIRM_ITEM_INNER_P(PLABEL, V...) do { \ if (encoderLine == _thisItemNr && ui.use_click()) { \ - ui.save_previous_screen(); \ + ui.push_current_screen(); \ ui.goto_screen([]{MenuItem_confirm::select_screen(V);}); \ return; \ } \ @@ -434,23 +434,23 @@ class MenuItem_bool : public MenuEditItemBase { }while(0) // Indexed items set a global index value -#define _CONFIRM_ITEM_N_P(N, V...) _CONFIRM_ITEM_N_S_P(N, nullptr, V) +#define _CONFIRM_ITEM_N_P(N, V...) _CONFIRM_ITEM_N_S_P(N, nullptr, V) -#define CONFIRM_ITEM_P(PLABEL,A,B,V...) _CONFIRM_ITEM_P(PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) -#define CONFIRM_ITEM(LABEL, V...) CONFIRM_ITEM_P(GET_TEXT(LABEL), ##V) +#define CONFIRM_ITEM_P(PLABEL,A,B,V...) _CONFIRM_ITEM_P(PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) +#define CONFIRM_ITEM(LABEL, V...) CONFIRM_ITEM_P(GET_TEXT(LABEL), ##V) -#define YESNO_ITEM_P(PLABEL, V...) _CONFIRM_ITEM_P(PLABEL, ##V) -#define YESNO_ITEM(LABEL, V...) YESNO_ITEM_P(GET_TEXT(LABEL), ##V) +#define YESNO_ITEM_P(PLABEL, V...) CONFIRM_ITEM_P(PLABEL, MSG_YES, MSG_NO, ##V) +#define YESNO_ITEM(LABEL, V...) YESNO_ITEM_P(GET_TEXT(LABEL), ##V) #define CONFIRM_ITEM_N_S_P(N,S,PLABEL,A,B,V...) _CONFIRM_ITEM_N_S_P(N, S, PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) #define CONFIRM_ITEM_N_S(N,S,LABEL,V...) CONFIRM_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ##V) #define CONFIRM_ITEM_N_P(N,PLABEL,A,B,V...) _CONFIRM_ITEM_N_P(N, PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) #define CONFIRM_ITEM_N(N,LABEL, V...) CONFIRM_ITEM_N_P(N, GET_TEXT(LABEL), ##V) -#define YESNO_ITEM_N_S_P(N,S,PLABEL, V...) _CONFIRM_ITEM_N_S_P(N, S, PLABEL, ##V) -#define YESNO_ITEM_N_S(N,S,LABEL, V...) YESNO_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ##V) -#define YESNO_ITEM_N_P(N,PLABEL, V...) _CONFIRM_ITEM_N_P(N, PLABEL, ##V) -#define YESNO_ITEM_N(N,LABEL, V...) YESNO_ITEM_N_P(N, GET_TEXT(LABEL), ##V) +#define YESNO_ITEM_N_S_P(N,S,PLABEL, V...) _CONFIRM_ITEM_N_S_P(N, S, PLABEL, MSG_YES, MSG_NO, ##V) +#define YESNO_ITEM_N_S(N,S,LABEL, V...) YESNO_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ##V) +#define YESNO_ITEM_N_P(N,PLABEL, V...) CONFIRM_ITEM_N_P(N, PLABEL, MSG_YES, MSG_NO, ##V) +#define YESNO_ITEM_N(N,LABEL, V...) YESNO_ITEM_N_P(N, GET_TEXT(LABEL), ##V) #if ENABLED(LEVEL_BED_CORNERS) void _lcd_level_bed_corners(); diff --git a/Marlin/src/lcd/menu/menu_main.cpp b/Marlin/src/lcd/menu/menu_main.cpp index 921c2435b5..6f32ef1d60 100644 --- a/Marlin/src/lcd/menu/menu_main.cpp +++ b/Marlin/src/lcd/menu/menu_main.cpp @@ -77,7 +77,6 @@ void menu_configuration(); #endif #if ENABLED(ADVANCED_PAUSE_FEATURE) - void _menu_temp_filament_op(const PauseMode, const int8_t); void menu_change_filament(); #endif @@ -365,10 +364,10 @@ void menu_main() { #if ENABLED(ADVANCED_PAUSE_FEATURE) #if E_STEPPERS == 1 && DISABLED(FILAMENT_LOAD_UNLOAD_GCODES) - if (thermalManager.targetHotEnoughToExtrude(active_extruder)) - GCODES_ITEM(MSG_FILAMENTCHANGE, PSTR("M600 B0")); - else - SUBMENU(MSG_FILAMENTCHANGE, []{ _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, 0); }); + YESNO_ITEM(MSG_FILAMENTCHANGE, + menu_change_filament, ui.goto_previous_screen, + GET_TEXT(MSG_FILAMENTCHANGE), (const char *)nullptr, PSTR("?") + ); #else SUBMENU(MSG_FILAMENTCHANGE, menu_change_filament); #endif @@ -387,7 +386,15 @@ void menu_main() { // #if ENABLED(PSU_CONTROL) if (powersupply_on) - GCODES_ITEM(MSG_SWITCH_PS_OFF, PSTR("M81")); + #if ENABLED(PS_OFF_CONFIRM) + CONFIRM_ITEM(MSG_SWITCH_PS_OFF, + MSG_YES, MSG_NO, + ui.poweroff, ui.goto_previous_screen, + GET_TEXT(MSG_SWITCH_PS_OFF), (const char *)nullptr, PSTR("?") + ); + #else + GCODES_ITEM(MSG_SWITCH_PS_OFF, PSTR("M81")); + #endif else GCODES_ITEM(MSG_SWITCH_PS_ON, PSTR("M80")); #endif diff --git a/Marlin/src/lcd/menu/menu_motion.cpp b/Marlin/src/lcd/menu/menu_motion.cpp index 076ece33b0..70f7acd547 100644 --- a/Marlin/src/lcd/menu/menu_motion.cpp +++ b/Marlin/src/lcd/menu/menu_motion.cpp @@ -28,6 +28,8 @@ #if HAS_LCD_MENU +#define LARGE_AREA_TEST ((X_BED_SIZE) >= 1000 || (Y_BED_SIZE) >= 1000 || (Z_MAX_POS) >= 1000) + #include "menu_item.h" #include "menu_addon.h" @@ -85,7 +87,7 @@ static void _lcd_move_xyz(PGM_P const name, const AxisEnum axis) { MenuEditItemBase::draw_edit_screen(name, ftostr63(imp_pos)); } else - MenuEditItemBase::draw_edit_screen(name, ui.manual_move.menu_scale >= 0.1f ? ftostr41sign(pos) : ftostr63(pos)); + MenuEditItemBase::draw_edit_screen(name, ui.manual_move.menu_scale >= 0.1f ? (LARGE_AREA_TEST ? ftostr51sign(pos) : ftostr41sign(pos)) : ftostr63(pos)); } } void lcd_move_x() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_X), X_AXIS); } @@ -165,11 +167,13 @@ void _menu_move_distance(const AxisEnum axis, const screenFunc_t func, const int BACK_ITEM(MSG_MOVE_AXIS); if (parser.using_inch_units()) { + if (LARGE_AREA_TEST) SUBMENU(MSG_MOVE_1IN, []{ _goto_manual_move(IN_TO_MM(1.000f)); }); SUBMENU(MSG_MOVE_01IN, []{ _goto_manual_move(IN_TO_MM(0.100f)); }); SUBMENU(MSG_MOVE_001IN, []{ _goto_manual_move(IN_TO_MM(0.010f)); }); SUBMENU(MSG_MOVE_0001IN, []{ _goto_manual_move(IN_TO_MM(0.001f)); }); } else { + if (LARGE_AREA_TEST) SUBMENU(MSG_MOVE_100MM, []{ _goto_manual_move(100); }); SUBMENU(MSG_MOVE_10MM, []{ _goto_manual_move(10); }); SUBMENU(MSG_MOVE_1MM, []{ _goto_manual_move( 1); }); SUBMENU(MSG_MOVE_01MM, []{ _goto_manual_move( 0.1f); }); @@ -180,7 +184,6 @@ void _menu_move_distance(const AxisEnum axis, const screenFunc_t func, const int PGM_P const label = GET_TEXT(MSG_MOVE_N_MM); char tmp[strlen_P(label) + 10 + 1], numstr[10]; sprintf_P(tmp, label, dtostrf(FINE_MANUAL_MOVE, 1, digs, numstr)); - #if DISABLED(HAS_GRAPHICAL_TFT) SUBMENU_P(NUL_STR, []{ _goto_manual_move(float(FINE_MANUAL_MOVE)); }); MENU_ITEM_ADDON_START(0 + ENABLED(HAS_MARLINUI_HD44780)); diff --git a/Marlin/src/lcd/menu/menu_password.cpp b/Marlin/src/lcd/menu/menu_password.cpp index 590ce48d59..d3a35abff2 100644 --- a/Marlin/src/lcd/menu/menu_password.cpp +++ b/Marlin/src/lcd/menu/menu_password.cpp @@ -177,7 +177,7 @@ void Password::menu_password() { START_MENU(); BACK_ITEM(MSG_ADVANCED_SETTINGS); SUBMENU(MSG_CHANGE_PASSWORD, screen_set_password); - ACTION_ITEM(MSG_REMOVE_PASSWORD, []{ ui.save_previous_screen(); remove_password(); } ); + ACTION_ITEM(MSG_REMOVE_PASSWORD, []{ ui.push_current_screen(); remove_password(); } ); #if ENABLED(EEPROM_SETTINGS) ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings); #endif diff --git a/Marlin/src/lcd/menu/menu_temperature.cpp b/Marlin/src/lcd/menu/menu_temperature.cpp index 96e6ee5f8e..65cef5b76d 100644 --- a/Marlin/src/lcd/menu/menu_temperature.cpp +++ b/Marlin/src/lcd/menu/menu_temperature.cpp @@ -169,10 +169,13 @@ void menu_temperature() { // Nozzle [1-5]: // #if HOTENDS == 1 - EDIT_ITEM_FAST(int3, MSG_NOZZLE, &thermalManager.temp_hotend[0].target, 0, thermalManager.hotend_max_target(0), []{ thermalManager.start_watching_hotend(0); }); + editable.celsius = thermalManager.temp_hotend[0].target; + EDIT_ITEM_FAST(int3, MSG_NOZZLE, &editable.celsius, 0, thermalManager.hotend_max_target(0), []{ thermalManager.setTargetHotend(editable.celsius, 0); }); #elif HAS_MULTI_HOTEND - HOTEND_LOOP() - EDIT_ITEM_FAST_N(int3, e, MSG_NOZZLE_N, &thermalManager.temp_hotend[e].target, 0, thermalManager.hotend_max_target(e), []{ thermalManager.start_watching_hotend(MenuItemBase::itemIndex); }); + HOTEND_LOOP() { + editable.celsius = thermalManager.temp_hotend[e].target; + EDIT_ITEM_FAST_N(int3, e, MSG_NOZZLE_N, &editable.celsius, 0, thermalManager.hotend_max_target(e), []{ thermalManager.setTargetHotend(editable.celsius, MenuItemBase::itemIndex); }); + } #endif #if ENABLED(SINGLENOZZLE_STANDBY_TEMP) diff --git a/Marlin/src/lcd/tft/touch.cpp b/Marlin/src/lcd/tft/touch.cpp index 3d4e0a40e1..64dfaa5755 100644 --- a/Marlin/src/lcd/tft/touch.cpp +++ b/Marlin/src/lcd/tft/touch.cpp @@ -93,9 +93,7 @@ void Touch::idle() { } #endif - #if LCD_TIMEOUT_TO_STATUS - ui.return_to_status_ms = last_touch_ms + LCD_TIMEOUT_TO_STATUS; - #endif + ui.reset_status_timeout(last_touch_ms); if (touch_time) { #if ENABLED(TOUCH_SCREEN_CALIBRATION) diff --git a/Marlin/src/libs/MAX31865.cpp b/Marlin/src/libs/MAX31865.cpp new file mode 100644 index 0000000000..590dea5ca5 --- /dev/null +++ b/Marlin/src/libs/MAX31865.cpp @@ -0,0 +1,500 @@ +/** + * 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 . + * + */ + +/** + * Based on Based on Adafruit MAX31865 library: + * + * This is a library for the Adafruit PT100/P1000 RTD Sensor w/MAX31865 + * Designed specifically to work with the Adafruit RTD Sensor + * https://www.adafruit.com/products/3328 + * + * This sensor uses SPI to communicate, 4 pins are required to interface. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Written by Limor Fried/Ladyada for Adafruit Industries. + * + * Modifications by JoAnn Manges (@GadgetAngel) + * Copyright (c) 2020, JoAnn Manges + * All rights reserved. + */ + +// Useful for RTD debugging. +//#define MAX31865_DEBUG +//#define MAX31865_DEBUG_SPI + +//TODO: switch to SPIclass/SoftSPI + +#include "../inc/MarlinConfig.h" + +#if HAS_MAX31865 && !LIB_USR_MAX31865 + +#include "MAX31865.h" + +// The maximum speed the MAX31865 can do is 5 MHz +SPISettings MAX31865::spiConfig = SPISettings( + #if defined(TARGET_LPC1768) + SPI_QUARTER_SPEED + #elif defined(ARDUINO_ARCH_STM32) + SPI_CLOCK_DIV4 + #else + 500000 + #endif + , MSBFIRST + , SPI_MODE_1 // CPOL0 CPHA1 +); + +#ifndef LARGE_PINMAP + + /** + * Create the interface object using software (bitbang) SPI for PIN values + * less than or equal to 127. + * + * @param spi_cs the SPI CS pin to use + * @param spi_mosi the SPI MOSI pin to use + * @param spi_miso the SPI MISO pin to use + * @param spi_clk the SPI clock pin to use + */ + MAX31865::MAX31865(int8_t spi_cs, int8_t spi_mosi, int8_t spi_miso, int8_t spi_clk) { + _cs = spi_cs; + _mosi = spi_mosi; + _miso = spi_miso; + _sclk = spi_clk; + } + + /** + * Create the interface object using hardware SPI for PIN for PIN values less + * than or equal to 127. + * + * @param spi_cs the SPI CS pin to use along with the default SPI device + */ + MAX31865::MAX31865(int8_t spi_cs) { + _cs = spi_cs; + _sclk = _miso = _mosi = -1; + } + +#else + + /** + * Create the interface object using software (bitbang) SPI for PIN values + * which are larger than 127. If you have PIN values less than or equal to + * 127 use the other call for SW SPI. + * + * @param spi_cs the SPI CS pin to use + * @param spi_mosi the SPI MOSI pin to use + * @param spi_miso the SPI MISO pin to use + * @param spi_clk the SPI clock pin to use + * @param pin_mapping set to 1 for positive pin values + */ + MAX31865::MAX31865(uint32_t spi_cs, uint32_t spi_mosi, + uint32_t spi_miso, uint32_t spi_clk, + uint8_t pin_mapping) { + _cs = spi_cs; + _mosi = spi_mosi; + _miso = spi_miso; + _sclk = spi_clk; + } + + /** + * Create the interface object using hardware SPI for PIN values which are + * larger than 127. If you have PIN values less than or equal to 127 use + * the other call for HW SPI. + * + * @param spi_cs the SPI CS pin to use along with the default SPI device + * @param pin_mapping set to 1 for positive pin values + */ + MAX31865::MAX31865(uint32_t spi_cs, uint8_t pin_mapping) { + _cs = spi_cs; + _sclk = _miso = _mosi = -1UL; //-1UL or 0xFFFFFFFF or 4294967295 + } + +#endif // LARGE_PINMAP + + +/** + * + * Instance & Class methods + * + */ + + +/** + * Initialize the SPI interface and set the number of RTD wires used + * + * @param wires The number of wires in enum format. Can be MAX31865_2WIRE, MAX31865_3WIRE, or MAX31865_4WIRE. + * @param zero The resistance of the RTD at 0 degC, in ohms. + * @param ref The resistance of the reference resistor, in ohms. + */ +void MAX31865::begin(max31865_numwires_t wires, float zero, float ref) { + Rzero = zero; + Rref = ref; + + OUT_WRITE(_cs, HIGH); + + if (_sclk != TERN(LARGE_PINMAP, -1UL, -1)) { + // define pin modes for Software SPI + #ifdef MAX31865_DEBUG + SERIAL_ECHOLN("Initializing MAX31865 Software SPI"); + #endif + + OUT_WRITE(_sclk, LOW); + SET_OUTPUT(_mosi); + SET_INPUT(_miso); + } else { + // start and configure hardware SPI + #ifdef MAX31865_DEBUG + SERIAL_ECHOLN("Initializing MAX31865 Hardware SPI"); + #endif + + SPI.begin(); + } + + setWires(wires); + enableBias(false); + autoConvert(false); + clearFault(); + + #ifdef MAX31865_DEBUG_SPI + #ifndef LARGE_PINMAP + SERIAL_ECHOLNPAIR( + "Regular begin call with _cs: ", _cs, + " _miso: ", _miso, + " _sclk: ", _sclk, + " _mosi: ", _mosi + ); + #else + SERIAL_ECHOLNPAIR( + "LARGE_PINMAP begin call with _cs: ", _cs, + " _miso: ", _miso, + " _sclk: ", _sclk, + " _mosi: ", _mosi + ); + #endif // LARGE_PINMAP + + SERIAL_ECHOLNPAIR("config: ", readRegister8(MAX31856_CONFIG_REG)); + SERIAL_EOL(); + #endif // MAX31865_DEBUG_SPI +} + +/** + * Read the raw 8-bit FAULTSTAT register + * + * @return The raw unsigned 8-bit FAULT status register + */ +uint8_t MAX31865::readFault() { + return readRegister8(MAX31856_FAULTSTAT_REG); +} + +/** + * Clear all faults in FAULTSTAT. + */ +void MAX31865::clearFault() { + setConfig(MAX31856_CONFIG_FAULTSTAT, 1); +} + +/** + * Whether we want to have continuous conversions (50/60 Hz) + * + * @param b If true, auto conversion is enabled + */ +void MAX31865::autoConvert(bool b) { + setConfig(MAX31856_CONFIG_MODEAUTO, b); +} + +/** + * Whether we want filter out 50Hz noise or 60Hz noise + * + * @param b If true, 50Hz noise is filtered, else 60Hz(default) + */ +void MAX31865::enable50HzFilter(bool b) { + setConfig(MAX31856_CONFIG_FILT50HZ, b); +} + +/** + * Enable the bias voltage on the RTD sensor + * + * @param b If true bias is enabled, else disabled + */ +void MAX31865::enableBias(bool b) { + setConfig(MAX31856_CONFIG_BIAS, b); + + // From the datasheet: + // Note that if VBIAS is off (to reduce supply current between conversions), any filter + // capacitors at the RTDIN inputs need to charge before an accurate conversion can be + // performed. Therefore, enable VBIAS and wait at least 10.5 time constants of the input + // RC network plus an additional 1ms before initiating the conversion. + if (b) + DELAY_US(11500); //11.5ms +} + +/** + * Start a one-shot temperature reading. + */ +void MAX31865::oneShot() { + setConfig(MAX31856_CONFIG_1SHOT, 1); + + // From the datasheet: + // Note that a single conversion requires approximately 52ms in 60Hz filter + // mode or 62.5ms in 50Hz filter mode to complete. 1-Shot is a self-clearing bit. + // TODO: switch this out depeding on the filter mode. + DELAY_US(65000); // 65ms +} + +/** + * How many wires we have in our RTD setup, can be MAX31865_2WIRE, + * MAX31865_3WIRE, or MAX31865_4WIRE + * + * @param wires The number of wires in enum format + */ +void MAX31865::setWires(max31865_numwires_t wires) { + uint8_t t = readRegister8(MAX31856_CONFIG_REG); + if (wires == MAX31865_3WIRE) + t |= MAX31856_CONFIG_3WIRE; + else // 2 or 4 wire + t &= ~MAX31856_CONFIG_3WIRE; + writeRegister8(MAX31856_CONFIG_REG, t); +} + +/** + * Read the raw 16-bit value from the RTD_REG in one shot mode. This will include + * the fault bit, D0. + * + * @return The raw unsigned 16-bit register value with ERROR bit attached, NOT temperature! + */ +uint16_t MAX31865::readRaw() { + clearFault(); + enableBias(true); + + oneShot(); + uint16_t rtd = readRegister16(MAX31856_RTDMSB_REG); + + #ifdef MAX31865_DEBUG + SERIAL_ECHOLNPAIR("RTD MSB:", (rtd >> 8), " RTD LSB:", (rtd & 0x00FF)); + #endif + + // Disable the bias to lower power dissipation between reads. + // If the ref resistor heats up, the temperature reading will be skewed. + enableBias(false); + + return rtd; +} + +/** + * Calulate and return the resistance value of the connected RTD. + * + * @param refResistor The value of the matching reference resistor, usually 430 or 4300 + * @return The raw RTD resistance value, NOT temperature! + */ +float MAX31865::readResistance() { + // Strip the error bit (D0) and convert to a float ratio. + // less precise method: (readRaw() * Rref) >> 16 + return (((readRaw() >> 1) / 32768.0f) * Rref); +} + +/** + * Read the RTD and pass it to temperature(float) for calculation. + * + * @return Temperature in C + */ +float MAX31865::temperature() { + return temperature(readResistance()); +} + +/** + * Given the 15-bit ADC value, calculate the resistance and pass it to temperature(float) for calculation. + * + * @return Temperature in C + */ +float MAX31865::temperature(uint16_t adcVal) { + return temperature(((adcVal) / 32768.0f) * Rref); +} + +/** + * Calculate the temperature in C from the RTD resistance. + * Uses the technique outlined in this PDF: + * http://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf + * + * @param Rrtd the resistance value in ohms + * @return the temperature in degC + */ +float MAX31865::temperature(float Rrtd) { + float temp = (RTD_Z1 + sqrt(RTD_Z2 + (RTD_Z3 * Rrtd))) / RTD_Z4; + + // From the PDF... + // + // The previous equation is valid only for temperatures of 0°C and above. + // The equation for RRTD(t) that defines negative temperature behavior is a + // fourth-order polynomial (after expanding the third term) and is quite + // impractical to solve for a single expression of temperature as a function + // of resistance. + // + if (temp < 0) { + Rrtd = (Rrtd / Rzero) * 100; // normalize to 100 ohm + float rpoly = Rrtd; + + temp = -242.02 + (2.2228 * rpoly); + rpoly *= Rrtd; // square + temp += 2.5859e-3 * rpoly; + rpoly *= Rrtd; // ^3 + temp -= 4.8260e-6 * rpoly; + rpoly *= Rrtd; // ^4 + temp -= 2.8183e-8 * rpoly; + rpoly *= Rrtd; // ^5 + temp += 1.5243e-10 * rpoly; + } + + return temp; +} + +// +// private: +// + + +/** + * Set a value in the configuration register. + * + * @param config 8-bit value for the config item + * @param enable whether to enable or disable the value + */ +void MAX31865::setConfig(uint8_t config, bool enable) { + uint8_t t = readRegister8(MAX31856_CONFIG_REG); + if (enable) + t |= config; + else + t &= ~config; // disable + writeRegister8(MAX31856_CONFIG_REG, t); +} + +/** + * Read a single byte from the specified register address. + * + * @param addr the register address + * @return the register contents + */ +uint8_t MAX31865::readRegister8(uint8_t addr) { + uint8_t ret = 0; + readRegisterN(addr, &ret, 1); + + return ret; +} + +/** + * Read two bytes: 1 from the specified register address, and 1 from the next address. + * + * @param addr the first register address + * @return both register contents as a single 16-bit int + */ +uint16_t MAX31865::readRegister16(uint8_t addr) { + uint8_t buffer[2] = {0, 0}; + readRegisterN(addr, buffer, 2); + + uint16_t ret = buffer[0]; + ret <<= 8; + ret |= buffer[1]; + + return ret; +} + +/** + * Read +n+ bytes from a specified address into +buffer+. Set D7 to 0 to specify a read. + * + * @param addr the first register address + * @param buffer storage for the read bytes + * @param n the number of bytes to read + */ +void MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) { + addr &= 0x7F; // make sure top bit is not set + if (_sclk == TERN(LARGE_PINMAP, -1UL, -1)) + SPI.beginTransaction(spiConfig); + else + WRITE(_sclk, LOW); + + WRITE(_cs, LOW); + spixfer(addr); + + while (n--) { + buffer[0] = spixfer(0xFF); + #ifdef MAX31865_DEBUG_SPI + SERIAL_ECHOLNPAIR("buffer read ", n, " data: ", buffer[0]); + #endif + buffer++; + } + + if (_sclk == TERN(LARGE_PINMAP, -1UL, -1)) + SPI.endTransaction(); + + WRITE(_cs, HIGH); +} + +/** + * Write an 8-bit value to a register. Set D7 to 1 to specify a write. + * + * @param addr the address to write to + * @param data the data to write + */ +void MAX31865::writeRegister8(uint8_t addr, uint8_t data) { + if (_sclk == TERN(LARGE_PINMAP, -1UL, -1)) + SPI.beginTransaction(spiConfig); + else + WRITE(_sclk, LOW); + + WRITE(_cs, LOW); + + spixfer(addr | 0x80); // make sure top bit is set + spixfer(data); + + if (_sclk == TERN(LARGE_PINMAP, -1UL, -1)) + SPI.endTransaction(); + + WRITE(_cs, HIGH); +} + +/** + * Transfer SPI data +x+ and read the response. From the datasheet... + * Input data (SDI) is latched on the internal strobe edge and output data (SDO) is + * shifted out on the shift edge. There is one clock for each bit transferred. + * Address and data bits are transferred in groups of eight, MSB first. + * + * @param x an 8-bit chunk of data to write + * @return the 8-bit response + */ +uint8_t MAX31865::spixfer(uint8_t x) { + if (_sclk == TERN(LARGE_PINMAP, -1UL, -1)) + return SPI.transfer(x); + + uint8_t reply = 0; + for (int i = 7; i >= 0; i--) { + reply <<= 1; + WRITE(_sclk, HIGH); + WRITE(_mosi, x & (1 << i)); + WRITE(_sclk, LOW); + if (READ(_miso)) + reply |= 1; + } + + return reply; +} + +#endif // HAS_MAX31865 && !LIB_USR_MAX31865 diff --git a/Marlin/src/libs/MAX31865.h b/Marlin/src/libs/MAX31865.h new file mode 100644 index 0000000000..2ab78ecbe8 --- /dev/null +++ b/Marlin/src/libs/MAX31865.h @@ -0,0 +1,131 @@ +/** + * 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 . + * + */ + +/** + * Based on Adafruit MAX31865 library: + * + * This is a library for the Adafruit PT100/P1000 RTD Sensor w/MAX31865 + * Designed specifically to work with the Adafruit RTD Sensor + * https://www.adafruit.com/products/3328 + * + * This sensor uses SPI to communicate, 4 pins are required to interface. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Written by Limor Fried/Ladyada for Adafruit Industries. + * + * Modifications by JoAnn Manges (@GadgetAngel) + * Copyright (c) 2020, JoAnn Manges + * All rights reserved. + */ +#pragma once + +#include "../inc/MarlinConfig.h" +#include "../HAL/shared/Delay.h" +#include HAL_PATH(../HAL, MarlinSPI.h) + +#define MAX31856_CONFIG_REG 0x00 +#define MAX31856_CONFIG_BIAS 0x80 +#define MAX31856_CONFIG_MODEAUTO 0x40 +#define MAX31856_CONFIG_MODEOFF 0x00 +#define MAX31856_CONFIG_1SHOT 0x20 +#define MAX31856_CONFIG_3WIRE 0x10 +#define MAX31856_CONFIG_24WIRE 0x00 +#define MAX31856_CONFIG_FAULTSTAT 0x02 +#define MAX31856_CONFIG_FILT50HZ 0x01 +#define MAX31856_CONFIG_FILT60HZ 0x00 + +#define MAX31856_RTDMSB_REG 0x01 +#define MAX31856_RTDLSB_REG 0x02 +#define MAX31856_HFAULTMSB_REG 0x03 +#define MAX31856_HFAULTLSB_REG 0x04 +#define MAX31856_LFAULTMSB_REG 0x05 +#define MAX31856_LFAULTLSB_REG 0x06 +#define MAX31856_FAULTSTAT_REG 0x07 + +#define MAX31865_FAULT_HIGHTHRESH 0x80 // D7 +#define MAX31865_FAULT_LOWTHRESH 0x40 // D6 +#define MAX31865_FAULT_REFINLOW 0x20 // D5 +#define MAX31865_FAULT_REFINHIGH 0x10 // D4 +#define MAX31865_FAULT_RTDINLOW 0x08 // D3 +#define MAX31865_FAULT_OVUV 0x04 // D2 + +// http://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf +// constants for calulating temperature from the measured RTD resistance. +#define RTD_Z1 -0.0039083 +#define RTD_Z2 0.00001758480889 +#define RTD_Z3 -0.0000000231 +#define RTD_Z4 -0.000001155 + +typedef enum max31865_numwires { + MAX31865_2WIRE = 0, + MAX31865_3WIRE = 1, + MAX31865_4WIRE = 0 +} max31865_numwires_t; + +/* Interface class for the MAX31865 RTD Sensor reader */ +class MAX31865 { +private: + static SPISettings spiConfig; + + TERN(LARGE_PINMAP, uint32_t, uint8_t) _sclk, _miso, _mosi, _cs; + float Rzero, Rref; + + void setConfig(uint8_t config, bool enable); + + void readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n); + uint8_t readRegister8(uint8_t addr); + uint16_t readRegister16(uint8_t addr); + + void writeRegister8(uint8_t addr, uint8_t reg); + uint8_t spixfer(uint8_t addr); + +public: + #ifdef LARGE_PINMAP + MAX31865(uint32_t spi_cs, uint8_t pin_mapping); + MAX31865(uint32_t spi_cs, uint32_t spi_mosi, uint32_t spi_miso, + uint32_t spi_clk, uint8_t pin_mapping); + #else + MAX31865(int8_t spi_cs); + MAX31865(int8_t spi_cs, int8_t spi_mosi, int8_t spi_miso, + int8_t spi_clk); + #endif + + void begin(max31865_numwires_t wires, float zero, float ref); + + uint8_t readFault(); + void clearFault(); + + void setWires(max31865_numwires_t wires); + void autoConvert(bool b); + void enable50HzFilter(bool b); + void enableBias(bool b); + void oneShot(); + + uint16_t readRaw(); + float readResistance(); + float temperature(); + float temperature(uint16_t adcVal); + float temperature(float Rrtd); +}; diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index c750d56713..8f6827de27 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -932,9 +932,13 @@ void Endstops::update() { #endif // If G38 command is active check Z_MIN_PROBE for ALL movement if (G38_move && TEST_ENDSTOP(_ENDSTOP(Z, MIN_PROBE)) != _G38_OPEN_STATE) { - if (stepper.axis_is_moving(X_AXIS)) { _ENDSTOP_HIT(X, MIN); planner.endstop_triggered(X_AXIS); } - else if (stepper.axis_is_moving(Y_AXIS)) { _ENDSTOP_HIT(Y, MIN); planner.endstop_triggered(Y_AXIS); } - else if (stepper.axis_is_moving(Z_AXIS)) { _ENDSTOP_HIT(Z, MIN); planner.endstop_triggered(Z_AXIS); } + if (stepper.axis_is_moving(X_AXIS)) { _ENDSTOP_HIT(X, TERN(X_HOME_TO_MIN, MIN, MAX)); planner.endstop_triggered(X_AXIS); } + #if HAS_Y_AXIS + else if (stepper.axis_is_moving(Y_AXIS)) { _ENDSTOP_HIT(Y, TERN(Y_HOME_TO_MIN, MIN, MAX)); planner.endstop_triggered(Y_AXIS); } + #endif + #if HAS_Z_AXIS + else if (stepper.axis_is_moving(Z_AXIS)) { _ENDSTOP_HIT(Z, TERN(Z_HOME_TO_MIN, MIN, MAX)); planner.endstop_triggered(Z_AXIS); } + #endif G38_did_trigger = true; } #endif diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index b540c9a938..eb6dc6597c 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -266,7 +266,18 @@ void report_current_position_projected() { 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); + SERIAL_ECHOPAIR( + "X:", lpos.x + #if HAS_Y_AXIS + , " Y:", lpos.y + #endif + #if HAS_Z_AXIS + , " Z:", lpos.z + #endif + #if HAS_EXTRUDERS + , " E:", current_position.e + #endif + ); stepper.report_positions(); #if IS_SCARA @@ -692,8 +703,7 @@ void restore_feedrate_and_scaling() { * at the same positions relative to the machine. */ void update_software_endstops(const AxisEnum axis - OPTARG(HAS_HOTEND_OFFSET, const uint8_t old_tool_index/*=0*/) - OPTARG(HAS_HOTEND_OFFSET, const uint8_t new_tool_index/*=0*/) + OPTARG(HAS_HOTEND_OFFSET, const uint8_t old_tool_index/*=0*/, const uint8_t new_tool_index/*=0*/) ) { #if ENABLED(DUAL_X_CARRIAGE) @@ -929,7 +939,7 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) { float cartesian_mm = diff.magnitude(); // If the move is very short, check the E move distance - if (UNEAR_ZERO(cartesian_mm)) cartesian_mm = ABS(diff.e); + TERN_(HAS_EXTRUDERS, if (UNEAR_ZERO(cartesian_mm)) cartesian_mm = ABS(diff.e)); // No E move either? Game over. if (UNEAR_ZERO(cartesian_mm)) return true; @@ -1008,7 +1018,7 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) { // If the move is very short, check the E move distance // No E move either? Game over. float cartesian_mm = diff.magnitude(); - if (UNEAR_ZERO(cartesian_mm)) cartesian_mm = ABS(diff.e); + TERN_(HAS_EXTRUDERS, if (UNEAR_ZERO(cartesian_mm)) cartesian_mm = ABS(diff.e)); if (UNEAR_ZERO(cartesian_mm)) return; // The length divided by the segment size diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp index 2b3a189884..dae25feea3 100644 --- a/Marlin/src/module/probe.cpp +++ b/Marlin/src/module/probe.cpp @@ -245,6 +245,7 @@ xyz_pos_t Probe::offset; // Initialized by settings.load() void Probe::set_probing_paused(const bool dopause) { TERN_(PROBING_HEATERS_OFF, thermalManager.pause_heaters(dopause)); TERN_(PROBING_FANS_OFF, thermalManager.set_fans_paused(dopause)); + TERN_(PROBING_ESTEPPERS_OFF, if (dopause) disable_e_steppers()); #if ENABLED(PROBING_STEPPERS_OFF) IF_DISABLED(DELTA, static uint8_t old_trusted); if (dopause) { @@ -253,7 +254,7 @@ xyz_pos_t Probe::offset; // Initialized by settings.load() DISABLE_AXIS_X(); DISABLE_AXIS_Y(); #endif - disable_e_steppers(); + IF_DISABLED(PROBING_ESTEPPERS_OFF, disable_e_steppers()); } else { #if DISABLED(DELTA) diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 062049ec77..0ff909d7cc 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -314,26 +314,18 @@ xyze_int8_t Stepper::count_direction{0}; A##3_STEP_WRITE(V); \ } -#define QUAD_ENDSTOP_APPLY_STEP(A,V) \ - if (separate_multi_axis) { \ - if (ENABLED(A##_HOME_TO_MIN)) { \ - if (!(TEST(endstops.state(), A##_MIN) && count_direction[_AXIS(A)] < 0) && !locked_##A##_motor) A##_STEP_WRITE(V); \ - if (!(TEST(endstops.state(), A##2_MIN) && count_direction[_AXIS(A)] < 0) && !locked_##A##2_motor) A##2_STEP_WRITE(V); \ - if (!(TEST(endstops.state(), A##3_MIN) && count_direction[_AXIS(A)] < 0) && !locked_##A##3_motor) A##3_STEP_WRITE(V); \ - if (!(TEST(endstops.state(), A##4_MIN) && count_direction[_AXIS(A)] < 0) && !locked_##A##4_motor) A##4_STEP_WRITE(V); \ - } \ - else { \ - if (!(TEST(endstops.state(), A##_MAX) && count_direction[_AXIS(A)] > 0) && !locked_##A##_motor) A##_STEP_WRITE(V); \ - if (!(TEST(endstops.state(), A##2_MAX) && count_direction[_AXIS(A)] > 0) && !locked_##A##2_motor) A##2_STEP_WRITE(V); \ - if (!(TEST(endstops.state(), A##3_MAX) && count_direction[_AXIS(A)] > 0) && !locked_##A##3_motor) A##3_STEP_WRITE(V); \ - if (!(TEST(endstops.state(), A##4_MAX) && count_direction[_AXIS(A)] > 0) && !locked_##A##4_motor) A##4_STEP_WRITE(V); \ - } \ - } \ - else { \ - A##_STEP_WRITE(V); \ - A##2_STEP_WRITE(V); \ - A##3_STEP_WRITE(V); \ - A##4_STEP_WRITE(V); \ +#define QUAD_ENDSTOP_APPLY_STEP(A,V) \ + if (separate_multi_axis) { \ + if (!(TEST(endstops.state(), (TERN(A##_HOME_TO_MIN, A##_MIN, A##_MAX))) && count_direction[_AXIS(A)] < 0) && !locked_##A##_motor) A##_STEP_WRITE(V); \ + if (!(TEST(endstops.state(), (TERN(A##_HOME_TO_MIN, A##2_MIN, A##2_MAX))) && count_direction[_AXIS(A)] < 0) && !locked_##A##2_motor) A##2_STEP_WRITE(V); \ + if (!(TEST(endstops.state(), (TERN(A##_HOME_TO_MIN, A##3_MIN, A##3_MAX))) && count_direction[_AXIS(A)] < 0) && !locked_##A##3_motor) A##3_STEP_WRITE(V); \ + if (!(TEST(endstops.state(), (TERN(A##_HOME_TO_MIN, A##4_MIN, A##4_MAX))) && count_direction[_AXIS(A)] < 0) && !locked_##A##4_motor) A##4_STEP_WRITE(V); \ + } \ + else { \ + A##_STEP_WRITE(V); \ + A##2_STEP_WRITE(V); \ + A##3_STEP_WRITE(V); \ + A##4_STEP_WRITE(V); \ } #define QUAD_SEPARATE_APPLY_STEP(A,V) \ diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 9274d0631e..83187259ff 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -34,6 +34,7 @@ #include "temperature.h" #include "endstops.h" #include "planner.h" +#include "printcounter.h" #if EITHER(HAS_COOLER, LASER_COOLANT_FLOW_METER) #include "../feature/cooler.h" @@ -56,112 +57,56 @@ #include "../feature/host_actions.h" #endif -#define TEMP_SENSOR_IS_ANY_MAX_TC(n) (ENABLED(TEMP_SENSOR_##n##_IS_MAX_TC) || (ENABLED(TEMP_SENSOR_REDUNDANT_IS_MAX_TC) && ENABLED(TEMP_SENSOR_REDUNDANT_SOURCE) && TEMP_SENSOR_REDUNDANT_SOURCE == n)) - -// LIB_MAX31855 can be added to the build_flags in platformio.ini to use a user-defined library -#if LIB_USR_MAX31855 - #include - #if PIN_EXISTS(MAX31855_MISO) && PIN_EXISTS(MAX31855_SCK) - #define MAX31855_USES_SW_SPI 1 - #endif - #if TEMP_SENSOR_IS_MAX(0, MAX31855) && PIN_EXISTS(MAX31855_CS) - #define HAS_MAX31855_TEMP 1 - Adafruit_MAX31855 max31855_0 = Adafruit_MAX31855(MAX31855_CS_PIN - #if MAX31855_USES_SW_SPI - , MAX31855_MISO_PIN, MAX31855_SCK_PIN // For software SPI also set MISO/SCK - #endif - #if ENABLED(LARGE_PINMAP) - , HIGH - #endif - ); - #endif - #if TEMP_SENSOR_IS_MAX(1, MAX31855) && PIN_EXISTS(MAX31855_CS2) - #define HAS_MAX31855_TEMP 1 - Adafruit_MAX31855 max31855_1 = Adafruit_MAX31855(MAX31855_CS2_PIN - #if MAX31855_USES_SW_SPI - , MAX31855_MISO_PIN, MAX31855_SCK_PIN // For software SPI also set MISO/SCK - #endif - #if ENABLED(LARGE_PINMAP) - , HIGH - #endif - ); - #endif -#endif - -// LIB_MAX31865 can be added to the build_flags in platformio.ini to use a user-defined library. -// If LIB_MAX31865 is not on the build_flags then the Adafruit MAX31865 V1.1.0 library is used. -#if HAS_MAX31865 - #include - #ifndef MAX31865_MOSI_PIN - #define MAX31865_MOSI_PIN SD_MOSI_PIN - #endif - #if PIN_EXISTS(MAX31865_MISO) && PIN_EXISTS(MAX31865_SCK) - #define MAX31865_USES_SW_SPI 1 - #endif - #if TEMP_SENSOR_IS_MAX(0, MAX31865) && PIN_EXISTS(MAX31865_CS) - #define HAS_MAX31865_TEMP 1 - Adafruit_MAX31865 max31865_0 = Adafruit_MAX31865(MAX31865_CS_PIN - #if MAX31865_USES_SW_SPI && PIN_EXISTS(MAX31865_MOSI) - , MAX31865_MOSI_PIN, MAX31865_MISO_PIN, MAX31865_SCK_PIN // For software SPI also set MOSI/MISO/SCK - #endif - #if ENABLED(LARGE_PINMAP) - , HIGH - #endif - ); - #endif - #if TEMP_SENSOR_IS_MAX(1, MAX31865) && PIN_EXISTS(MAX31865_CS2) - #define HAS_MAX31865_TEMP 1 - Adafruit_MAX31865 max31865_1 = Adafruit_MAX31865(MAX31865_CS2_PIN - #if MAX31865_USES_SW_SPI && PIN_EXISTS(MAX31865_MOSI) - , MAX31865_MOSI_PIN, MAX31865_MISO_PIN, MAX31865_SCK_PIN // For software SPI also set MOSI/MISO/SCK - #endif - #if ENABLED(LARGE_PINMAP) - , HIGH - #endif - ); - #endif -#endif +// MAX TC related macros +#define TEMP_SENSOR_IS_MAX(n, M) (ENABLED(TEMP_SENSOR_##n##_IS_MAX##M) || (ENABLED(TEMP_SENSOR_REDUNDANT_IS_MAX##M) && TEMP_SENSOR_REDUNDANT_SOURCE == (n))) +#define TEMP_SENSOR_IS_ANY_MAX_TC(n) (ENABLED(TEMP_SENSOR_##n##_IS_MAX_TC) || (ENABLED(TEMP_SENSOR_REDUNDANT_IS_MAX_TC) && TEMP_SENSOR_REDUNDANT_SOURCE == n)) // LIB_MAX6675 can be added to the build_flags in platformio.ini to use a user-defined library -#if LIB_USR_MAX6675 +// If LIB_MAX6675 is not on the build_flags then raw SPI reads will be used. +#if HAS_MAX6675 && LIB_USR_MAX6675 #include - #if PIN_EXISTS(MAX6675_MISO) && PIN_EXISTS(MAX6675_SCK) - #define MAX6675_USES_SW_SPI 1 - #endif - #if TEMP_SENSOR_IS_MAX(0, MAX6675) && PIN_EXISTS(MAX6675_CS) - #define HAS_MAX6675_TEMP 1 - MAX6675 max6675_0 = MAX6675(MAX6675_CS_PIN - #if MAX6675_USES_SW_SPI - , MAX6675_MISO_PIN, MAX6675_SCK_PIN // For software SPI also set MISO/SCK - #endif - #if ENABLED(LARGE_PINMAP) - , HIGH - #endif - ); - #endif - #if TEMP_SENSOR_IS_MAX(1, MAX6675) && PIN_EXISTS(MAX6675_CS2) - #define HAS_MAX6675_TEMP 1 - MAX6675 max6675_1 = MAX6675(MAX6675_CS2_PIN - #if MAX6675_USES_SW_SPI - , MAX6675_MISO_PIN, MAX6675_SCK_PIN // For software SPI also set MISO/SCK - #endif - #if ENABLED(LARGE_PINMAP) - , HIGH - #endif - ); + #define HAS_MAX6675_LIBRARY 1 +#endif + +// LIB_MAX31855 can be added to the build_flags in platformio.ini to use a user-defined library. +// If LIB_MAX31855 is not on the build_flags then raw SPI reads will be used. +#if HAS_MAX31855 && LIB_USR_MAX31855 + #include + #define HAS_MAX31855_LIBRARY 1 + typedef Adafruit_MAX31855 MAX31855; +#endif + +#if HAS_MAX31865 + #if LIB_USR_MAX31865 + #include + typedef Adafruit_MAX31865 MAX31865; + #else + #include "../libs/MAX31865.h" #endif #endif -#if !HAS_MAX6675_TEMP && !HAS_MAX31855_TEMP && !HAS_MAX31865_TEMP - #define NO_THERMO_TEMPS 1 +#if HAS_MAX6675_LIBRARY || HAS_MAX31855_LIBRARY || HAS_MAX31865 + #define HAS_MAXTC_LIBRARIES 1 #endif -#if (TEMP_SENSOR_0_IS_MAX_TC || TEMP_SENSOR_1_IS_MAX_TC || TEMP_SENSOR_REDUNDANT_IS_MAX_TC) && PINS_EXIST(MAX6675_SCK, MAX6675_DO) && NO_THERMO_TEMPS - #define THERMO_SEPARATE_SPI 1 +// If we have a MAX TC with SCK and MISO pins defined, it's either on a separate/dedicated Hardware +// SPI bus, or some pins for Software SPI. Alternate Hardware SPI buses are not supported yet, so +// your SPI options are: +// +// 1. Only CS pin(s) defined: Hardware SPI on the default bus (usually the SD card SPI). +// 2. CS, MISO, and SCK pins defined: Software SPI on a separate bus, as defined by MISO, SCK. +// 3. CS, MISO, and SCK pins w/ FORCE_HW_SPI: Hardware SPI on the default bus, ignoring MISO, SCK. +// +#if TEMP_SENSOR_IS_ANY_MAX_TC(0) && TEMP_SENSOR_0_HAS_SPI_PINS && DISABLED(TEMP_SENSOR_FORCE_HW_SPI) + #define TEMP_SENSOR_0_USES_SW_SPI 1 +#endif +#if TEMP_SENSOR_IS_ANY_MAX_TC(1) && TEMP_SENSOR_1_HAS_SPI_PINS && DISABLED(TEMP_SENSOR_FORCE_HW_SPI) + #define TEMP_SENSOR_1_USES_SW_SPI 1 #endif -#if THERMO_SEPARATE_SPI +#if (TEMP_SENSOR_0_USES_SW_SPI || TEMP_SENSOR_1_USES_SW_SPI) && !HAS_MAXTC_LIBRARIES #include "../libs/private_spi.h" + #define HAS_MAXTC_SW_SPI 1 #endif #if ENABLED(PID_EXTRUSION_SCALING) @@ -172,8 +117,6 @@ #include "../feature/babystep.h" #endif -#include "printcounter.h" - #if ENABLED(FILAMENT_WIDTH_SENSOR) #include "../feature/filwidth.h" #endif @@ -246,7 +189,67 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, #define _E_PSTR(h,N) ((HOTENDS) > N && (h) == N) ? PSTR(LCD_STR_E##N) : #define HEATER_PSTR(h) _BED_PSTR(h) _CHAMBER_PSTR(h) _COOLER_PSTR(h) _E_PSTR(h,1) _E_PSTR(h,2) _E_PSTR(h,3) _E_PSTR(h,4) _E_PSTR(h,5) PSTR(LCD_STR_E0) -// public: +// +// Initialize MAX TC objects/SPI +// +#if HAS_MAX_TC + + #if HAS_MAXTC_SW_SPI + // Initialize SoftSPI for non-lib Software SPI; Libraries take care of it themselves. + template + SoftSPI SPIclass::softSPI; + SPIclass max_tc_spi; + #endif + + #define MAXTC_INIT(n, M) \ + MAX##M max##M##_##n = MAX##M( \ + TEMP_##n##_CS_PIN \ + OPTARG(_MAX31865_##n##_SW, TEMP_##n##_MOSI_PIN) \ + OPTARG(TEMP_SENSOR_##n##_USES_SW_SPI, TEMP_##n##_MISO_PIN, TEMP_##n##_SCK_PIN) \ + OPTARG(LARGE_PINMAP, HIGH) \ + ) + + #if HAS_MAX6675_LIBRARY + #if TEMP_SENSOR_IS_MAX(0, 6675) + MAXTC_INIT(0, 6675); + #endif + #if TEMP_SENSOR_IS_MAX(1, 6675) + MAXTC_INIT(1, 6675); + #endif + #endif + + #if HAS_MAX31855_LIBRARY + #if TEMP_SENSOR_IS_MAX(0, 31855) + MAXTC_INIT(0, 31855); + #endif + #if TEMP_SENSOR_IS_MAX(1, 31855) + MAXTC_INIT(1, 31855); + #endif + #endif + + // MAX31865 always uses a library, unlike '55 & 6675 + #if HAS_MAX31865 + #define _MAX31865_0_SW TEMP_SENSOR_0_USES_SW_SPI + #define _MAX31865_1_SW TEMP_SENSOR_1_USES_SW_SPI + + #if TEMP_SENSOR_IS_MAX(0, 31865) + MAXTC_INIT(0, 31865); + #endif + #if TEMP_SENSOR_IS_MAX(1, 31865) + MAXTC_INIT(1, 31865); + #endif + + #undef _MAX31865_0_SW + #undef _MAX31865_1_SW + #endif + + #undef MAXTC_INIT + +#endif + +/** + * public: + */ #if ENABLED(NO_FAN_SLOWING_IN_PID_TUNING) bool Temperature::adaptive_fan_slowing = true; @@ -274,6 +277,25 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, uint8_t Temperature::coolerfan_speed; // = 0 #endif +// Init fans according to whether they're native PWM or Software PWM +#ifdef BOARD_OPENDRAIN_MOSFETS + #define _INIT_SOFT_FAN(P) OUT_WRITE_OD(P, FAN_INVERTING ? LOW : HIGH) +#else + #define _INIT_SOFT_FAN(P) OUT_WRITE(P, FAN_INVERTING ? LOW : HIGH) +#endif +#if ENABLED(FAN_SOFT_PWM) + #define _INIT_FAN_PIN(P) _INIT_SOFT_FAN(P) +#else + #define _INIT_FAN_PIN(P) do{ if (PWM_PIN(P)) SET_PWM(P); else _INIT_SOFT_FAN(P); }while(0) +#endif +#if ENABLED(FAST_PWM_FAN) + #define SET_FAST_PWM_FREQ(P) set_pwm_frequency(P, FAST_PWM_FAN_FREQUENCY) +#else + #define SET_FAST_PWM_FREQ(P) NOOP +#endif +#define INIT_FAN_PIN(P) do{ _INIT_FAN_PIN(P); SET_FAST_PWM_FREQ(P); }while(0) + +// HAS_FAN does not include CONTROLLER_FAN #if HAS_FAN uint8_t Temperature::fan_speed[FAN_COUNT]; // = { 0 } @@ -419,7 +441,18 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, celsius_t Temperature::extrude_min_temp = EXTRUDE_MINTEMP; #endif -// private: +#if HAS_ADC_BUTTONS + uint32_t Temperature::current_ADCKey_raw = HAL_ADC_RANGE; + uint16_t Temperature::ADCKey_count = 0; +#endif + +#if ENABLED(PID_EXTRUSION_SCALING) + int16_t Temperature::lpq_len; // Initialized in settings.cpp +#endif + +/** + * private: + */ volatile bool Temperature::raw_temps_ready = false; @@ -472,16 +505,10 @@ volatile bool Temperature::raw_temps_ready = false; bool Temperature::paused_for_probing; #endif -// public: - -#if HAS_ADC_BUTTONS - uint32_t Temperature::current_ADCKey_raw = HAL_ADC_RANGE; - uint16_t Temperature::ADCKey_count = 0; -#endif - -#if ENABLED(PID_EXTRUSION_SCALING) - int16_t Temperature::lpq_len; // Initialized in settings.cpp -#endif +/** + * public: + * Class and Instance Methods + */ #if HAS_PID_HEATING @@ -758,10 +785,6 @@ volatile bool Temperature::raw_temps_ready = false; #endif // HAS_PID_HEATING -/** - * Class and Instance Methods - */ - int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { switch (heater_id) { #if HAS_HEATED_BED @@ -781,6 +804,16 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { #define _EFANOVERLAP(A,B) _FANOVERLAP(E##A,B) #if HAS_AUTO_FAN + #if EXTRUDER_AUTO_FAN_SPEED != 255 + #define INIT_E_AUTO_FAN_PIN(P) do{ if (P == FAN1_PIN || P == FAN2_PIN) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) + #else + #define INIT_E_AUTO_FAN_PIN(P) SET_OUTPUT(P) + #endif + #if CHAMBER_AUTO_FAN_SPEED != 255 + #define INIT_CHAMBER_AUTO_FAN_PIN(P) do{ if (P == FAN1_PIN || P == FAN2_PIN) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) + #else + #define INIT_CHAMBER_AUTO_FAN_PIN(P) SET_OUTPUT(P) + #endif #define CHAMBER_FAN_INDEX HOTENDS @@ -1668,11 +1701,6 @@ void Temperature::manage_heater() { } celsius_float_t Temperature::user_thermistor_to_deg_c(const uint8_t t_index, const int16_t raw) { - //#if (MOTHERBOARD == BOARD_RAMPS_14_EFB) - // static uint32_t clocks_total = 0; - // static uint32_t calls = 0; - // uint32_t tcnt5 = TCNT5; - //#endif if (!WITHIN(t_index, 0, COUNT(user_thermistor) - 1)) return 25; @@ -1700,14 +1728,6 @@ void Temperature::manage_heater() { value += t.sh_c_coeff * cu(log_resistance); value = 1.0f / value; - //#if (MOTHERBOARD == BOARD_RAMPS_14_EFB) - // int32_t clocks = TCNT5 - tcnt5; - // if (clocks >= 0) { - // clocks_total += clocks; - // calls++; - // } - //#endif - // Return degrees C (up to 999, as the LCD only displays 3 digits) return _MIN(value + THERMISTOR_ABS_ZERO_C, 999); } @@ -1730,7 +1750,14 @@ void Temperature::manage_heater() { #if TEMP_SENSOR_0_IS_CUSTOM return user_thermistor_to_deg_c(CTI_HOTEND_0, raw); #elif TEMP_SENSOR_0_IS_MAX_TC - return TERN(TEMP_SENSOR_0_IS_MAX31865, max31865_0.temperature(MAX31865_SENSOR_OHMS_0, MAX31865_CALIBRATION_OHMS_0), raw * 0.25); + #if TEMP_SENSOR_0_IS_MAX31865 + return TERN(LIB_INTERNAL_MAX31865, + max31865_0.temperature((uint16_t)raw), + max31865_0.temperature(MAX31865_SENSOR_OHMS_0, MAX31865_CALIBRATION_OHMS_0) + ); + #else + return raw * 0.25; + #endif #elif TEMP_SENSOR_0_IS_AD595 return TEMP_AD595(raw); #elif TEMP_SENSOR_0_IS_AD8495 @@ -1742,7 +1769,14 @@ void Temperature::manage_heater() { #if TEMP_SENSOR_1_IS_CUSTOM return user_thermistor_to_deg_c(CTI_HOTEND_1, raw); #elif TEMP_SENSOR_1_IS_MAX_TC - return TERN(TEMP_SENSOR_1_IS_MAX31865, max31865_1.temperature(MAX31865_SENSOR_OHMS_1, MAX31865_CALIBRATION_OHMS_1), raw * 0.25); + #if TEMP_SENSOR_0_IS_MAX31865 + return TERN(LIB_INTERNAL_MAX31865, + max31865_1.temperature((uint16_t)raw), + max31865_1.temperature(MAX31865_SENSOR_OHMS_1, MAX31865_CALIBRATION_OHMS_1) + ); + #else + return raw * 0.25; + #endif #elif TEMP_SENSOR_1_IS_AD595 return TEMP_AD595(raw); #elif TEMP_SENSOR_1_IS_AD8495 @@ -1901,9 +1935,9 @@ void Temperature::manage_heater() { #if TEMP_SENSOR_REDUNDANT_IS_CUSTOM return user_thermistor_to_deg_c(CTI_REDUNDANT, raw); #elif TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 0 - return TERN(TEMP_SENSOR_REDUNDANT_IS_MAX31865, max31865_0.temperature(MAX31865_SENSOR_OHMS_0, MAX31865_CALIBRATION_OHMS_0), raw * 0.25); + return TERN(TEMP_SENSOR_REDUNDANT_IS_MAX31865, max31865_0.temperature((uint16_t)raw), raw * 0.25); #elif TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 1 - return TERN(TEMP_SENSOR_REDUNDANT_IS_MAX31865, max31865_1.temperature(MAX31865_SENSOR_OHMS_1, MAX31865_CALIBRATION_OHMS_1), raw * 0.25); + return TERN(TEMP_SENSOR_REDUNDANT_IS_MAX31865, max31865_1.temperature((uint16_t)raw), raw * 0.25); #elif TEMP_SENSOR_REDUNDANT_IS_THERMISTOR SCAN_THERMISTOR_TABLE(TEMPTABLE_REDUNDANT, TEMPTABLE_REDUNDANT_LEN); #elif TEMP_SENSOR_REDUNDANT_IS_AD595 @@ -1936,6 +1970,7 @@ void Temperature::updateTemperaturesFromRawValues() { TERN_(TEMP_SENSOR_0_IS_MAX_TC, temp_hotend[0].raw = READ_MAX_TC(0)); TERN_(TEMP_SENSOR_1_IS_MAX_TC, temp_hotend[1].raw = READ_MAX_TC(1)); TERN_(TEMP_SENSOR_REDUNDANT_IS_MAX_TC, temp_redundant.raw = READ_MAX_TC(TEMP_SENSOR_REDUNDANT_SOURCE)); + #if HAS_HOTEND HOTEND_LOOP() temp_hotend[e].celsius = analog_to_celsius_hotend(temp_hotend[e].raw, e); #endif @@ -2008,40 +2043,7 @@ void Temperature::updateTemperaturesFromRawValues() { if (cutter.unitPower > 0 && COOLERCMP(temp_cooler.raw, maxtemp_raw_COOLER)) max_temp_error(H_COOLER); if (COOLERCMP(mintemp_raw_COOLER, temp_cooler.raw)) min_temp_error(H_COOLER); #endif -} - -#if THERMO_SEPARATE_SPI - template SoftSPI SPIclass::softSPI; - SPIclass max_tc_spi; -#endif - -// Init fans according to whether they're native PWM or Software PWM -#ifdef BOARD_OPENDRAIN_MOSFETS - #define _INIT_SOFT_FAN(P) OUT_WRITE_OD(P, FAN_INVERTING ? LOW : HIGH) -#else - #define _INIT_SOFT_FAN(P) OUT_WRITE(P, FAN_INVERTING ? LOW : HIGH) -#endif -#if ENABLED(FAN_SOFT_PWM) - #define _INIT_FAN_PIN(P) _INIT_SOFT_FAN(P) -#else - #define _INIT_FAN_PIN(P) do{ if (PWM_PIN(P)) SET_PWM(P); else _INIT_SOFT_FAN(P); }while(0) -#endif -#if ENABLED(FAST_PWM_FAN) - #define SET_FAST_PWM_FREQ(P) set_pwm_frequency(P, FAST_PWM_FAN_FREQUENCY) -#else - #define SET_FAST_PWM_FREQ(P) NOOP -#endif -#define INIT_FAN_PIN(P) do{ _INIT_FAN_PIN(P); SET_FAST_PWM_FREQ(P); }while(0) -#if EXTRUDER_AUTO_FAN_SPEED != 255 - #define INIT_E_AUTO_FAN_PIN(P) do{ if (P == FAN1_PIN || P == FAN2_PIN) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) -#else - #define INIT_E_AUTO_FAN_PIN(P) SET_OUTPUT(P) -#endif -#if CHAMBER_AUTO_FAN_SPEED != 255 - #define INIT_CHAMBER_AUTO_FAN_PIN(P) do{ if (P == FAN1_PIN || P == FAN2_PIN) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) -#else - #define INIT_CHAMBER_AUTO_FAN_PIN(P) SET_OUTPUT(P) -#endif +} // Temperature::updateTemperaturesFromRawValues /** * Initialize the temperature manager @@ -2070,36 +2072,47 @@ void Temperature::init() { #endif // Init (and disable) SPI thermocouples - #if TEMP_SENSOR_IS_MAX(0, MAX6675) && PIN_EXISTS(MAX6675_CS) - OUT_WRITE(MAX6675_CS_PIN, HIGH); + #if TEMP_SENSOR_IS_ANY_MAX_TC(0) && PIN_EXISTS(TEMP_0_CS) + OUT_WRITE(TEMP_0_CS_PIN, HIGH); #endif - #if TEMP_SENSOR_IS_MAX(1, MAX6675) && PIN_EXISTS(MAX6675_CS2) - OUT_WRITE(MAX6675_CS2_PIN, HIGH); - #endif - #if TEMP_SENSOR_IS_MAX(0, MAX6675) && PIN_EXISTS(MAX31855_CS) - OUT_WRITE(MAX31855_CS_PIN, HIGH); - #endif - #if TEMP_SENSOR_IS_MAX(1, MAX6675) && PIN_EXISTS(MAX31855_CS2) - OUT_WRITE(MAX31855_CS2_PIN, HIGH); - #endif - #if TEMP_SENSOR_IS_MAX(0, MAX6675) && PIN_EXISTS(MAX31865_CS) - OUT_WRITE(MAX31865_CS_PIN, HIGH); - #endif - #if TEMP_SENSOR_IS_MAX(1, MAX6675) && PIN_EXISTS(MAX31865_CS2) - OUT_WRITE(MAX31865_CS2_PIN, HIGH); + #if TEMP_SENSOR_IS_ANY_MAX_TC(1) && PIN_EXISTS(TEMP_1_CS) + OUT_WRITE(TEMP_1_CS_PIN, HIGH); #endif - #if HAS_MAX31865_TEMP - TERN_(TEMP_SENSOR_IS_MAX(0, MAX31865), max31865_0.begin(MAX31865_2WIRE)); // MAX31865_2WIRE, MAX31865_3WIRE, MAX31865_4WIRE - TERN_(TEMP_SENSOR_IS_MAX(1, MAX31865), max31865_1.begin(MAX31865_2WIRE)); - #endif - #if HAS_MAX31855_TEMP - TERN_(TEMP_SENSOR_IS_MAX(0, MAX31855), max31855_0.begin()); - TERN_(TEMP_SENSOR_IS_MAX(1, MAX31855), max31855_1.begin()); - #endif - #if HAS_MAX6675_TEMP - TERN_(TEMP_SENSOR_IS_MAX(0, MAX6675), max6675_0.begin()); - TERN_(TEMP_SENSOR_IS_MAX(1, MAX6675), max6675_1.begin()); + // Setup objects for library-based polling of MAX TCs + #if HAS_MAXTC_LIBRARIES + #define _MAX31865_WIRES(n) MAX31865_##n##WIRE + #define MAX31865_WIRES(n) _MAX31865_WIRES(n) + + #if TEMP_SENSOR_IS_MAX(0, 6675) && HAS_MAX6675_LIBRARY + max6675_0.begin(); + #elif TEMP_SENSOR_IS_MAX(0, 31855) && HAS_MAX31855_LIBRARY + max31855_0.begin(); + #elif TEMP_SENSOR_IS_MAX(0, 31865) + max31865_0.begin( + MAX31865_WIRES(MAX31865_SENSOR_WIRES_0) // MAX31865_2WIRE, MAX31865_3WIRE, MAX31865_4WIRE + OPTARG(LIB_INTERNAL_MAX31865, MAX31865_SENSOR_OHMS_0, MAX31865_CALIBRATION_OHMS_0) + ); + #if defined(LIB_INTERNAL_MAX31865) && ENABLED(MAX31865_50HZ_FILTER) + max31865_0.enable50HzFilter(1); + #endif + #endif + + #if TEMP_SENSOR_IS_MAX(1, 6675) && HAS_MAX6675_LIBRARY + max6675_1.begin(); + #elif TEMP_SENSOR_IS_MAX(1, 31855) && HAS_MAX31855_LIBRARY + max31855_1.begin(); + #elif TEMP_SENSOR_IS_MAX(1, 31865) + max31865_1.begin( + MAX31865_WIRES(MAX31865_SENSOR_WIRES_1) // MAX31865_2WIRE, MAX31865_3WIRE, MAX31865_4WIRE + OPTARG(LIB_INTERNAL_MAX31865, MAX31865_SENSOR_OHMS_1, MAX31865_CALIBRATION_OHMS_1) + ); + #if defined(LIB_INTERNAL_MAX31865) && ENABLED(MAX31865_50HZ_FILTER) + max31865_1.enable50HzFilter(1); + #endif + #endif + #undef MAX31865_WIRES + #undef _MAX31865_WIRES #endif #if MB(RUMBA) @@ -2138,7 +2151,6 @@ void Temperature::init() { OUT_WRITE(HEATER_0_PIN, HEATER_0_INVERTING); #endif #endif - #if HAS_HEATER_1 OUT_WRITE(HEATER_1_PIN, HEATER_1_INVERTING); #endif @@ -2205,7 +2217,9 @@ void Temperature::init() { INIT_FAN_PIN(CONTROLLER_FAN_PIN); #endif - TERN_(THERMO_SEPARATE_SPI, max_tc_spi.init()); + #if HAS_MAXTC_SW_SPI + max_tc_spi.init(); + #endif HAL_adc_init(); @@ -2304,11 +2318,7 @@ void Temperature::init() { INIT_CHAMBER_AUTO_FAN_PIN(CHAMBER_AUTO_FAN_PIN); #endif - // Wait for temperature measurement to settle - //delay(250); - #if HAS_HOTEND - #define _TEMP_MIN_E(NR) do{ \ 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; \ @@ -2372,7 +2382,6 @@ void Temperature::init() { #if _MINMAX_TEST(7, MAX) _TEMP_MAX_E(7); #endif - #endif // HAS_HOTEND #if HAS_HEATED_BED @@ -2506,9 +2515,8 @@ void Temperature::init() { void Temperature::disable_all_heaters() { + // Disable autotemp, unpause and reset everything TERN_(AUTOTEMP, planner.autotemp_enabled = false); - - // Unpause and reset everything TERN_(PROBING_HEATERS_OFF, pause_heaters(false)); #if HAS_HOTEND @@ -2544,8 +2552,6 @@ void Temperature::disable_all_heaters() { #if ENABLED(PRINTJOB_TIMER_AUTOSTART) - #include "printcounter.h" - bool Temperature::auto_job_over_threshold() { #if HAS_HOTEND HOTEND_LOOP() if (degTargetHotend(e) > (EXTRUDE_MINTEMP) / 2) return true; @@ -2564,7 +2570,7 @@ void Temperature::disable_all_heaters() { } } -#endif +#endif // PRINTJOB_TIMER_AUTOSTART #if ENABLED(PROBING_HEATERS_OFF) @@ -2602,7 +2608,7 @@ void Temperature::disable_all_heaters() { #endif } -#endif +#endif // SINGLENOZZLE_STANDBY_TEMP || SINGLENOZZLE_STANDBY_FAN #if HAS_MAX_TC @@ -2610,113 +2616,114 @@ void Temperature::disable_all_heaters() { #define THERMOCOUPLE_MAX_ERRORS 15 #endif - int Temperature::read_max_tc(TERN_(HAS_MULTI_MAX_TC, const uint8_t hindex/*=0*/)) { - #define MAX6675_HEAT_INTERVAL 250UL + /** + * @brief Read MAX Thermocouple temperature. + * + * Reads the thermocouple board via HW or SW SPI, using a library (LIB_USR_x) or raw SPI reads. + * Doesn't strictly return a temperature; returns an "ADC Value" (i.e. raw register content). + * + * @param hindex the hotend we're referencing (if MULTI_MAX_TC) + * @return integer representing the board's buffer, to be converted later if needed + */ + int16_t Temperature::read_max_tc(TERN_(HAS_MULTI_MAX_TC, const uint8_t hindex/*=0*/)) { + #define MAXTC_HEAT_INTERVAL 250UL - #if HAS_MAX31855_TEMP - static uint32_t max_tc_temp = 2000; - #define MAX_TC_ERROR_MASK 7 - #define MAX_TC_DISCARD_BITS 18 - #define MAX_TC_SPEED_BITS 3 // (_BV(SPR1)) // clock ÷ 64 - #elif HAS_MAX31865_TEMP - static uint16_t max_tc_temp = 2000; // From datasheet 16 bits D15-D0 - #define MAX_TC_ERROR_MASK 1 // D0 Bit not used + #if HAS_MAX31855 + #define MAX_TC_ERROR_MASK 7 // D2-0: SCV, SCG, OC + #define MAX_TC_DISCARD_BITS 18 // Data D31-18; sign bit D31 + #define MAX_TC_SPEED_BITS 3 // ~1MHz + #elif HAS_MAX31865 + #define MAX_TC_ERROR_MASK 1 // D0 Bit on fault only #define MAX_TC_DISCARD_BITS 1 // Data is in D15-D1 - #define MAX_TC_SPEED_BITS 3 // (_BV(SPR1)) // clock ÷ 64 - #else - static uint16_t max_tc_temp = 2000; - #define MAX_TC_ERROR_MASK 4 - #define MAX_TC_DISCARD_BITS 3 - #define MAX_TC_SPEED_BITS 2 // (_BV(SPR0)) // clock ÷ 16 + #define MAX_TC_SPEED_BITS 3 // ~1MHz + #else // MAX6675 + #define MAX_TC_ERROR_MASK 3 // D2 only; 1 = open circuit + #define MAX_TC_DISCARD_BITS 3 // Data D15-D1 + #define MAX_TC_SPEED_BITS 2 // ~2MHz #endif #if HAS_MULTI_MAX_TC // Needed to return the correct temp when this is called between readings - static celsius_t max_tc_temp_previous[MAX_TC_COUNT] = { 0 }; + static int16_t max_tc_temp_previous[MAX_TC_COUNT] = { 0 }; #define THERMO_TEMP(I) max_tc_temp_previous[I] #define THERMO_SEL(A,B) (hindex ? (B) : (A)) - #define MAX6675_WRITE(V) do{ switch (hindex) { case 1: WRITE(MAX6675_SS2_PIN, V); break; default: WRITE(MAX6675_SS_PIN, V); } }while(0) - #define MAX6675_SET_OUTPUT() do{ switch (hindex) { case 1: SET_OUTPUT(MAX6675_SS2_PIN); break; default: SET_OUTPUT(MAX6675_SS_PIN); } }while(0) + #define MAXTC_CS_WRITE(V) do{ switch (hindex) { case 1: WRITE(TEMP_1_CS_PIN, V); break; default: WRITE(TEMP_0_CS_PIN, V); } }while(0) #else + // When we have only 1 max tc, THERMO_SEL will pick the appropriate sensor + // variable, and MAXTC_*() macros will be hardcoded to the correct CS pin. constexpr uint8_t hindex = 0; #define THERMO_TEMP(I) max_tc_temp - #if TEMP_SENSOR_IS_ANY_MAX_TC(1) - #define THERMO_SEL(A,B) B - #else + #if TEMP_SENSOR_IS_ANY_MAX_TC(0) #define THERMO_SEL(A,B) A - #endif - #if TEMP_SENSOR_IS_MAX(0, MAX6675) - #define MAX6675_WRITE(V) WRITE(MAX6675_SS_PIN, V) - #define MAX6675_SET_OUTPUT() SET_OUTPUT(MAX6675_SS_PIN) + #define MAXTC_CS_WRITE(V) WRITE(TEMP_0_CS_PIN, V) #else - #define MAX6675_WRITE(V) WRITE(MAX6675_SS2_PIN, V) - #define MAX6675_SET_OUTPUT() SET_OUTPUT(MAX6675_SS2_PIN) + #define THERMO_SEL(A,B) B + #define MAXTC_CS_WRITE(V) WRITE(TEMP_1_CS_PIN, V) #endif - #endif + static TERN(HAS_MAX31855, uint32_t, uint16_t) max_tc_temp = THERMO_SEL( + TEMP_SENSOR_0_MAX_TC_TMAX, + TEMP_SENSOR_1_MAX_TC_TMAX + ); + static uint8_t max_tc_errors[MAX_TC_COUNT] = { 0 }; + static millis_t next_max_tc_ms[MAX_TC_COUNT] = { 0 }; // Return last-read value between readings - static millis_t next_max_tc_ms[MAX_TC_COUNT] = { 0 }; millis_t ms = millis(); - if (PENDING(ms, next_max_tc_ms[hindex])) return int(THERMO_TEMP(hindex)); - next_max_tc_ms[hindex] = ms + MAX6675_HEAT_INTERVAL; + if (PENDING(ms, next_max_tc_ms[hindex])) + return (int16_t)THERMO_TEMP(hindex); - // - // TODO: spiBegin, spiRec and spiInit doesn't work when soft spi is used. - // - #if !THERMO_SEPARATE_SPI && NO_THERMO_TEMPS - spiBegin(); - spiInit(MAX_TC_SPEED_BITS); - #endif + next_max_tc_ms[hindex] = ms + MAXTC_HEAT_INTERVAL; - #if NO_THERMO_TEMPS - MAX6675_WRITE(LOW); // enable TT_MAX6675 - DELAY_NS(100); // Ensure 100ns delay - #endif + #if !HAS_MAXTC_LIBRARIES + max_tc_temp = 0; - max_tc_temp = 0; + #if !HAS_MAXTC_SW_SPI + // Initialize SPI using the default Hardware SPI bus. + // FIXME: spiBegin, spiRec and spiInit doesn't work when soft spi is used. + spiBegin(); + spiInit(MAX_TC_SPEED_BITS); + #endif - // Read a big-endian temperature value - #if NO_THERMO_TEMPS + MAXTC_CS_WRITE(LOW); // enable MAXTC + DELAY_NS(100); // Ensure 100ns delay + + // Read a big-endian temperature value without using a library for (uint8_t i = sizeof(max_tc_temp); i--;) { - max_tc_temp |= TERN(THERMO_SEPARATE_SPI, max_tc_spi.receive(), spiRec()); + max_tc_temp |= TERN(HAS_MAXTC_SW_SPI, max_tc_spi.receive(), spiRec()); if (i > 0) max_tc_temp <<= 8; // shift left if not the last byte } - MAX6675_WRITE(HIGH); // disable TT_MAX6675 - #endif - #if HAS_MAX31855_TEMP - Adafruit_MAX31855 &max855ref = THERMO_SEL(max31855_0, max31855_1); - max_tc_temp = max855ref.readRaw32(); - #endif + MAXTC_CS_WRITE(HIGH); // disable MAXTC + #else + #if HAS_MAX6675_LIBRARY + MAX6675 &max6675ref = THERMO_SEL(max6675_0, max6675_1); + max_tc_temp = max6675ref.readRaw16(); + #endif - #if HAS_MAX31865_TEMP - Adafruit_MAX31865 &max865ref = THERMO_SEL(max31865_0, max31865_1); - #if ENABLED(LIB_USR_MAX31865) - max_tc_temp = max865ref.readRTD_with_Fault(); + #if HAS_MAX31855_LIBRARY + MAX31855 &max855ref = THERMO_SEL(max31855_0, max31855_1); + max_tc_temp = max855ref.readRaw32(); + #endif + + #if HAS_MAX31865 + MAX31865 &max865ref = THERMO_SEL(max31865_0, max31865_1); + max_tc_temp = TERN(LIB_INTERNAL_MAX31865, max865ref.readRaw(), max865ref.readRTD_with_Fault()); #endif #endif - #if HAS_MAX6675_TEMP - MAX6675 &max6675ref = THERMO_SEL(max6675_0, max6675_1); - max_tc_temp = max6675ref.readRaw16(); - #endif - - #if ENABLED(LIB_ADAFRUIT_MAX31865) - const uint8_t fault_31865 = max865ref.readFault() & 0x3FU; - #endif - - if (DISABLED(IGNORE_THERMOCOUPLE_ERRORS) - && TERN(LIB_ADAFRUIT_MAX31865, fault_31865, (max_tc_temp & MAX_TC_ERROR_MASK)) - ) { + // Handle an error. If there have been more than THERMOCOUPLE_MAX_ERRORS, send an error over serial. + // Either way, return the TMAX for the thermocouple to trigger a max_temp_error() + if (max_tc_temp & MAX_TC_ERROR_MASK) { max_tc_errors[hindex]++; + if (max_tc_errors[hindex] > THERMOCOUPLE_MAX_ERRORS) { SERIAL_ERROR_START(); SERIAL_ECHOPGM("Temp measurement error! "); - #if MAX_TC_ERROR_MASK == 7 - SERIAL_ECHOPGM("MAX31855 Fault : (", max_tc_temp & 0x7, ") >> "); + #if HAS_MAX31855 + SERIAL_ECHOPAIR("MAX31855 Fault: (", max_tc_temp & 0x7, ") >> "); if (max_tc_temp & 0x1) SERIAL_ECHOLNPGM("Open Circuit"); else if (max_tc_temp & 0x2) @@ -2724,59 +2731,46 @@ void Temperature::disable_all_heaters() { else if (max_tc_temp & 0x4) SERIAL_ECHOLNPGM("Short to VCC"); #elif HAS_MAX31865 - #if ENABLED(LIB_USR_MAX31865) - // At the present time we do not have the ability to set the MAX31865 HIGH threshold - // or thr LOW threshold, so no need to check for them, zero these bits out - const uint8_t fault_31865 = max865ref.readFault() & 0x3FU; - #endif + const uint8_t fault_31865 = max865ref.readFault(); max865ref.clearFault(); if (fault_31865) { SERIAL_EOL(); - SERIAL_ECHOLNPAIR("\nMAX31865 Fault :(", fault_31865, ") >>"); + SERIAL_ECHOLNPAIR("\nMAX31865 Fault: (", fault_31865, ") >>"); if (fault_31865 & MAX31865_FAULT_HIGHTHRESH) SERIAL_ECHOLNPGM("RTD High Threshold"); if (fault_31865 & MAX31865_FAULT_LOWTHRESH) SERIAL_ECHOLNPGM("RTD Low Threshold"); if (fault_31865 & MAX31865_FAULT_REFINLOW) - SERIAL_ECHOLNPGM("REFIN- > 0.85 x Bias"); + SERIAL_ECHOLNPGM("REFIN- > 0.85 x V bias"); if (fault_31865 & MAX31865_FAULT_REFINHIGH) - SERIAL_ECHOLNPGM("REFIN- < 0.85 x Bias - FORCE- open"); + SERIAL_ECHOLNPGM("REFIN- < 0.85 x V bias (FORCE- open)"); if (fault_31865 & MAX31865_FAULT_RTDINLOW) - SERIAL_ECHOLNPGM("REFIN- < 0.85 x Bias - FORCE- open"); + SERIAL_ECHOLNPGM("REFIN- < 0.85 x V bias (FORCE- open)"); if (fault_31865 & MAX31865_FAULT_OVUV) SERIAL_ECHOLNPGM("Under/Over voltage"); } - #else - SERIAL_ECHOLNPGM("MAX6675 Open Circuit"); + #else // MAX6675 + SERIAL_ECHOLNPGM("MAX6675 Fault: Open Circuit"); #endif - // Thermocouple open - max_tc_temp = 4 * THERMO_SEL(TEMP_SENSOR_0_MAX_TC_TMAX, TEMP_SENSOR_1_MAX_TC_TMAX); + // Set thermocouple above max temperature (TMAX) + max_tc_temp = THERMO_SEL(TEMP_SENSOR_0_MAX_TC_TMAX, TEMP_SENSOR_1_MAX_TC_TMAX) << (MAX_TC_DISCARD_BITS + 1); } - else - max_tc_temp >>= MAX_TC_DISCARD_BITS; } else { - max_tc_temp >>= MAX_TC_DISCARD_BITS; - max_tc_errors[hindex] = 0; + max_tc_errors[hindex] = 0; // No error bit, reset error count } - #if HAS_MAX31855 - if (max_tc_temp & 0x00002000) max_tc_temp |= 0xFFFFC000; // Support negative temperature - #endif + max_tc_temp >>= MAX_TC_DISCARD_BITS; - // Return the RTD resistance for MAX31865 for display in SHOW_TEMP_ADC_VALUES - #if HAS_MAX31865_TEMP - #if ENABLED(LIB_ADAFRUIT_MAX31865) - max_tc_temp = (uint32_t(max865ref.readRTD()) * THERMO_SEL(MAX31865_CALIBRATION_OHMS_0, MAX31865_CALIBRATION_OHMS_1)) >> 16; - #elif ENABLED(LIB_USR_MAX31865) - max_tc_temp = (uint32_t(max_tc_temp) * THERMO_SEL(MAX31865_CALIBRATION_OHMS_0, MAX31865_CALIBRATION_OHMS_1)) >> 16; - #endif + #if HAS_MAX31855 + // Support negative temperature for MAX38155 + if (max_tc_temp & 0x00002000) max_tc_temp |= 0xFFFFC000; #endif THERMO_TEMP(hindex) = max_tc_temp; - return int(max_tc_temp); + return (int16_t)max_tc_temp; } #endif // HAS_MAX_TC @@ -2801,16 +2795,16 @@ void Temperature::update_raw_temperatures() { temp_redundant.update(); #endif - TERN_(HAS_TEMP_ADC_2, temp_hotend[2].update()); - TERN_(HAS_TEMP_ADC_3, temp_hotend[3].update()); - TERN_(HAS_TEMP_ADC_4, temp_hotend[4].update()); - TERN_(HAS_TEMP_ADC_5, temp_hotend[5].update()); - TERN_(HAS_TEMP_ADC_6, temp_hotend[6].update()); - TERN_(HAS_TEMP_ADC_7, temp_hotend[7].update()); - TERN_(HAS_TEMP_ADC_BED, temp_bed.update()); + TERN_(HAS_TEMP_ADC_2, temp_hotend[2].update()); + TERN_(HAS_TEMP_ADC_3, temp_hotend[3].update()); + TERN_(HAS_TEMP_ADC_4, temp_hotend[4].update()); + TERN_(HAS_TEMP_ADC_5, temp_hotend[5].update()); + TERN_(HAS_TEMP_ADC_6, temp_hotend[6].update()); + TERN_(HAS_TEMP_ADC_7, temp_hotend[7].update()); + TERN_(HAS_TEMP_ADC_BED, temp_bed.update()); TERN_(HAS_TEMP_ADC_CHAMBER, temp_chamber.update()); - TERN_(HAS_TEMP_ADC_PROBE, temp_probe.update()); - TERN_(HAS_TEMP_ADC_COOLER, temp_cooler.update()); + TERN_(HAS_TEMP_ADC_PROBE, temp_probe.update()); + TERN_(HAS_TEMP_ADC_COOLER, temp_cooler.update()); TERN_(HAS_JOY_ADC_X, joystick.x.update()); TERN_(HAS_JOY_ADC_Y, joystick.y.update()); @@ -3451,7 +3445,7 @@ void Temperature::isr() { SERIAL_PRINT(t, SFP); #if ENABLED(SHOW_TEMP_ADC_VALUES) // Temperature MAX SPI boards do not have an OVERSAMPLENR defined - SERIAL_ECHOPAIR(" (", TERN(NO_THERMO_TEMPS, false, k == 'T') ? r : r * RECIPROCAL(OVERSAMPLENR)); + SERIAL_ECHOPAIR(" (", TERN(HAS_MAXTC_LIBRARIES, k == 'T', false) ? r : r * RECIPROCAL(OVERSAMPLENR)); SERIAL_CHAR(')'); #endif delay(2); diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index 3a8c506a5d..26c1dca8af 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -428,6 +428,15 @@ class Temperature { static heater_idle_t heater_idle[NR_HEATER_IDLE]; + #endif // HEATER_IDLE_TIMER + + #if HAS_ADC_BUTTONS + static uint32_t current_ADCKey_raw; + static uint16_t ADCKey_count; + #endif + + #if ENABLED(PID_EXTRUSION_SCALING) + static int16_t lpq_len; #endif private: @@ -486,15 +495,6 @@ class Temperature { #endif public: - #if HAS_ADC_BUTTONS - static uint32_t current_ADCKey_raw; - static uint16_t ADCKey_count; - #endif - - #if ENABLED(PID_EXTRUSION_SCALING) - static int16_t lpq_len; - #endif - /** * Instance Methods */ @@ -915,7 +915,7 @@ class Temperature { #else #define READ_MAX_TC(N) read_max_tc() #endif - static int read_max_tc(TERN_(HAS_MULTI_MAX_TC, const uint8_t hindex=0)); + static int16_t read_max_tc(TERN_(HAS_MULTI_MAX_TC, const uint8_t hindex=0)); #endif static void checkExtruderAutoFans(); diff --git a/Marlin/src/pins/linux/pins_RAMPS_LINUX.h b/Marlin/src/pins/linux/pins_RAMPS_LINUX.h index ab1446f07c..568086e066 100644 --- a/Marlin/src/pins/linux/pins_RAMPS_LINUX.h +++ b/Marlin/src/pins/linux/pins_RAMPS_LINUX.h @@ -133,11 +133,11 @@ #define TEMP_1_PIN 1 // Analog Input #define TEMP_BED_PIN 2 // Analog Input -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define TEMP_0_CS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define TEMP_0_CS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif // diff --git a/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h b/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h index 066c65be3a..f7e566e2d6 100644 --- a/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h +++ b/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h @@ -73,6 +73,19 @@ #endif #endif +// CS, MISO, MOSI, and SCK for MAX Thermocouple SPI +#if HAS_MAX_TC + //#define TEMP_0_CS_PIN P... + //#define TEMP_0_MISO_PIN P... + //#define TEMP_0_MOSI_PIN P... + //#define TEMP_0_SCK_PIN P... + + //#define TEMP_1_CS_PIN P... + //#define TEMP_1_MISO_PIN P... + //#define TEMP_1_MOSI_PIN P... + //#define TEMP_1_SCK_PIN P... +#endif + // // Heaters / Fans // diff --git a/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h b/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h index 83fcf36e4e..c25f676a08 100644 --- a/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h +++ b/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h @@ -248,8 +248,8 @@ #define PS_ON_PIN P2_12 // (12) -#if !defined(MAX6675_SS_PIN) && DISABLED(USE_ZMAX_PLUG) - #define MAX6675_SS_PIN P1_28 +#if !defined(TEMP_0_CS_PIN) && DISABLED(USE_ZMAX_PLUG) + #define TEMP_0_CS_PIN P1_28 #endif #if ENABLED(CASE_LIGHT_ENABLE) && !PIN_EXISTS(CASE_LIGHT) && !defined(SPINDLE_LASER_ENA_PIN) diff --git a/Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h b/Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h index 1e7b3f02a2..970a402b30 100644 --- a/Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h +++ b/Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h @@ -201,7 +201,15 @@ #define EXP1_09_PIN P0_16 #define EXP1_10_PIN P2_08 -#if HAS_WIRED_LCD +#if ENABLED(DWIN_CREALITY_LCD) + #error "DWIN_CREALITY_LCD requires a custom cable with TX = P0_15, RX = P0_16. Comment out this line to continue." + + #define BEEPER_PIN EXP1_10_PIN + #define BTN_EN1 EXP1_03_PIN + #define BTN_EN2 EXP1_04_PIN + #define BTN_ENC EXP1_06_PIN + +#elif HAS_WIRED_LCD #if ENABLED(CR10_STOCKDISPLAY) diff --git a/Marlin/src/pins/mega/pins_MALYAN_M180.h b/Marlin/src/pins/mega/pins_MALYAN_M180.h index e244d294f1..19095a5379 100644 --- a/Marlin/src/pins/mega/pins_MALYAN_M180.h +++ b/Marlin/src/pins/mega/pins_MALYAN_M180.h @@ -72,17 +72,17 @@ #define TEMP_BED_PIN 15 // Analog Input // Extruder thermocouples 0 and 1 are read out by two separate ICs using -// SPI for Max6675 Thermocouple +// SPI for MAX Thermocouple // Uses a separate SPI bus -#define THERMO_SCK_PIN 78 // E2 - SCK -#define THERMO_DO_PIN 3 // E5 - DO -#define THERMO_CS1_PIN 5 // E3 - CS0 -#define THERMO_CS2_PIN 2 // E4 - CS1 +#define TEMP_0_CS_PIN 5 // E3 - CS0 +#define TEMP_0_SCK_PIN 78 // E2 - SCK +#define TEMP_0_MISO_PIN 3 // E5 - MISO +//#define TEMP_0_MOSI_PIN ... // For MAX31865 -#define MAX6675_SS_PIN THERMO_CS1_PIN -#define MAX6675_SS2_PIN THERMO_CS2_PIN -#define MAX6675_SCK_PIN THERMO_SCK_PIN -#define MAX6675_DO_PIN THERMO_DO_PIN +#define TEMP_1_CS_PIN 2 // E4 - CS1 +#define TEMP_1_SCK_PIN TEMP_0_SCK_PIN +#define TEMP_1_MISO_PIN TEMP_0_MISO_PIN +//#define TEMP_1_MOSI_PIN TEMP_0_MOSI_PIN // // Heaters / Fans diff --git a/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h b/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h index 2531f10a7a..aea05134a8 100644 --- a/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h +++ b/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h @@ -125,7 +125,7 @@ // K7 - 69 / ADC15 - 15 #define TEMP_BED_PIN 15 -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple // Uses a separate SPI bus // // 3 E5 DO (SO) @@ -133,15 +133,15 @@ // 2 E4 CS2 // 78 E2 SCK // -#define THERMO_SCK_PIN 78 // E2 -#define THERMO_DO_PIN 3 // E5 -#define THERMO_CS1_PIN 5 // E3 -#define THERMO_CS2_PIN 2 // E4 +#define TEMP_0_CS_PIN 5 // E3 +#define TEMP_0_SCK_PIN 78 // E2 +#define TEMP_0_MISO_PIN 3 // E5 +//#define TEMP_0_MOSI_PIN ... // For MAX31865 -#define MAX6675_SS_PIN THERMO_CS1_PIN -#define MAX6675_SS2_PIN THERMO_CS2_PIN -#define MAX6675_SCK_PIN THERMO_SCK_PIN -#define MAX6675_DO_PIN THERMO_DO_PIN +#define TEMP_1_CS_PIN 2 // E4 +#define TEMP_1_SCK_PIN TEMP_0_SCK_PIN +#define TEMP_1_MISO_PIN TEMP_0_MISO_PIN +//#define TEMP_1_MOSI_PIN TEMP_0_MOSI_PIN // // Augmentation for auto-assigning plugs diff --git a/Marlin/src/pins/mega/pins_PICA.h b/Marlin/src/pins/mega/pins_PICA.h index 41afe5d891..47c101711c 100644 --- a/Marlin/src/pins/mega/pins_PICA.h +++ b/Marlin/src/pins/mega/pins_PICA.h @@ -118,11 +118,11 @@ #define SSR_PIN 6 -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define TEMP_0_CS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define TEMP_0_CS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif // diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index 88dd170a9e..1f53227553 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -610,11 +610,11 @@ #elif MB(VAKE403D) #include "stm32f4/pins_VAKE403D.h" // STM32F4 #elif MB(FYSETC_S6) - #include "stm32f4/pins_FYSETC_S6.h" // STM32F4 env:FYSETC_S6 + #include "stm32f4/pins_FYSETC_S6.h" // STM32F4 env:FYSETC_S6 env:FYSETC_S6_8000 #elif MB(FYSETC_S6_V2_0) - #include "stm32f4/pins_FYSETC_S6_V2_0.h" // STM32F4 env:FYSETC_S6 + #include "stm32f4/pins_FYSETC_S6_V2_0.h" // STM32F4 env:FYSETC_S6 env:FYSETC_S6_8000 #elif MB(FYSETC_SPIDER) - #include "stm32f4/pins_FYSETC_SPIDER.h" // STM32F4 env:FYSETC_S6 + #include "stm32f4/pins_FYSETC_SPIDER.h" // STM32F4 env:FYSETC_S6 env:FYSETC_S6_8000 #elif MB(FLYF407ZG) #include "stm32f4/pins_FLYF407ZG.h" // STM32F4 env:FLYF407ZG #elif MB(MKS_ROBIN2) diff --git a/Marlin/src/pins/pinsDebug_list.h b/Marlin/src/pins/pinsDebug_list.h index 1ab7188b70..8b1cad3a7c 100644 --- a/Marlin/src/pins/pinsDebug_list.h +++ b/Marlin/src/pins/pinsDebug_list.h @@ -760,17 +760,29 @@ #if PIN_EXISTS(LED_RED) REPORT_NAME_DIGITAL(__LINE__, LED_RED_PIN) #endif -#if PIN_EXISTS(MAX6675_DO) - REPORT_NAME_DIGITAL(__LINE__, MAX6675_DO_PIN) +#if PIN_EXISTS(TEMP_0_CS) + REPORT_NAME_DIGITAL(__LINE__, TEMP_0_CS_PIN) #endif -#if PIN_EXISTS(MAX6675_SCK) - REPORT_NAME_DIGITAL(__LINE__, MAX6675_SCK_PIN) +#if PIN_EXISTS(TEMP_0_SCK) + REPORT_NAME_DIGITAL(__LINE__, TEMP_0_SCK_PIN) #endif -#if PIN_EXISTS(MAX6675_SS) - REPORT_NAME_DIGITAL(__LINE__, MAX6675_SS_PIN) +#if PIN_EXISTS(TEMP_0_MOSI) + REPORT_NAME_DIGITAL(__LINE__, TEMP_0_MOSI_PIN) #endif -#if PIN_EXISTS(MAX6675_SS2) - REPORT_NAME_DIGITAL(__LINE__, MAX6675_SS2_PIN) +#if PIN_EXISTS(TEMP_0_MISO) + REPORT_NAME_DIGITAL(__LINE__, TEMP_0_MISO_PIN) +#endif +#if PIN_EXISTS(TEMP_1_CS) + REPORT_NAME_DIGITAL(__LINE__, TEMP_1_CS_PIN) +#endif +#if PIN_EXISTS(TEMP_1_SCK) + REPORT_NAME_DIGITAL(__LINE__, TEMP_1_SCK_PIN) +#endif +#if PIN_EXISTS(TEMP_1_MOSI) + REPORT_NAME_DIGITAL(__LINE__, TEMP_1_MOSI_PIN) +#endif +#if PIN_EXISTS(TEMP_1_MISO) + REPORT_NAME_DIGITAL(__LINE__, TEMP_1_MISO_PIN) #endif #if PIN_EXISTS(MAX7219_CLK) REPORT_NAME_DIGITAL(__LINE__, MAX7219_CLK_PIN) @@ -1010,18 +1022,6 @@ #if PIN_EXISTS(SUICIDE) REPORT_NAME_DIGITAL(__LINE__, SUICIDE_PIN) #endif -#if PIN_EXISTS(THERMO_CS1) - REPORT_NAME_DIGITAL(__LINE__, THERMO_CS1_PIN) -#endif -#if PIN_EXISTS(THERMO_CS2) - REPORT_NAME_DIGITAL(__LINE__, THERMO_CS2_PIN) -#endif -#if PIN_EXISTS(THERMO_DO) - REPORT_NAME_DIGITAL(__LINE__, THERMO_DO_PIN) -#endif -#if PIN_EXISTS(THERMO_SCK) - REPORT_NAME_DIGITAL(__LINE__, THERMO_SCK_PIN) -#endif #if PIN_EXISTS(TLC_BLANK) REPORT_NAME_DIGITAL(__LINE__, TLC_BLANK_PIN) #endif diff --git a/Marlin/src/pins/rambo/pins_RAMBO.h b/Marlin/src/pins/rambo/pins_RAMBO.h index 5d6f9c1fd0..f2d34dc00d 100644 --- a/Marlin/src/pins/rambo/pins_RAMBO.h +++ b/Marlin/src/pins/rambo/pins_RAMBO.h @@ -171,10 +171,10 @@ #define SPINDLE_DIR_PIN 32 // -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple // -#ifndef MAX6675_SS_PIN - #define MAX6675_SS_PIN 32 // SPINDLE_DIR_PIN / STAT_LED_BLUE_PIN +#ifndef TEMP_0_CS_PIN + #define TEMP_0_CS_PIN 32 // SPINDLE_DIR_PIN / STAT_LED_BLUE_PIN #endif // diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h b/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h index 383501caaa..34a4ceb27d 100644 --- a/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h +++ b/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h @@ -114,11 +114,11 @@ #define TEMP_1_PIN 15 // Analog Input #define TEMP_BED_PIN 14 // Analog Input -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define TEMP_0_CS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define TEMP_0_CS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif // diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h b/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h index ac0b7428f4..5f645e5d95 100644 --- a/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h +++ b/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h @@ -111,11 +111,11 @@ #define TEMP_1_PIN 15 // Analog Input #define TEMP_BED_PIN 3 // Analog Input -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define TEMP_0_CS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define TEMP_0_CS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif // diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h b/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h index 76a9fbe628..c953cff3d0 100644 --- a/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h +++ b/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h @@ -111,11 +111,11 @@ #define TEMP_1_PIN 15 // Analog Input #define TEMP_BED_PIN 14 // Analog Input -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define TEMP_0_CS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define TEMP_0_CS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif // diff --git a/Marlin/src/pins/ramps/pins_RAMPS.h b/Marlin/src/pins/ramps/pins_RAMPS.h index a4cf7e49bc..ed4f0057a9 100644 --- a/Marlin/src/pins/ramps/pins_RAMPS.h +++ b/Marlin/src/pins/ramps/pins_RAMPS.h @@ -167,10 +167,10 @@ #endif // -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple // -#ifndef MAX6675_SS_PIN - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card (SDSS) or 49 (SD_DETECT_PIN) +#ifndef TEMP_0_CS_PIN + #define TEMP_0_CS_PIN 66 // Don't use 53 if using Display/SD card (SDSS) or 49 (SD_DETECT_PIN) #endif // diff --git a/Marlin/src/pins/ramps/pins_RAMPS_OLD.h b/Marlin/src/pins/ramps/pins_RAMPS_OLD.h index a43ee3c6ca..9747666235 100644 --- a/Marlin/src/pins/ramps/pins_RAMPS_OLD.h +++ b/Marlin/src/pins/ramps/pins_RAMPS_OLD.h @@ -74,11 +74,11 @@ #define TEMP_0_PIN 2 // Analog Input #define TEMP_BED_PIN 1 // Analog Input -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card + #define TEMP_0_CS_PIN 66 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) + #define TEMP_0_CS_PIN 66 // Don't use 49 (SD_DETECT_PIN) #endif // diff --git a/Marlin/src/pins/ramps/pins_RIGIDBOARD.h b/Marlin/src/pins/ramps/pins_RIGIDBOARD.h index 345c51d5de..203af5e081 100644 --- a/Marlin/src/pins/ramps/pins_RIGIDBOARD.h +++ b/Marlin/src/pins/ramps/pins_RIGIDBOARD.h @@ -75,12 +75,12 @@ #define TEMP_1_PIN 13 // Analog Input #define TEMP_BED_PIN 15 // Analog Input -// SPI for Max6675 or Max31855 Thermocouple -#undef MAX6675_SS_PIN +// SPI for MAX Thermocouple +#undef TEMP_0_CS_PIN #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 // Don't use pin 53 if there is even the remote possibility of using Display/SD card + #define TEMP_0_CS_PIN 53 // Don't use pin 53 if there is even the remote possibility of using Display/SD card #else - #define MAX6675_SS_PIN 49 // Don't use pin 49 as this is tied to the switch inside the SD card socket to detect if there is an SD card present + #define TEMP_0_CS_PIN 49 // Don't use pin 49 as this is tied to the switch inside the SD card socket to detect if there is an SD card present #endif // diff --git a/Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h b/Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h index 53e419af00..de8db60847 100644 --- a/Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h +++ b/Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h @@ -123,11 +123,11 @@ #define TEMP_1_PIN 15 // Analog Input #define TEMP_BED_PIN 14 // Analog Input -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN -1 // Don't use 53 if using Display/SD card + #define TEMP_0_CS_PIN -1 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN -1 // Don't use 49 (SD_DETECT_PIN) + #define TEMP_0_CS_PIN -1 // Don't use 49 (SD_DETECT_PIN) #endif // diff --git a/Marlin/src/pins/ramps/pins_TT_OSCAR.h b/Marlin/src/pins/ramps/pins_TT_OSCAR.h index aba8f80e61..57a9a560d3 100644 --- a/Marlin/src/pins/ramps/pins_TT_OSCAR.h +++ b/Marlin/src/pins/ramps/pins_TT_OSCAR.h @@ -181,11 +181,11 @@ #define TEMP_4_PIN 12 #endif -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple //#if DISABLED(SDSUPPORT) -// #define MAX6675_SS_PIN 66 // Don't use 53 if using Display/SD card +// #define TEMP_0_CS_PIN 66 // Don't use 53 if using Display/SD card //#else -// #define MAX6675_SS_PIN 66 // Don't use 49 (SD_DETECT_PIN) +// #define TEMP_0_CS_PIN 66 // Don't use 49 (SD_DETECT_PIN) //#endif // diff --git a/Marlin/src/pins/sam/pins_DUE3DOM.h b/Marlin/src/pins/sam/pins_DUE3DOM.h index de3cb33e8d..81eca3e4b1 100644 --- a/Marlin/src/pins/sam/pins_DUE3DOM.h +++ b/Marlin/src/pins/sam/pins_DUE3DOM.h @@ -82,11 +82,11 @@ #define TEMP_2_PIN 5 // Analog Input (unused) #define TEMP_BED_PIN 1 // Analog Input (BED thermistor) -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN -1 + #define TEMP_0_CS_PIN -1 #else - #define MAX6675_SS_PIN -1 + #define TEMP_0_CS_PIN -1 #endif // diff --git a/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h b/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h index c52199a54d..bc0d29b00a 100644 --- a/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h +++ b/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h @@ -71,11 +71,11 @@ #define TEMP_2_PIN 5 // Analog Input (OnBoard thermistor beta 3950) #define TEMP_BED_PIN 1 // Analog Input (BED thermistor) -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 + #define TEMP_0_CS_PIN 53 #else - #define MAX6675_SS_PIN 53 + #define TEMP_0_CS_PIN 53 #endif // diff --git a/Marlin/src/pins/sam/pins_RADDS.h b/Marlin/src/pins/sam/pins_RADDS.h index 7b0ec5ab68..7a865b4ad8 100644 --- a/Marlin/src/pins/sam/pins_RADDS.h +++ b/Marlin/src/pins/sam/pins_RADDS.h @@ -179,11 +179,11 @@ #define TEMP_4_PIN 5 // dummy so will compile when PINS_DEBUGGING is enabled #define TEMP_BED_PIN 4 // Analog Input -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 + #define TEMP_0_CS_PIN 53 #else - #define MAX6675_SS_PIN 49 + #define TEMP_0_CS_PIN 49 #endif // diff --git a/Marlin/src/pins/sam/pins_RAMPS_DUO.h b/Marlin/src/pins/sam/pins_RAMPS_DUO.h index b1a6680c50..5b2b2f0b66 100644 --- a/Marlin/src/pins/sam/pins_RAMPS_DUO.h +++ b/Marlin/src/pins/sam/pins_RAMPS_DUO.h @@ -60,12 +60,12 @@ #undef TEMP_BED_PIN #define TEMP_BED_PIN 10 // Analog Input -// SPI for Max6675 or Max31855 Thermocouple -#undef MAX6675_SS_PIN +// SPI for MAX Thermocouple +#undef TEMP_0_CS_PIN #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 69 // Don't use 53 if using Display/SD card + #define TEMP_0_CS_PIN 69 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 69 // Don't use 49 (SD_DETECT_PIN) + #define TEMP_0_CS_PIN 69 // Don't use 49 (SD_DETECT_PIN) #endif // diff --git a/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h b/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h index e4c53530f7..30f209ad37 100644 --- a/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h +++ b/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h @@ -109,11 +109,11 @@ #define TEMP_2_PIN 3 // Analog Input #define TEMP_BED_PIN 0 // Analog Input -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 + #define TEMP_0_CS_PIN 53 #else - #define MAX6675_SS_PIN 49 + #define TEMP_0_CS_PIN 49 #endif // diff --git a/Marlin/src/pins/sam/pins_RAMPS_SMART.h b/Marlin/src/pins/sam/pins_RAMPS_SMART.h index 3882dfb944..96d0c9e1cc 100644 --- a/Marlin/src/pins/sam/pins_RAMPS_SMART.h +++ b/Marlin/src/pins/sam/pins_RAMPS_SMART.h @@ -94,12 +94,12 @@ #undef TEMP_BED_PIN #define TEMP_BED_PIN 11 // Analog Input -// SPI for Max6675 or Max31855 Thermocouple -#undef MAX6675_SS_PIN +// SPI for MAX Thermocouple +#undef TEMP_0_CS_PIN #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 67 // Don't use 53 if using Display/SD card + #define TEMP_0_CS_PIN 67 // Don't use 53 if using Display/SD card #else - #define MAX6675_SS_PIN 67 // Don't use 49 (SD_DETECT_PIN) + #define TEMP_0_CS_PIN 67 // Don't use 49 (SD_DETECT_PIN) #endif // diff --git a/Marlin/src/pins/sam/pins_RURAMPS4D_11.h b/Marlin/src/pins/sam/pins_RURAMPS4D_11.h index a52af48e11..b217428911 100644 --- a/Marlin/src/pins/sam/pins_RURAMPS4D_11.h +++ b/Marlin/src/pins/sam/pins_RURAMPS4D_11.h @@ -156,12 +156,12 @@ #define TEMP_5_PIN 6 // A6 (Marlin 2.0 not support) #endif -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple /* #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 + #define TEMP_0_CS_PIN 53 #else - #define MAX6675_SS_PIN 49 + #define TEMP_0_CS_PIN 49 #endif */ diff --git a/Marlin/src/pins/sam/pins_RURAMPS4D_13.h b/Marlin/src/pins/sam/pins_RURAMPS4D_13.h index 37ebb567a6..7002886908 100644 --- a/Marlin/src/pins/sam/pins_RURAMPS4D_13.h +++ b/Marlin/src/pins/sam/pins_RURAMPS4D_13.h @@ -142,12 +142,12 @@ #define TEMP_5_PIN 6 // A6 (Marlin 2.0 not support) #endif -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple /* #if DISABLED(SDSUPPORT) - #define MAX6675_SS_PIN 53 + #define TEMP_0_CS_PIN 53 #else - #define MAX6675_SS_PIN 49 + #define TEMP_0_CS_PIN 49 #endif */ diff --git a/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h b/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h index e567b0f5e1..a655d0121c 100644 --- a/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h +++ b/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h @@ -149,12 +149,11 @@ #define SD_MISO_PIN 74 #define SD_MOSI_PIN 75 -// SPI for Max6675 or Max31855 Thermocouple -#define MAX6675_SS_PIN 65 -#define MAX31855_SS0 65 -#define MAX31855_SS1 52 -#define MAX31855_SS2 50 -#define MAX31855_SS3 51 +// SPI for MAX Thermocouple +#define TEMP_0_CS_PIN 65 +#define TEMP_1_CS_PIN 52 +#define TEMP_2_CS_PIN 50 +#define TEMP_3_CS_PIN 51 #define ENC424_SS 61 diff --git a/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h index 5850f11ef0..8f305542a9 100644 --- a/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h +++ b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h @@ -117,14 +117,14 @@ /** * SKR Mini E3 V1.0, V1.2 SKR Mini E3 V2.0 - * _____ _____ - * 5V | 1 2 | GND 5V | 1 2 | GND - * (LCD_EN) PB7 | 3 4 | PB8 (LCD_RS) (LCD_EN) PB15 | 3 4 | PB8 (LCD_RS) - * (LCD_D4) PB9 | 5 6 PA10 (BTN_EN2) (LCD_D4) PB9 | 5 6 PA10 (BTN_EN2) - * RESET | 7 8 | PA9 (BTN_EN1) RESET | 7 8 | PA9 (BTN_EN1) - * (BTN_ENC) PB6 | 9 10| PB5 (BEEPER) (BTN_ENC) PA15 | 9 10| PB5 (BEEPER) - * ----- ----- - * EXP1 EXP1 + * ______ ______ + * 5V | 1 2 | GND 5V | 1 2 | GND + * (LCD_EN) PB7 | 3 4 | PB8 (LCD_RS) (LCD_EN) PB15 | 3 4 | PB8 (LCD_RS) + * (LCD_D4) PB9 | 5 6 PA10 (BTN_EN2) (LCD_D4) PB9 | 5 6 PA10 (BTN_EN2) + * RESET | 7 8 | PA9 (BTN_EN1) RESET | 7 8 | PA9 (BTN_EN1) + * (BTN_ENC) PB6 | 9 10 | PB5 (BEEPER) (BTN_ENC) PA15 | 9 10 | PB5 (BEEPER) + * ------ ------ + * EXP1 EXP1 */ #ifdef SKR_MINI_E3_V2 #define EXP1_9 PA15 @@ -134,7 +134,28 @@ #define EXP1_3 PB7 #endif -#if HAS_WIRED_LCD +#if ENABLED(DWIN_CREALITY_LCD) + /** + * ------ ------ ------ + * VCC | 1 2 | GND VCC | 1 2 | GND GND | 2 1 | VCC + * A | 3 4 | B A | 3 4 | B B | 4 3 | A + * | 5 6 TX BEEP | 5 6 ENT ENT | 6 5 | BEEP + * | 7 8 | RX TX | 7 8 | RX RX | 8 7 | TX + * BEEP | 9 10 | ENT | 9 10 | | 10 9 | + * ------ ------ ------ + * EXP1 DWIN DWIN (plug) + * + * All pins are labeled as printed on DWIN PCB. Connect TX-TX, A-A and so on. + */ + + #error "DWIN_CREALITY_LCD requires a custom cable, see diagram above this line. Comment out this line to continue." + + #define BEEPER_PIN EXP1_9 + #define BTN_EN1 EXP1_3 + #define BTN_EN2 PB8 + #define BTN_ENC PB5 + +#elif HAS_WIRED_LCD #if ENABLED(CR10_STOCKDISPLAY) @@ -184,19 +205,19 @@ * TFTGLCD_PANEL_SPI display pinout * * Board Display - * _____ _____ - * 5V | 1 2 | GND (SPI1-MISO) MISO | 1 2 | SCK (SPI1-SCK) - * (FREE) PB7 | 3 4 | PB8 (LCD_CS) (PA9) LCD_CS | 3 4 | SD_CS (PA10) - * (FREE) PB9 | 5 6 | PA10 (SD_CS) (FREE) | 5 6 | MOSI (SPI1-MOSI) - * RESET | 7 8 | PA9 (MOD_RESET) (PB5) SD_DET | 7 8 | (FREE) - * (BEEPER) PB6 | 9 10| PB5 (SD_DET) GND | 9 10| 5V - * ----- ----- - * EXP1 EXP1 + * ______ ______ + * 5V | 1 2 | GND (SPI1-MISO) MISO | 1 2 | SCK (SPI1-SCK) + * (FREE) PB7 | 3 4 | PB8 (LCD_CS) (PA9) LCD_CS | 3 4 | SD_CS (PA10) + * (FREE) PB9 | 5 6 | PA10 (SD_CS) (FREE) | 5 6 | MOSI (SPI1-MOSI) + * RESET | 7 8 | PA9 (MOD_RESET) (PB5) SD_DET | 7 8 | (FREE) + * (BEEPER) PB6 | 9 10 | PB5 (SD_DET) GND | 9 10 | 5V + * ------ ------ + * EXP1 EXP1 * * Needs custom cable: * - * Board Adapter Display - * _________ + * Board Display + * * EXP1-1 ----------- EXP1-10 * EXP1-2 ----------- EXP1-9 * SPI1-4 ----------- EXP1-6 @@ -223,17 +244,18 @@ #error "CAUTION! LCD_FYSETC_TFT81050 requires wiring modifications. See 'pins_BTT_SKR_MINI_E3_common.h' for details. Comment out this line to continue." - /** FYSETC TFT TFT81050 display pinout + /** + * FYSETC TFT TFT81050 display pinout * * Board Display - * _____ _____ - * 5V | 1 2 | GND (SPI1-MISO) MISO | 1 2 | SCK (SPI1-SCK) - * (FREE) PB7 | 3 4 | PB8 (LCD_CS) (PA9) MOD_RESET | 3 4 | SD_CS (PA10) - * (FREE) PB9 | 5 6 | PA10 (SD_CS) (PB8) LCD_CS | 5 6 | MOSI (SPI1-MOSI) - * RESET | 7 8 | PA9 (MOD_RESET) (PB5) SD_DET | 7 8 | RESET - * (BEEPER) PB6 | 9 10| PB5 (SD_DET) GND | 9 10| 5V - * ----- ----- - * EXP1 EXP1 + * ______ ______ + * 5V | 1 2 | GND (SPI1-MISO) MISO | 1 2 | SCK (SPI1-SCK) + * (FREE) PB7 | 3 4 | PB8 (LCD_CS) (PA9) MOD_RESET | 3 4 | SD_CS (PA10) + * (FREE) PB9 | 5 6 | PA10 (SD_CS) (PB8) LCD_CS | 5 6 | MOSI (SPI1-MOSI) + * RESET | 7 8 | PA9 (MOD_RESET) (PB5) SD_DET | 7 8 | RESET + * (BEEPER) PB6 | 9 10 | PB5 (SD_DET) GND | 9 10 | 5V + * ------ ------ + * EXP1 EXP1 * * Needs custom cable: * diff --git a/Marlin/src/pins/stm32f1/pins_MINGDA_MPX_ARM_MINI.h b/Marlin/src/pins/stm32f1/pins_MINGDA_MPX_ARM_MINI.h index 429cf14ac5..179c04a304 100644 --- a/Marlin/src/pins/stm32f1/pins_MINGDA_MPX_ARM_MINI.h +++ b/Marlin/src/pins/stm32f1/pins_MINGDA_MPX_ARM_MINI.h @@ -100,10 +100,10 @@ //#define TEMP_0_PIN PB3 // E0 K+ #define TEMP_BED_PIN PF7 // THERM_BED -#define MAX6675_SS_PIN PB5 -#define MAX6675_SCK_PIN PB3 -#define MAX6675_DO_PIN PB4 -#define MAX6675_MOSI_PIN PA14 +#define TEMP_0_CS_PIN PB5 +#define TEMP_0_SCK_PIN PB3 +#define TEMP_0_MISO_PIN PB4 +#define TEMP_0_MOSI_PIN PA14 // // Heaters / Fans diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h index b9f1074c7a..8da4dcc9de 100644 --- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h @@ -121,8 +121,8 @@ // // Thermocouples // -//#define MAX6675_SS_PIN PE5 // TC1 - CS1 -//#define MAX6675_SS_PIN PE6 // TC2 - CS2 +//#define TEMP_0_CS_PIN PE5 // TC1 - CS1 +//#define TEMP_0_CS_PIN PE6 // TC2 - CS2 // // Filament runout sensor diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h index ea3a7a1eea..0e2aee9e99 100644 --- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h @@ -124,8 +124,8 @@ // // Thermocouples // -//#define MAX6675_SS_PIN PE5 // TC1 - CS1 -//#define MAX6675_SS_PIN PE6 // TC2 - CS2 +//#define TEMP_0_CS_PIN PE5 // TC1 - CS1 +//#define TEMP_0_CS_PIN PE6 // TC2 - CS2 // // Misc. Functions diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h index 6ef3a08043..3a203aab49 100644 --- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h @@ -188,8 +188,8 @@ // // Thermocouples // -//#define MAX6675_SS_PIN PE5 // TC1 - CS1 -//#define MAX6675_SS_PIN PE6 // TC2 - CS2 +//#define TEMP_0_CS_PIN PE5 // TC1 - CS1 +//#define TEMP_0_CS_PIN PE6 // TC2 - CS2 // // Misc. Functions diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h index b56971c7a3..129b640d97 100644 --- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h @@ -175,8 +175,8 @@ /** * Note: MKS Robin Pro board is using SPI2 interface. Make sure your stm32duino library is configured accordingly */ -//#define MAX6675_SS_PIN PE5 // TC1 - CS1 -//#define MAX6675_SS_PIN PF11 // TC2 - CS2 +//#define TEMP_0_CS_PIN PE5 // TC1 - CS1 +//#define TEMP_0_CS_PIN PF11 // TC2 - CS2 #define POWER_LOSS_PIN PA2 // PW_DET #define PS_ON_PIN PG11 // PW_OFF 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 4438ed63ac..3151a38ae8 100644 --- a/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h +++ b/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h @@ -298,19 +298,19 @@ #define TEMP_BED_PIN PC0 // T0 <-> Bed -// SPI for Max6675 or Max31855 Thermocouple +// SPI for MAX Thermocouple // Uses a separate SPI bus -// If you have a two-way thermocouple, you can customize two THERMO_CSx_PIN pins (x:1~2) +// If you have a two-way thermocouple, you can customize two TEMP_x_CS_PIN pins (x:0~1) -#define THERMO_SCK_PIN PI1 // SCK -#define THERMO_DO_PIN PI2 // MISO -#define THERMO_CS1_PIN PH9 // GTR K-TEMP -#define THERMO_CS2_PIN PH2 // M5 K-TEMP +#define TEMP_0_CS_PIN PH9 // GTR K-TEMP +#define TEMP_0_SCK_PIN PI1 // SCK +#define TEMP_0_MISO_PIN PI2 // MISO +//#define TEMP_0_MOSI_PIN ... // For MAX31865 -#define MAX6675_SS_PIN THERMO_CS1_PIN -#define MAX6675_SS2_PIN THERMO_CS2_PIN -#define MAX6675_SCK_PIN THERMO_SCK_PIN -#define MAX6675_DO_PIN THERMO_DO_PIN +#define TEMP_1_CS_PIN PH2 // M5 K-TEMP +#define TEMP_1_SCK_PIN TEMP_0_SCK_PIN +#define TEMP_1_MISO_PIN TEMP_0_MISO_PIN +//#define TEMP_1_MOSI_PIN TEMP_0_MOSI_PIN // // Heaters / Fans diff --git a/Marlin/src/pins/stm32f4/pins_FYSETC_S6.h b/Marlin/src/pins/stm32f4/pins_FYSETC_S6.h index 7aeab0196a..504a86d7d0 100644 --- a/Marlin/src/pins/stm32f4/pins_FYSETC_S6.h +++ b/Marlin/src/pins/stm32f4/pins_FYSETC_S6.h @@ -56,7 +56,9 @@ // // Servos // -#define SERVO0_PIN PA3 +#ifndef SERVO0_PIN + #define SERVO0_PIN PA3 +#endif // // Limit Switches diff --git a/Marlin/src/pins/stm32f4/pins_FYSETC_SPIDER.h b/Marlin/src/pins/stm32f4/pins_FYSETC_SPIDER.h index a33f35bd55..e90ac552ae 100644 --- a/Marlin/src/pins/stm32f4/pins_FYSETC_SPIDER.h +++ b/Marlin/src/pins/stm32f4/pins_FYSETC_SPIDER.h @@ -68,6 +68,12 @@ // #define X_ENABLE_PIN PE9 +// +// Servos +// Z_MAX_PIN only works in input mode +// +#define SERVO0_PIN PA2 + #if HAS_TMC_UART #define X_SERIAL_TX_PIN PE7 #define X_SERIAL_RX_PIN PE7 diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_S.h b/Marlin/src/pins/stm32f4/pins_LERDGE_S.h index 105d0d6f60..65db99025c 100644 --- a/Marlin/src/pins/stm32f4/pins_LERDGE_S.h +++ b/Marlin/src/pins/stm32f4/pins_LERDGE_S.h @@ -104,16 +104,16 @@ // MAX6675 Cold-Junction-Compensated K-Thermocouple to Digital Converter (0°C to +1024°C) // https://datasheets.maximintegrated.com/en/ds/MAX6675.pdf -#define MAX6675_SCK_PIN PB3 // max6675 datasheet: SCK pin, found with multimeter, not tested -#define MAX6675_DO_PIN PB4 // max6675 datasheet: SO pin, found with multimeter, not tested -#define MAX6675_SS_PIN PC4 // max6675 datasheet: /CS pin, found with multimeter, not tested and likely wrong +#define TEMP_0_CS_PIN PC4 // max6675 datasheet: /CS pin, found with multimeter, not tested and likely wrong +#define TEMP_0_SCK_PIN PB3 // max6675 datasheet: SCK pin, found with multimeter, not tested +#define TEMP_0_MISO_PIN PB4 // max6675 datasheet: SO pin, found with multimeter, not tested // Expansion board with second max6675 // Warning: Some boards leave the slot unpopulated. -//#define MAX6675_SCK2_PIN PB3 // max6675 datasheet: SCK pin, found with multimeter, not tested -//#define MAX6675_DO2_PIN PB4 // max6675 datasheet: SO pin, found with multimeter, not tested -//#define MAX6675_SS2_PIN PF1 // max6675 datasheet: /CS pin, found with multimeter, not tested +//#define TEMP_1_CS_PIN PF1 // max6675 datasheet: /CS pin, found with multimeter, not tested +//#define TEMP_1_SCK_PIN PB3 // max6675 datasheet: SCK pin, found with multimeter, not tested +//#define TEMP_1_MISO_PIN PB4 // max6675 datasheet: SO pin, found with multimeter, not tested // // Heaters / Fans diff --git a/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h index 5a056b97cd..9ae2870a40 100644 --- a/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h +++ b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h @@ -172,8 +172,8 @@ // // Thermocouples // -//#define MAX6675_SS_PIN HEATER_0_PIN // TC1 - CS1 -//#define MAX6675_SS_PIN HEATER_1_PIN // TC2 - CS2 +//#define TEMP_0_CS_PIN HEATER_0_PIN // TC1 - CS1 +//#define TEMP_0_CS_PIN HEATER_1_PIN // TC2 - CS2 // // Misc. Functions diff --git a/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h index 2b0df002d3..0b9512a1cb 100644 --- a/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h +++ b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h @@ -189,8 +189,8 @@ // // Thermocouples // -//#define MAX6675_SS_PIN PE5 // TC1 - CS1 -//#define MAX6675_SS_PIN PE6 // TC2 - CS2 +//#define TEMP_0_CS_PIN PE5 // TC1 - CS1 +//#define TEMP_0_CS_PIN PE6 // TC2 - CS2 // // Misc. Functions diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 2b74480711..2e4f3e7643 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -262,54 +262,82 @@ void CardReader::selectByName(SdFile dir, const char * const match) { } } -// -// Recursive method to print all files within a folder in flat -// DOS 8.3 format. This style of listing is the most compatible -// with legacy hosts. -// -// This method recurses to unlimited depth and lists every -// G-code file within the given parent. If the hierarchy is -// very deep this can blow up the stack, so a 'depth' parameter -// (as with printListingJSON) would be a good addition. -// -void CardReader::printListing(SdFile parent, const char * const prepend/*=nullptr*/) { +/** + * Recursive method to print all files within a folder in flat + * DOS 8.3 format. This style of listing is the most compatible + * with legacy hosts. + * + * This method recurses to unlimited depth and lists all G-code + * files within the given parent. If the hierarchy is very deep + * this can blow up the stack, so a 'depth' parameter would be a + * good addition. + */ +void CardReader::printListing( + SdFile parent + OPTARG(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames/*=false*/) + , const char * const prepend/*=nullptr*/ + OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong/*=nullptr*/) +) { dir_t p; while (parent.readDir(&p, longFilename) > 0) { if (DIR_IS_SUBDIR(&p)) { - // Get the short name for the item, which we know is a folder - char dosFilename[FILENAME_LENGTH]; + size_t lenPrepend = prepend ? strlen(prepend) + 1 : 0; + // Allocate enough stack space for the full path including / separator + char path[lenPrepend + FILENAME_LENGTH]; + if (prepend) { + strcpy(path, prepend); + path[lenPrepend - 1] = '/'; + } + char* dosFilename = path + lenPrepend; createFilename(dosFilename, p); - // Allocate enough stack space for the full path to a folder, trailing slash, and nul - const bool prepend_is_empty = (!prepend || prepend[0] == '\0'); - const int len = (prepend_is_empty ? 1 : strlen(prepend)) + strlen(dosFilename) + 1 + 1; - char path[len]; - - // Append the FOLDERNAME12/ to the passed string. - // It contains the full path to the "parent" argument. - // We now have the full path to the item in this folder. - strcpy(path, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty - strcat(path, dosFilename); // FILENAME_LENGTH characters maximum - strcat(path, "/"); // 1 character - - // Serial.print(path); - // Get a new directory object using the full path // and dive recursively into it. SdFile child; // child.close() in destructor if (child.open(&parent, dosFilename, O_READ)) - printListing(child, path); + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + if (includeLongNames) { + size_t lenPrependLong = prependLong ? strlen(prependLong) + 1 : 0; + // Allocate enough stack space for the full long path including / separator + char pathLong[lenPrependLong + strlen(longFilename) + 1]; + if (prependLong) { + strcpy(pathLong, prependLong); + pathLong[lenPrependLong - 1] = '/'; + } + strcpy(pathLong + lenPrependLong, longFilename); + printListing(child, /*includeLongNames=*/true, path, pathLong); + } + else + #endif + printListing(child, path); else { SERIAL_ECHO_MSG(STR_SD_CANT_OPEN_SUBDIR, dosFilename); return; } } else if (is_dir_or_gcode(p)) { - if (prepend) SERIAL_ECHO(prepend); + if (prepend) { + SERIAL_ECHO(prepend); + SERIAL_CHAR('/'); + } SERIAL_ECHO(createFilename(filename, p)); SERIAL_CHAR(' '); - SERIAL_ECHOLN(p.fileSize); + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + if (!includeLongNames) + #endif + SERIAL_ECHOLN(p.fileSize); + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + else { + SERIAL_ECHO(p.fileSize); + SERIAL_CHAR(' '); + if (prependLong) { + SERIAL_ECHO(prependLong); + SERIAL_CHAR('/'); + } + SERIAL_ECHOLN(longFilename[0] ? longFilename : "???"); + } + #endif } } } @@ -317,10 +345,10 @@ void CardReader::printListing(SdFile parent, const char * const prepend/*=nullpt // // List all files on the SD card // -void CardReader::ls() { +void CardReader::ls(TERN_(LONG_FILENAME_HOST_SUPPORT, bool includeLongNames/*=false*/)) { if (flag.mounted) { root.rewind(); - printListing(root); + printListing(root OPTARG(LONG_FILENAME_HOST_SUPPORT, includeLongNames)); } } diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index 943cdae741..66cb97baeb 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -199,7 +199,7 @@ public: FORCE_INLINE static void getfilename_sorted(const uint16_t nr) { selectFileByIndex(nr); } #endif - static void ls(); + static void ls(TERN_(LONG_FILENAME_HOST_SUPPORT, bool includeLongNames=false)); #if ENABLED(POWER_LOSS_RECOVERY) static bool jobRecoverFileExists(); @@ -330,7 +330,12 @@ private: static int countItems(SdFile dir); static void selectByIndex(SdFile dir, const uint8_t index); static void selectByName(SdFile dir, const char * const match); - static void printListing(SdFile parent, const char * const prepend=nullptr); + static void printListing( + SdFile parent + OPTARG(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames=false) + , const char * const prepend=nullptr + OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong=nullptr) + ); #if ENABLED(SDCARD_SORT_ALPHA) static void flush_presort(); diff --git a/buildroot/share/PlatformIO/boards/marlin_blackSTM32F407VET6.json b/buildroot/share/PlatformIO/boards/marlin_blackSTM32F407VET6.json index 1765634086..a3f130c6b1 100644 --- a/buildroot/share/PlatformIO/boards/marlin_blackSTM32F407VET6.json +++ b/buildroot/share/PlatformIO/boards/marlin_blackSTM32F407VET6.json @@ -48,7 +48,7 @@ "upload": { "disable_flushing": false, "maximum_ram_size": 131072, - "maximum_size": 514288, + "maximum_size": 524288, "protocol": "stlink", "protocols": [ "stlink", diff --git a/buildroot/share/PlatformIO/boards/marlin_fysetc_s6.json b/buildroot/share/PlatformIO/boards/marlin_fysetc_s6.json index 286e46ffbd..42a203786d 100644 --- a/buildroot/share/PlatformIO/boards/marlin_fysetc_s6.json +++ b/buildroot/share/PlatformIO/boards/marlin_fysetc_s6.json @@ -21,7 +21,7 @@ "name": "3D Printer control board", "upload": { "maximum_ram_size": 131072, - "maximum_size": 524288, + "maximum_size": 458752, "protocol": "stlink", "protocols": [ "jlink", diff --git a/buildroot/share/PlatformIO/boards/marlin_fysetc_s6_8000.json b/buildroot/share/PlatformIO/boards/marlin_fysetc_s6_8000.json new file mode 100644 index 0000000000..1d808a23d7 --- /dev/null +++ b/buildroot/share/PlatformIO/boards/marlin_fysetc_s6_8000.json @@ -0,0 +1,35 @@ +{ + "build": { + "cpu": "cortex-m4", + "extra_flags": "-DSTM32F446xx", + "f_cpu": "180000000L", + "mcu": "stm32f446ret6", + "variant": "MARLIN_FYSETC_S6" + }, + "connectivity": [ + "can" + ], + "debug": { + "jlink_device": "STM32F446RE", + "openocd_target": "stm32f4x", + "svd_path": "STM32F446x.svd" + }, + "frameworks": [ + "arduino", + "stm32cube" + ], + "name": "3D Printer control board", + "upload": { + "maximum_ram_size": 131072, + "maximum_size": 491520, + "protocol": "stlink", + "protocols": [ + "jlink", + "stlink", + "blackmagic", + "serial" + ] + }, + "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html", + "vendor": "FYSETC" +} diff --git a/buildroot/share/PlatformIO/scripts/custom_board.py b/buildroot/share/PlatformIO/scripts/custom_board.py index 5d3ca3c652..e462738190 100644 --- a/buildroot/share/PlatformIO/scripts/custom_board.py +++ b/buildroot/share/PlatformIO/scripts/custom_board.py @@ -1,6 +1,9 @@ # # buildroot/share/PlatformIO/scripts/custom_board.py # +# - For build.address replace VECT_TAB_ADDR to relocate the firmware +# - For build.ldscript use one of the linker scripts in buildroot/share/PlatformIO/ldscripts +# import marlin board = marlin.env.BoardConfig() diff --git a/buildroot/share/PlatformIO/scripts/fix_framework_weakness.py b/buildroot/share/PlatformIO/scripts/fix_framework_weakness.py index 29705de442..fa91b7bb70 100644 --- a/buildroot/share/PlatformIO/scripts/fix_framework_weakness.py +++ b/buildroot/share/PlatformIO/scripts/fix_framework_weakness.py @@ -30,15 +30,3 @@ if env.MarlinFeatureIsEnabled("POSTMORTEM_DEBUGGING"): print("Done patching exception handler") print("Libmaple modified and ready for post mortem debugging") - -mf = env["MARLIN_FEATURES"] -rxBuf = mf["RX_BUFFER_SIZE"] if "RX_BUFFER_SIZE" in mf else "0" -txBuf = mf["TX_BUFFER_SIZE"] if "TX_BUFFER_SIZE" in mf else "0" -if int(rxBuf) < 64: - rxBuf = "64" -if int(txBuf) < 64: - txBuf = "64" - -build_flags = env.get('BUILD_FLAGS') -build_flags.append("-DUSART_RX_BUF_SIZE=" + rxBuf + " -DUSART_TX_BUF_SIZE=" + txBuf) -env.Replace(BUILD_FLAGS=build_flags) diff --git a/buildroot/share/PlatformIO/scripts/marlin.py b/buildroot/share/PlatformIO/scripts/marlin.py index 23c1b95742..3949037904 100644 --- a/buildroot/share/PlatformIO/scripts/marlin.py +++ b/buildroot/share/PlatformIO/scripts/marlin.py @@ -67,11 +67,3 @@ def encrypt_mks(source, target, env, new_name): def add_post_action(action): env.AddPostAction(join("$BUILD_DIR", "${PROGNAME}.bin"), action); - -# Apply customizations for a MKS Robin -def prepare_robin(address, ldname, fwname): - def encrypt(source, target, env): - encrypt_mks(source, target, env, fwname) - relocate_firmware(address) - custom_ld_script(ldname) - add_post_action(encrypt); diff --git a/buildroot/share/PlatformIO/scripts/mks_robin.py b/buildroot/share/PlatformIO/scripts/mks_robin.py index 8c5e4ae276..2dea7c615f 100644 --- a/buildroot/share/PlatformIO/scripts/mks_robin.py +++ b/buildroot/share/PlatformIO/scripts/mks_robin.py @@ -1,5 +1,5 @@ # # buildroot/share/PlatformIO/scripts/mks_robin.py # -import marlin -marlin.prepare_robin("0x08007000", "mks_robin.ld", "Robin.bin") +import robin +robin.prepare("0x08007000", "mks_robin.ld", "Robin.bin") diff --git a/buildroot/share/PlatformIO/scripts/mks_robin_e3.py b/buildroot/share/PlatformIO/scripts/mks_robin_e3.py index 7f6f538d6a..6ddeccbf80 100644 --- a/buildroot/share/PlatformIO/scripts/mks_robin_e3.py +++ b/buildroot/share/PlatformIO/scripts/mks_robin_e3.py @@ -1,5 +1,5 @@ # # buildroot/share/PlatformIO/scripts/mks_robin_e3.py # -import marlin -marlin.prepare_robin("0x08005000", "mks_robin_e3.ld", "Robin_e3.bin") +import robin +robin.prepare("0x08005000", "mks_robin_e3.ld", "Robin_e3.bin") diff --git a/buildroot/share/PlatformIO/scripts/mks_robin_e3p.py b/buildroot/share/PlatformIO/scripts/mks_robin_e3p.py index 1f3cacf873..5eeb93c096 100644 --- a/buildroot/share/PlatformIO/scripts/mks_robin_e3p.py +++ b/buildroot/share/PlatformIO/scripts/mks_robin_e3p.py @@ -1,5 +1,5 @@ # # buildroot/share/PlatformIO/scripts/mks_robin_e3p.py # -import marlin -marlin.prepare_robin("0x08007000", "mks_robin_e3p.ld", "Robin_e3p.bin") +import robin +robin.prepare("0x08007000", "mks_robin_e3p.ld", "Robin_e3p.bin") diff --git a/buildroot/share/PlatformIO/scripts/mks_robin_lite.py b/buildroot/share/PlatformIO/scripts/mks_robin_lite.py index b8c039ada8..c2018336fd 100644 --- a/buildroot/share/PlatformIO/scripts/mks_robin_lite.py +++ b/buildroot/share/PlatformIO/scripts/mks_robin_lite.py @@ -1,5 +1,5 @@ # # buildroot/share/PlatformIO/scripts/mks_robin_lite.py # -import marlin -marlin.prepare_robin("0x08005000", "mks_robin_lite.ld", "mksLite.bin") +import robin +robin.prepare("0x08005000", "mks_robin_lite.ld", "mksLite.bin") diff --git a/buildroot/share/PlatformIO/scripts/mks_robin_lite3.py b/buildroot/share/PlatformIO/scripts/mks_robin_lite3.py index bea8b80ace..42c8fb18b6 100644 --- a/buildroot/share/PlatformIO/scripts/mks_robin_lite3.py +++ b/buildroot/share/PlatformIO/scripts/mks_robin_lite3.py @@ -1,5 +1,5 @@ # # buildroot/share/PlatformIO/scripts/mks_robin_lite3.py # -import marlin -marlin.prepare_robin("0x08005000", "mks_robin_lite.ld", "mksLite3.bin") +import robin +robin.prepare("0x08005000", "mks_robin_lite.ld", "mksLite3.bin") diff --git a/buildroot/share/PlatformIO/scripts/mks_robin_mini.py b/buildroot/share/PlatformIO/scripts/mks_robin_mini.py index 3ff9ccf4a6..b0d8388653 100644 --- a/buildroot/share/PlatformIO/scripts/mks_robin_mini.py +++ b/buildroot/share/PlatformIO/scripts/mks_robin_mini.py @@ -1,5 +1,5 @@ # # buildroot/share/PlatformIO/scripts/mks_robin_mini.py # -import marlin -marlin.prepare_robin("0x08007000", "mks_robin_mini.ld", "Robin_mini.bin") +import robin +robin.prepare("0x08007000", "mks_robin_mini.ld", "Robin_mini.bin") diff --git a/buildroot/share/PlatformIO/scripts/mks_robin_nano.py b/buildroot/share/PlatformIO/scripts/mks_robin_nano.py index 319b4d4982..35e99830c4 100644 --- a/buildroot/share/PlatformIO/scripts/mks_robin_nano.py +++ b/buildroot/share/PlatformIO/scripts/mks_robin_nano.py @@ -1,5 +1,5 @@ # # buildroot/share/PlatformIO/scripts/mks_robin_nano.py # -import marlin -marlin.prepare_robin("0x08007000", "mks_robin_nano.ld", "Robin_nano.bin") +import robin +robin.prepare("0x08007000", "mks_robin_nano.ld", "Robin_nano.bin") diff --git a/buildroot/share/PlatformIO/scripts/mks_robin_nano35.py b/buildroot/share/PlatformIO/scripts/mks_robin_nano35.py index 310c3d6606..4a5726ad5b 100644 --- a/buildroot/share/PlatformIO/scripts/mks_robin_nano35.py +++ b/buildroot/share/PlatformIO/scripts/mks_robin_nano35.py @@ -1,5 +1,5 @@ # # buildroot/share/PlatformIO/scripts/mks_robin_nano35.py # -import marlin -marlin.prepare_robin("0x08007000", "mks_robin_nano.ld", "Robin_nano35.bin") +import robin +robin.prepare("0x08007000", "mks_robin_nano.ld", "Robin_nano35.bin") diff --git a/buildroot/share/PlatformIO/scripts/mks_robin_pro.py b/buildroot/share/PlatformIO/scripts/mks_robin_pro.py index c624663a33..60e2482bb0 100644 --- a/buildroot/share/PlatformIO/scripts/mks_robin_pro.py +++ b/buildroot/share/PlatformIO/scripts/mks_robin_pro.py @@ -1,5 +1,5 @@ # # buildroot/share/PlatformIO/scripts/mks_robin_pro.py # -import marlin -marlin.prepare_robin("0x08007000", "mks_robin_pro.ld", "Robin_pro.bin") +import robin +robin.prepare("0x08007000", "mks_robin_pro.ld", "Robin_pro.bin") diff --git a/buildroot/share/PlatformIO/scripts/robin.py b/buildroot/share/PlatformIO/scripts/robin.py new file mode 100644 index 0000000000..50d0d92d2f --- /dev/null +++ b/buildroot/share/PlatformIO/scripts/robin.py @@ -0,0 +1,12 @@ +# +# buildroot/share/PlatformIO/scripts/robin.py +# +import marlin + +# Apply customizations for a MKS Robin +def prepare(address, ldname, fwname): + def encrypt(source, target, env): + marlin.encrypt_mks(source, target, env, fwname) + marlin.relocate_firmware(address) + marlin.custom_ld_script(ldname) + marlin.add_post_action(encrypt); diff --git a/buildroot/share/PlatformIO/scripts/stm32_bootloader.py b/buildroot/share/PlatformIO/scripts/stm32_bootloader.py index eb28b901d2..f3b1b273a2 100644 --- a/buildroot/share/PlatformIO/scripts/stm32_bootloader.py +++ b/buildroot/share/PlatformIO/scripts/stm32_bootloader.py @@ -1,6 +1,13 @@ # # stm32_bootloader.py # +# - If 'build.offset' is provided, either by JSON or by the environment... +# - Set linker flag LD_FLASH_OFFSET and relocate the VTAB based on 'build.offset'. +# - Set linker flag LD_MAX_DATA_SIZE based on 'build.maximum_ram_size'. +# - Define STM32_FLASH_SIZE from 'upload.maximum_size' for use by Flash-based EEPROM emulation. +# +# - For 'board_build.rename' add a post-action to rename the firmware file. +# import os,sys,marlin Import("env") diff --git a/buildroot/share/PlatformIO/scripts/stm32_serialbuffer.py b/buildroot/share/PlatformIO/scripts/stm32_serialbuffer.py index 2be5a202ef..fecce47db3 100644 --- a/buildroot/share/PlatformIO/scripts/stm32_serialbuffer.py +++ b/buildroot/share/PlatformIO/scripts/stm32_serialbuffer.py @@ -13,11 +13,16 @@ Import("env") # # The script will set the value as the default one (64 bytes) # or the user-configured one, whichever is higher. +# +# Marlin has 128 and 32 as default values for RX_BUFFER_SIZE and +# TX_BUFFER_SIZE respectively. We use the highest value. mf = env["MARLIN_FEATURES"] -rxBuf = str(max(64, int(mf["RX_BUFFER_SIZE"]) if "RX_BUFFER_SIZE" in mf else 0)) +rxBuf = str(max(128, int(mf["RX_BUFFER_SIZE"]) if "RX_BUFFER_SIZE" in mf else 0)) txBuf = str(max(64, int(mf["TX_BUFFER_SIZE"]) if "TX_BUFFER_SIZE" in mf else 0)) build_flags = env.get('BUILD_FLAGS') build_flags.append("-DSERIAL_RX_BUFFER_SIZE=" + rxBuf) build_flags.append("-DSERIAL_TX_BUFFER_SIZE=" + txBuf) +build_flags.append("-DUSART_RX_BUF_SIZE=" + rxBuf) +build_flags.append("-DUSART_TX_BUF_SIZE=" + txBuf) env.Replace(BUILD_FLAGS=build_flags) diff --git a/buildroot/tests/BIGTREE_GTR_V1_0 b/buildroot/tests/BIGTREE_GTR_V1_0 index 24293a4932..58cbe4a142 100755 --- a/buildroot/tests/BIGTREE_GTR_V1_0 +++ b/buildroot/tests/BIGTREE_GTR_V1_0 @@ -20,11 +20,12 @@ exec_test $1 $2 "BigTreeTech GTR | 8 Extruders | Auto-Fan | Mixed TMC Drivers | restore_configs opt_set MOTHERBOARD BOARD_BTT_GTR_V1_0 SERIAL_PORT -1 \ - EXTRUDERS 6 TEMP_SENSOR_1 1 TEMP_SENSOR_2 1 TEMP_SENSOR_3 1 TEMP_SENSOR_4 1 TEMP_SENSOR_5 1 \ - NUM_Z_STEPPER_DRIVERS 3 \ - DEFAULT_Kp_LIST '{ 22.2, 20.0, 21.0, 19.0, 18.0, 17.0 }' DEFAULT_Ki_LIST '{ 1.08 }' DEFAULT_Kd_LIST '{ 114.0, 112.0, 110.0, 108.0 }' -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" + EXTRUDERS 5 TEMP_SENSOR_1 1 TEMP_SENSOR_2 1 TEMP_SENSOR_3 1 TEMP_SENSOR_4 1 \ + NUM_Z_STEPPER_DRIVERS 4 \ + DEFAULT_Kp_LIST '{ 22.2, 20.0, 21.0, 19.0, 18.0 }' DEFAULT_Ki_LIST '{ 1.08 }' DEFAULT_Kd_LIST '{ 114.0, 112.0, 110.0, 108.0 }' +opt_enable TOOLCHANGE_FILAMENT_SWAP TOOLCHANGE_MIGRATION_FEATURE TOOLCHANGE_FS_INIT_BEFORE_SWAP TOOLCHANGE_FS_PRIME_FIRST_USED \ + PID_PARAMS_PER_HOTEND Z_MULTI_ENDSTOPS +exec_test $1 $2 "BigTreeTech GTR | 6 Extruders | Quad Z + Endstops" "$3" restore_configs opt_set MOTHERBOARD BOARD_BTT_GTR_V1_0 SERIAL_PORT -1 \ diff --git a/buildroot/tests/rambo b/buildroot/tests/rambo index df2717c715..6b87d01a5e 100755 --- a/buildroot/tests/rambo +++ b/buildroot/tests/rambo @@ -32,7 +32,8 @@ opt_enable USE_ZMAX_PLUG REPRAP_DISCOUNT_SMART_CONTROLLER LCD_PROGRESS_BAR LCD_P SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE \ BACKLASH_COMPENSATION BACKLASH_GCODE BAUD_RATE_GCODE BEZIER_CURVE_SUPPORT \ FWRETRACT ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS \ - PSU_CONTROL AUTO_POWER_CONTROL POWER_LOSS_RECOVERY POWER_LOSS_PIN POWER_LOSS_STATE POWER_LOSS_RECOVER_ZHOME POWER_LOSS_ZHOME_POS \ + PSU_CONTROL PS_OFF_CONFIRM PS_OFF_SOUND AUTO_POWER_CONTROL \ + POWER_LOSS_RECOVERY POWER_LOSS_PIN POWER_LOSS_STATE POWER_LOSS_RECOVER_ZHOME POWER_LOSS_ZHOME_POS \ SLOW_PWM_HEATERS THERMAL_PROTECTION_CHAMBER LIN_ADVANCE EXTRA_LIN_ADVANCE_K \ HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT PINS_DEBUGGING MAX7219_DEBUG M114_DETAIL opt_add DEBUG_POWER_LOSS_RECOVERY @@ -114,10 +115,10 @@ opt_set MOTHERBOARD BOARD_RAMBO \ FAN_MIN_PWM 50 FAN_KICKSTART_TIME 100 \ XY_FREQUENCY_LIMIT 15 opt_enable COREYX USE_XMAX_PLUG MIXING_EXTRUDER GRADIENT_MIX \ - BABYSTEPPING BABYSTEP_DISPLAY_TOTAL FILAMENT_LCD_DISPLAY \ + BABYSTEPPING BABYSTEP_DISPLAY_TOTAL FILAMENT_LCD_DISPLAY FILAMENT_WIDTH_SENSOR \ REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER MENU_ADDAUTOSTART SDSUPPORT SDCARD_SORT_ALPHA \ ENDSTOP_NOISE_THRESHOLD FAN_SOFT_PWM \ - FIX_MOUNTED_PROBE AUTO_BED_LEVELING_LINEAR DEBUG_LEVELING_FEATURE FILAMENT_WIDTH_SENSOR PROBE_OFFSET_WIZARD \ + FIX_MOUNTED_PROBE PROBING_ESTEPPERS_OFF AUTO_BED_LEVELING_LINEAR DEBUG_LEVELING_FEATURE PROBE_OFFSET_WIZARD \ Z_SAFE_HOMING SHOW_TEMP_ADC_VALUES HOME_Y_BEFORE_X EMERGENCY_PARSER \ SD_ABORT_ON_ENDSTOP_HIT HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT ADVANCED_OK M114_DETAIL \ VOLUMETRIC_DEFAULT_ON NO_WORKSPACE_OFFSETS EXTRA_FAN_SPEED FWRETRACT \ diff --git a/ini/features.ini b/ini/features.ini index b9fae83c46..6dce2be4a4 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -27,9 +27,9 @@ HAS_TMC26X = TMC26XStepper=https://github.com/trinam src_filter=+ HAS_L64XX = Arduino-L6470@0.8.0 src_filter=+ + + + +LIB_INTERNAL_MAX31865 = src_filter=+ NEOPIXEL_LED = adafruit/Adafruit NeoPixel@~1.8.0 src_filter=+ -TEMP_.+_IS_MAX31865 = Adafruit MAX31865 library@~1.1.0 I2C_AMMETER = peterus/INA226Lib@1.1.2 USES_LIQUIDCRYSTAL = fmalpartida/LiquidCrystal@1.5.0 USES_LIQUIDCRYSTAL_I2C = marcoschwartz/LiquidCrystal_I2C@1.1.4 @@ -168,7 +168,7 @@ HAS_USER_THERMISTORS = src_filter=+ SD_ABORT_ON_ENDSTOP_HIT = src_filter=+ BAUD_RATE_GCODE = src_filter=+ HAS_SMART_EFF_MOD = src_filter=+ -COOLANT_CONTROL = src_filter=+ +COOLANT_CONTROL|AIR_ASSIST = src_filter=+ AIR_EVACUATION = src_filter=+ HAS_SOFTWARE_ENDSTOPS = src_filter=+ HAS_DUPLICATION_MODE = src_filter=+ diff --git a/ini/stm32f1-maple.ini b/ini/stm32f1-maple.ini index 25ebfb64b6..2580c4700c 100644 --- a/ini/stm32f1-maple.ini +++ b/ini/stm32f1-maple.ini @@ -36,6 +36,7 @@ lib_deps = ${common.lib_deps} platform_packages = tool-stm32duino extra_scripts = ${common.extra_scripts} pre:buildroot/share/PlatformIO/scripts/fix_framework_weakness.py + pre:buildroot/share/PlatformIO/scripts/stm32_serialbuffer.py # # STM32F103RC @@ -325,7 +326,8 @@ lib_ignore = ${common_stm32f1.lib_ignore} platform = ${common_stm32f1.platform} extends = common_stm32f1 board = marlin_CHITU_F103 -extra_scripts = pre:buildroot/share/PlatformIO/scripts/common-dependencies.py +extra_scripts = ${common_stm32f1.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/common-dependencies.py pre:buildroot/share/PlatformIO/scripts/STM32F1_create_variant.py buildroot/share/PlatformIO/scripts/chitu_crypt.py build_flags = ${common_stm32f1.build_flags} diff --git a/ini/stm32f1.ini b/ini/stm32f1.ini index dca640cd50..6c39d0b6fa 100644 --- a/ini/stm32f1.ini +++ b/ini/stm32f1.ini @@ -41,7 +41,6 @@ board = genericSTM32F103RC monitor_speed = 115200 board_build.core = stm32 board_build.variant = MARLIN_F103Rx -board_build.ldscript = ldscript.ld extra_scripts = ${common_stm32.extra_scripts} pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py buildroot/share/PlatformIO/scripts/stm32_bootloader.py @@ -108,7 +107,6 @@ extends = common_stm32 board = genericSTM32F103ZE board_build.core = stm32 board_build.variant = MARLIN_F103Zx -board_build.ldscript = ldscript.ld board_build.offset = 0x7000 board_build.encrypt = Robin.bin build_flags = ${common_stm32.build_flags} @@ -135,7 +133,7 @@ board_build.offset = 0x5000 board_build.encrypt = Robin_e3.bin board_upload.offset_address = 0x08005000 debug_tool = stlink -extra_scripts = ${env:STM32F103RC.extra_scripts} +extra_scripts = ${common_STM32F103RC.extra_scripts} buildroot/share/PlatformIO/scripts/mks_encrypt.py # @@ -150,10 +148,9 @@ monitor_speed = 115200 board_build.core = stm32 board_build.variant = MARLIN_F103Rx board_build.offset = 0x7000 -board_build.ldscript = ldscript.ld board_upload.offset_address = 0x08007000 build_unflags = ${common_stm32.build_unflags} -DUSBCON -DUSBD_USE_CDC -extra_scripts = ${common.extra_scripts} +extra_scripts = ${common_stm32.extra_scripts} pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py pre:buildroot/share/PlatformIO/scripts/random-bin.py buildroot/share/PlatformIO/scripts/stm32_bootloader.py @@ -175,10 +172,9 @@ monitor_speed = 115200 board_build.core = stm32 board_build.variant = MARLIN_F103Rx board_build.offset = 0x7000 -board_build.ldscript = ldscript.ld board_upload.offset_address = 0x08007000 build_unflags = ${common_stm32.build_unflags} -extra_scripts = ${common.extra_scripts} +extra_scripts = ${common_stm32.extra_scripts} pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py buildroot/share/PlatformIO/scripts/stm32_bootloader.py debug_tool = jlink @@ -207,7 +203,6 @@ build_flags = ${common_stm32.build_flags} -DMCU_STM32F103VE -DSS_TIMER= board = genericSTM32F103VE board_build.core = stm32 board_build.variant = MARLIN_F103Vx -board_build.ldscript = ldscript.ld board_build.offset = 0x7000 board_build.encrypt = Robin_mini.bin board_upload.offset_address = 0x08007000 @@ -227,7 +222,6 @@ build_flags = ${common_stm32.build_flags} -DMCU_STM32F103VE -DSS_TIMER= board = genericSTM32F103VE board_build.core = stm32 board_build.variant = MARLIN_F103Vx -board_build.ldscript = ldscript.ld board_build.offset = 0x7000 board_build.encrypt = Robin_nano35.bin board_upload.offset_address = 0x08007000 @@ -248,7 +242,6 @@ extends = common_stm32 board = genericSTM32F103ZE board_build.core = stm32 board_build.variant = MARLIN_F103Zx -board_build.ldscript = ldscript.ld board_build.offset = 0x10000 build_flags = ${common_stm32.build_flags} -DENABLE_HWSERIAL3 -DTIMER_SERIAL=TIM5 build_unflags = ${common_stm32.build_unflags} -DUSBCON -DUSBD_USE_CDC diff --git a/ini/stm32f4.ini b/ini/stm32f4.ini index dec7fea568..6067bbc3b8 100644 --- a/ini/stm32f4.ini +++ b/ini/stm32f4.ini @@ -76,15 +76,28 @@ platform = ${common_stm32.platform} extends = common_stm32 platform_packages = tool-stm32duino board = marlin_fysetc_s6 -build_flags = ${common_stm32.build_flags} - -DVECT_TAB_OFFSET=0x10000 - -DHAL_PCD_MODULE_ENABLED +build_flags = ${common_stm32.build_flags} -DVECT_TAB_OFFSET=0x10000 -DHAL_PCD_MODULE_ENABLED extra_scripts = ${common.extra_scripts} pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py debug_tool = stlink upload_protocol = dfu upload_command = dfu-util -a 0 -s 0x08010000:leave -D "$SOURCE" +# +# FYSETC S6 new bootloader +# +[env:FYSETC_S6_8000] +platform = ${common_stm32.platform} +extends = env:FYSETC_S6 +board = marlin_fysetc_s6_8000 +board_build.offset = 0x8000 +board_upload.offset_address = 0x08008000 +build_flags = ${common_stm32.build_flags} -DHAL_PCD_MODULE_ENABLED +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py + buildroot/share/PlatformIO/scripts/stm32_bootloader.py +upload_command = dfu-util -a 0 -s 0x08008000:leave -D "$SOURCE" + # # STM32F407VET6 with RAMPS-like shield # 'Black' STM32F407VET6 board - https://wiki.stm32duino.com/index.php?title=STM32F407 @@ -112,7 +125,6 @@ build_flags = ${common_stm32.build_flags} -DHAL_SD_MODULE_ENABLED -DHAL board = marlin_STM32F407VGT6_CCM board_build.core = stm32 board_build.variant = MARLIN_F4x7Vx -board_build.ldscript = ldscript.ld board_build.encrypt = firmware.srec # Just openblt.py (not stm32_bootloader.py) generates the file board_build.offset = 0x10000 @@ -222,7 +234,6 @@ extends = common_stm32 board = marlin_STM32F407VGT6_CCM board_build.core = stm32 board_build.variant = MARLIN_F4x7Vx -board_build.ldscript = ldscript.ld board_build.offset = 0x8000 board_upload.offset_address = 0x08008000 extra_scripts = ${common.extra_scripts} @@ -238,7 +249,7 @@ build_flags = ${stm_flash_drive.build_flags} [env:BIGTREE_OCTOPUS_V1] platform = ${common_stm32.platform} extends = common_stm32 -board = marlin_BigTree_octopus_v1 +board = marlin_BigTree_Octopus_v1 extra_scripts = ${common.extra_scripts} pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py build_flags = ${common_stm32.build_flags} @@ -344,7 +355,6 @@ upload_protocol = dfu monitor_speed = 500000 board_build.core = stm32 board_build.variant = MARLIN_F446VE -board_build.ldscript = ldscript.ld board_build.offset = 0x0000 extra_scripts = ${common.extra_scripts} pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py @@ -361,7 +371,6 @@ build_flags = ${stm_flash_drive.build_flags} board = genericSTM32F407VET6 board_build.core = stm32 board_build.variant = MARLIN_F4x7Vx -board_build.ldscript = ldscript.ld board_build.offset = 0x0000 board_upload.offset_address = 0x08000000 build_unflags = ${common_stm32.build_unflags} -DUSBCON -DUSBD_USE_CDC @@ -387,7 +396,6 @@ build_flags = ${common_stm32.build_flags} ${stm32f4_I2C1.build_flags} - board = marlin_STM32F407VGT6_CCM board_build.core = stm32 board_build.variant = MARLIN_F4x7Vx -board_build.ldscript = ldscript.ld board_build.rename = Robin_nano_v3.bin board_build.offset = 0xC000 board_upload.offset_address = 0x0800C000 diff --git a/platformio.ini b/platformio.ini index 8f4ce19159..aa78394014 100644 --- a/platformio.ini +++ b/platformio.ini @@ -574,6 +574,7 @@ default_src_filter = + - - + - - - - - - + - - - - -