From 0904be9100ded803b7093e8eb17217ca6392e4e1 Mon Sep 17 00:00:00 2001 From: InsanityAutomation Date: Sun, 23 Jun 2019 15:51:08 -0400 Subject: [PATCH] Partial --- Marlin/Configuration.h | 67 +- Marlin/Configuration_adv.h | 73 +- Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp | 51 +- Marlin/src/HAL/HAL_AVR/endstop_interrupts.h | 3 +- Marlin/src/HAL/HAL_AVR/fastio_AVR.h | 3 +- Marlin/src/HAL/HAL_DUE/DebugMonitor_Due.cpp | 3 +- Marlin/src/HAL/HAL_DUE/HAL_timers_Due.cpp | 1 - Marlin/src/HAL/HAL_DUE/ServoTimers.h | 20 +- Marlin/src/HAL/HAL_DUE/spi_pins.h | 13 +- .../HAL/HAL_DUE/u8g_com_HAL_DUE_sw_spi.cpp | 4 +- .../src/HAL/HAL_DUE/usb/udi_composite_desc.c | 12 +- Marlin/src/HAL/HAL_DUE/usb/usb_protocol_cdc.h | 2 + Marlin/src/HAL/HAL_ESP32/HAL.cpp | 5 +- Marlin/src/HAL/HAL_ESP32/HAL_Servo_ESP32.cpp | 6 +- Marlin/src/HAL/HAL_ESP32/HAL_spi_ESP32.cpp | 5 +- Marlin/src/HAL/HAL_ESP32/i2s.cpp | 3 +- Marlin/src/HAL/HAL_ESP32/i2s.h | 6 - Marlin/src/HAL/HAL_LINUX/hardware/Heater.cpp | 2 +- Marlin/src/HAL/HAL_LINUX/spi_pins.h | 3 +- Marlin/src/HAL/HAL_LPC1768/main.cpp | 6 +- Marlin/src/HAL/HAL_LPC1768/spi_pins.h | 2 +- Marlin/src/HAL/HAL_STM32/HAL.h | 1 + Marlin/src/HAL/HAL_STM32/HAL_spi_STM32.cpp | 3 +- Marlin/src/HAL/HAL_STM32F1/HAL.cpp | 23 +- Marlin/src/HAL/HAL_STM32F1/HAL.h | 3 + .../src/HAL/HAL_STM32F1/HAL_Servo_Stm32f1.cpp | 124 +- .../src/HAL/HAL_STM32F1/HAL_Servo_Stm32f1.h | 7 + .../src/HAL/HAL_STM32F1/HAL_sdio_STM32F1.cpp | 2 +- .../src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp | 51 +- Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h | 4 +- .../HAL_STM32F1/persistent_store_eeprom.cpp | 66 + .../HAL_STM32F1/persistent_store_sdcard.cpp | 2 +- Marlin/src/HAL/HAL_STM32F1/pinsDebug.h | 128 +- Marlin/src/HAL/HAL_STM32F1/spi_pins.h | 37 +- .../HAL/HAL_STM32F1/stm32f1_flag_script.py | 1 - .../HAL_STM32F1/u8g_com_stm32duino_fsmc.cpp | 10 +- .../HAL_STM32F1/u8g_com_stm32duino_swspi.cpp | 165 +++ .../src/HAL/HAL_STM32F1/watchdog_Stm32f1.cpp | 2 +- .../src/HAL/HAL_STM32F4/HAL_spi_STM32F4.cpp | 2 +- .../src/HAL/HAL_STM32F7/HAL_spi_STM32F7.cpp | 5 +- .../HAL/HAL_TEENSY31_32/HAL_spi_Teensy.cpp | 6 +- .../HAL/HAL_TEENSY35_36/HAL_Servo_Teensy.h | 4 +- .../HAL/HAL_TEENSY35_36/HAL_spi_Teensy.cpp | 79 +- .../HAL/HAL_TEENSY35_36/HAL_timers_Teensy.cpp | 1 - Marlin/src/HAL/shared/SpiEeprom.cpp | 3 +- Marlin/src/HAL/shared/persistent_store_api.h | 2 + Marlin/src/Marlin.cpp | 54 +- Marlin/src/core/boards.h | 359 +++--- Marlin/src/core/drivers.h | 9 + Marlin/src/core/macros.h | 8 +- Marlin/src/core/utility.cpp | 288 +---- Marlin/src/core/utility.h | 92 +- Marlin/src/feature/backlash.h | 2 + Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp | 5 +- Marlin/src/feature/bltouch.cpp | 6 +- Marlin/src/feature/bltouch.h | 18 +- Marlin/src/feature/caselight.cpp | 15 +- Marlin/src/feature/dac/dac_mcp4728.cpp | 21 +- Marlin/src/feature/dac/dac_mcp4728.h | 12 +- Marlin/src/feature/host_actions.cpp | 2 +- Marlin/src/feature/leds/leds.cpp | 21 +- Marlin/src/feature/leds/leds.h | 11 + Marlin/src/feature/leds/neopixel.cpp | 20 +- Marlin/src/feature/pause.cpp | 7 +- Marlin/src/feature/power_loss_recovery.cpp | 27 +- Marlin/src/feature/power_loss_recovery.h | 4 +- Marlin/src/feature/prusa_MMU2/mmu2.cpp | 2 +- Marlin/src/feature/tmc_util.cpp | 186 +-- Marlin/src/feature/tmc_util.h | 113 +- Marlin/src/gcode/bedlevel/abl/G29.cpp | 2 +- Marlin/src/gcode/bedlevel/mbl/G29.cpp | 4 +- Marlin/src/gcode/calibrate/G28.cpp | 10 +- Marlin/src/gcode/calibrate/G34_M422.cpp | 57 +- Marlin/src/gcode/calibrate/M100.cpp | 55 +- Marlin/src/gcode/config/M200-M205.cpp | 4 +- Marlin/src/gcode/config/M43.cpp | 17 +- Marlin/src/gcode/config/M540.cpp | 4 +- Marlin/src/gcode/config/M92.cpp | 2 + Marlin/src/gcode/control/M605.cpp | 7 +- Marlin/src/gcode/control/M7-M9.cpp | 63 + Marlin/src/gcode/control/M999.cpp | 3 +- Marlin/src/gcode/feature/L6470/M916-918.cpp | 14 +- .../src/gcode/feature/digipot/M907-M910.cpp | 10 +- Marlin/src/gcode/feature/pause/M600.cpp | 2 +- .../src/gcode/feature/trinamic/M911-M914.cpp | 20 +- Marlin/src/gcode/gcode.cpp | 110 +- Marlin/src/gcode/gcode.h | 56 +- Marlin/src/gcode/host/M110.cpp | 4 +- Marlin/src/gcode/motion/M290.cpp | 8 + Marlin/src/gcode/parser.cpp | 2 +- Marlin/src/gcode/queue.cpp | 229 ++-- Marlin/src/gcode/queue.h | 189 +-- Marlin/src/gcode/sdcard/M28_M29.cpp | 2 +- Marlin/src/inc/Conditionals_LCD.h | 29 +- Marlin/src/inc/Conditionals_post.h | 8 +- Marlin/src/inc/SanityCheck.h | 264 ++-- Marlin/src/inc/Version.h | 4 +- Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp | 1 + Marlin/src/lcd/HD44780/ultralcd_HD44780.h | 1 - Marlin/src/lcd/dogm/HAL_LCD_com_defines.h | 19 +- Marlin/src/lcd/dogm/dogm_Statusscreen.h | 103 +- Marlin/src/lcd/dogm/status_screen_DOGM.cpp | 51 +- ...8g_dev_tft_320x240_upscale_from_128x64.cpp | 2 +- Marlin/src/lcd/dogm/ultralcd_DOGM.cpp | 3 +- .../extensible_ui/lib/dgus/DGUSDisplay.cpp | 1090 +++++++++++++++++ .../lcd/extensible_ui/lib/dgus/DGUSDisplay.h | 236 ++++ .../lib/dgus/DGUSDisplayDefinition.cpp | 231 ++++ .../lib/dgus/DGUSDisplayDefinition.h | 192 +++ .../extensible_ui/lib/dgus/DGUSVPVariable.h | 47 + Marlin/src/lcd/extensible_ui/ui_api.cpp | 102 +- Marlin/src/lcd/extensible_ui/ui_api.h | 2 +- Marlin/src/lcd/extui_dgus_lcd.cpp | 81 ++ .../lib/example.cpp => extui_example.cpp} | 10 +- .../{malyanlcd.cpp => extui_malyan_lcd.cpp} | 14 +- Marlin/src/lcd/language/language_de.h | 15 +- Marlin/src/lcd/language/language_en.h | 5 +- Marlin/src/lcd/language/language_fr.h | 24 +- Marlin/src/lcd/language/language_it.h | 7 +- Marlin/src/lcd/language/language_sk.h | 24 +- Marlin/src/lcd/menu/menu.cpp | 10 +- Marlin/src/lcd/menu/menu.h | 5 +- Marlin/src/lcd/menu/menu_advanced.cpp | 20 +- Marlin/src/lcd/menu/menu_bed_corners.cpp | 2 +- Marlin/src/lcd/menu/menu_bed_leveling.cpp | 10 +- Marlin/src/lcd/menu/menu_configuration.cpp | 38 +- Marlin/src/lcd/menu/menu_custom.cpp | 2 +- Marlin/src/lcd/menu/menu_delta_calibrate.cpp | 2 +- Marlin/src/lcd/menu/menu_filament.cpp | 4 +- Marlin/src/lcd/menu/menu_info.cpp | 19 + Marlin/src/lcd/menu/menu_job_recovery.cpp | 2 +- Marlin/src/lcd/menu/menu_main.cpp | 101 +- Marlin/src/lcd/menu/menu_temperature.cpp | 5 +- Marlin/src/lcd/menu/menu_tmc.cpp | 2 +- Marlin/src/lcd/menu/menu_ubl.cpp | 70 +- Marlin/src/lcd/thermistornames.h | 2 + Marlin/src/lcd/ultralcd.cpp | 177 ++- Marlin/src/lcd/ultralcd.h | 10 +- Marlin/src/libs/crc16.cpp | 32 + Marlin/src/libs/crc16.h | 26 + Marlin/src/libs/numtostr.cpp | 289 +++++ Marlin/src/libs/numtostr.h | 92 ++ Marlin/src/module/configuration_store.cpp | 34 +- Marlin/src/module/endstops.cpp | 6 +- Marlin/src/module/planner.cpp | 11 +- Marlin/src/module/planner.h | 4 +- Marlin/src/module/probe.cpp | 122 +- Marlin/src/module/stepper.h | 15 +- Marlin/src/module/stepper_indirection.cpp | 200 +-- Marlin/src/module/stepper_indirection.h | 125 +- Marlin/src/module/temperature.cpp | 116 +- Marlin/src/module/temperature.h | 4 +- Marlin/src/module/thermistor/thermistor_18.h | 58 + Marlin/src/module/thermistor/thermistors.h | 3 + Marlin/src/module/tool_change.cpp | 50 +- Marlin/src/pins/pins.h | 10 + Marlin/src/pins/pinsDebug_list.h | 6 + Marlin/src/pins/pins_AZTEEG_X3.h | 6 +- Marlin/src/pins/pins_AZTEEG_X3_PRO.h | 56 +- Marlin/src/pins/pins_BIGTREE_SKR_MINI_V1_1.h | 181 +++ Marlin/src/pins/pins_BIGTREE_SKR_V1.3.h | 4 +- Marlin/src/pins/pins_BQ_ZUM_MEGA_3D.h | 8 +- Marlin/src/pins/pins_EINSTART-S.h | 64 +- Marlin/src/pins/pins_ESP32.h | 16 +- Marlin/src/pins/pins_FYSETC_F6_13.h | 2 +- Marlin/src/pins/pins_GT2560_V3.h | 30 +- Marlin/src/pins/pins_GT2560_V3_MC2.h | 11 +- Marlin/src/pins/pins_JGAURORA_A5S_A1.h | 125 ++ Marlin/src/pins/pins_MELZI_CREALITY.h | 3 +- Marlin/src/pins/pins_MIGHTYBOARD_REVE.h | 185 ++- Marlin/src/pins/pins_MKS_SBASE.h | 4 +- Marlin/src/pins/pins_MKS_SGEN.h | 2 +- Marlin/src/pins/pins_RAMBO.h | 6 + Marlin/src/pins/pins_RAMPS.h | 42 +- Marlin/src/pins/pins_RAMPS_DAGOMA.h | 39 + Marlin/src/pins/pins_RAMPS_FD_V1.h | 4 +- Marlin/src/pins/pins_RAMPS_LINUX.h | 4 +- Marlin/src/pins/pins_RAMPS_RE_ARM.h | 4 +- Marlin/src/pins/pins_TRIGORILLA_14.h | 10 + Marlin/src/pins/pins_TRONXY_V3_1_0.h | 8 +- Marlin/src/pins/pins_Z_BOLT_X_SERIES.h | 257 ++++ Marlin/src/sd/cardreader.cpp | 24 +- Marlin/src/sd/cardreader.h | 11 +- Marlin/src/sd/usb_flashdrive/lib/Usb.cpp | 2 +- 183 files changed, 6296 insertions(+), 2238 deletions(-) create mode 100644 Marlin/src/HAL/HAL_STM32F1/persistent_store_eeprom.cpp create mode 100644 Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_swspi.cpp create mode 100644 Marlin/src/gcode/control/M7-M9.cpp create mode 100644 Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp create mode 100644 Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.h create mode 100644 Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.cpp create mode 100644 Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.h create mode 100644 Marlin/src/lcd/extensible_ui/lib/dgus/DGUSVPVariable.h create mode 100644 Marlin/src/lcd/extui_dgus_lcd.cpp rename Marlin/src/lcd/{extensible_ui/lib/example.cpp => extui_example.cpp} (96%) rename Marlin/src/lcd/{malyanlcd.cpp => extui_malyan_lcd.cpp} (97%) create mode 100644 Marlin/src/libs/crc16.cpp create mode 100644 Marlin/src/libs/crc16.h create mode 100644 Marlin/src/libs/numtostr.cpp create mode 100644 Marlin/src/libs/numtostr.h create mode 100644 Marlin/src/module/thermistor/thermistor_18.h create mode 100644 Marlin/src/pins/pins_BIGTREE_SKR_MINI_V1_1.h create mode 100644 Marlin/src/pins/pins_JGAURORA_A5S_A1.h create mode 100644 Marlin/src/pins/pins_RAMPS_DAGOMA.h create mode 100644 Marlin/src/pins/pins_Z_BOLT_X_SERIES.h diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 41e6b8df07..97315d0287 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -53,7 +53,7 @@ #define tallVersion -#define ABL_Bilinear +//#define ABL_Bilinear /* * Enables a filament sensor plugged into the laser pin. Disables the laser */ @@ -435,6 +435,7 @@ * 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 : the PT100 circuit found in the Ultimainboard V2.x * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 * 61 : 100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup @@ -460,7 +461,7 @@ * 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. * - * :{ '0':"Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '501':"100K Zonestar (Tronxy X3A)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '61':"100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup", '66':"Dyze Design 4.7M High Temperature thermistor", '67':"Slice Engineering 450C High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-4':"Thermocouple + AD8495", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595", '998':"Dummy 1", '999':"Dummy 2", '1000':"Custom thermistor params" } + * :{ '0':"Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '501':"100K Zonestar (Tronxy X3A)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '18':"ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327" '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '61':"100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup", '66':"Dyze Design 4.7M High Temperature thermistor", '67':"Slice Engineering 450C High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-4':"Thermocouple + AD8495", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595", '998':"Dummy 1", '999':"Dummy 2", '1000':"Custom thermistor params" } */ #if ENABLED(TREX3) #define TEMP_SENSOR_0 61 @@ -755,7 +756,7 @@ #if ENABLED(Z_2208) #define Z_DRIVER_TYPE TMC2208_STANDALONE #elif ENABLED(Z_4988) - #define Z_DRIVER_TYPE A4988 + #define Z_DRIVER_TYPE A4988 #else #define Z_DRIVER_TYPE DRV8825 #endif @@ -766,7 +767,7 @@ #define E0_DRIVER_TYPE TMC2208_STANDALONE #define E1_DRIVER_TYPE TMC2208_STANDALONE #else - #define E0_DRIVER_TYPE DRV8825 + #define E0_DRIVER_TYPE DRV8825 #define E1_DRIVER_TYPE DRV8825 #endif //#define E2_DRIVER_TYPE A4988 @@ -965,6 +966,22 @@ */ #define BLTOUCH +/** + * Touch-MI Probe by hotends.fr + * + * This probe is deployed and activated by moving the X-axis to a magnet at the edge of the bed. + * By default, the magnet is assumed to be on the left and activated by a home. If the magnet is + * on the right, enable and set TOUCH_MI_DEPLOY_XPOS to the deploy position. + * + * Also requires: BABYSTEPPING, BABYSTEP_ZPROBE_OFFSET, Z_SAFE_HOMING, + * MIN_PROBE_EDGE, and a minimum Z_HOMING_HEIGHT of 10. + */ +//#define TOUCH_MI_PROBE +#if ENABLED(TOUCH_MI_PROBE) + #define TOUCH_MI_RETRACT_Z 0.5 // Height at which the probe retracts + //#define TOUCH_MI_DEPLOY_XPOS (X_MAX_BED + 2) // For a magnet on the right side of the bed +#endif + // A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) //#define SOLENOID_PROBE @@ -984,23 +1001,23 @@ // /** - * Z Probe to nozzle (X,Y) offset, relative to (0, 0). - * X and Y offsets must be integers. + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. * - * In the following example the X and Y offsets are both positive: - * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 - * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 * - * +-- BACK ---+ - * | | - * L | (+) P | R <-- probe (20,20) - * E | | I - * F | (-) N (+) | G <-- nozzle (10,10) - * T | | H - * | (-) | T - * | | - * O-- FRONT --+ - * (0,0) + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) */ #if ENABLED(TREX3) @@ -1338,10 +1355,10 @@ #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X // Set the boundaries for probing (where the probe can reach). - #define LEFT_PROBE_BED_POSITION (MAX(X_MIN_BED + MIN_PROBE_EDGE, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER)) + 5 - #define FRONT_PROBE_BED_POSITION (MAX(Y_MIN_BED + MIN_PROBE_EDGE, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) + 5 - #define RIGHT_PROBE_BED_POSITION (MIN(X_MAX_BED - (MIN_PROBE_EDGE), X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER)) - 5 - #define BACK_PROBE_BED_POSITION (MIN(Y_MAX_BED - (MIN_PROBE_EDGE), Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) - 5 + //#define LEFT_PROBE_BED_POSITION MIN_PROBE_EDGE + //#define RIGHT_PROBE_BED_POSITION (X_BED_SIZE - (MIN_PROBE_EDGE)) + //#define FRONT_PROBE_BED_POSITION MIN_PROBE_EDGE + //#define BACK_PROBE_BED_POSITION (Y_BED_SIZE - (MIN_PROBE_EDGE)) // Probe along the Y axis, advancing X after each column //#define PROBE_Y_FIRST @@ -2265,6 +2282,10 @@ #define NEOPIXEL_IS_SEQUENTIAL // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once. #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness (0-255) //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup + + // Use a single Neopixel LED for static (background) lighting + //#define NEOPIXEL_BKGD_LED_INDEX 0 // Index of the LED to use + //#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W #endif /** diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 751c3d4b48..65dadd01f7 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -316,7 +316,7 @@ * If left undefined this defaults to F = F_CPU/(2*255*1) * ie F = 31.4 Khz on 16 MHz microcontrollers or F = 39.2 KHz on 20 MHz microcontrollers * These defaults are the same as with the old FAST_PWM_FAN implementation - no migration is required - * NOTE: Setting very low frequencies (< 10 Hz) may result in unexpected timer behaviour. + * NOTE: Setting very low frequencies (< 10 Hz) may result in unexpected timer behavior. * * USE_OCR2A_AS_TOP [undefined by default] * Boards that use TIMER2 for PWM have limitations resulting in only a few possible frequencies on TIMER2: @@ -381,17 +381,14 @@ #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on #define CASE_LIGHT_DEFAULT_BRIGHTNESS 255 // Set default power-up brightness (0-255, requires PWM pin) - #define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu + #define CASE_LIGHT_MENU // Add Case Light options to the LCD menu + #define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting. //#define CASE_LIGHT_USE_NEOPIXEL // Use Neopixel LED as case light, requires NEOPIXEL_LED. #if ENABLED(CASE_LIGHT_USE_NEOPIXEL) #define CASE_LIGHT_NEOPIXEL_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White } #endif #endif -//=========================================================================== -//============================ Mechanical Settings ========================== -//=========================================================================== - // @section homing // If you want endstops to stay on (by default) even when not homing @@ -655,12 +652,11 @@ // @section lcd #if EITHER(ULTIPANEL, EXTENSIBLE_UI) - #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel -#endif - -#if ENABLED(ULTIPANEL) - #define MANUAL_E_MOVES_RELATIVE // Show LCD extruder moves as relative rather than absolute positions - #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder + #define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 60 } // Feedrates for manual moves along X, Y, Z, E from panel + #if ENABLED(ULTIPANEL) + #define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position" + #define ULTIPANEL_FEEDMULTIPLY // Encoder sets the feedrate multiplier on the Status Screen + #endif #endif // @section extras @@ -822,6 +818,7 @@ * A (A shifted) B (B shifted) IC * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (0x5C) MCP4451 + * AZTEEG_X5_MINI 0x2C (0x58) 0x2E (0x5C) MCP4451 * AZTEEG_X5_MINI_WIFI 0x58 0x5C MCP4451 * MIGHTYBOARD_REVE 0x2F (0x5E) MCP4018 */ @@ -918,7 +915,7 @@ //#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files - #define EVENT_GCODE_SD_STOP "G28XY" // G-code to run on Stop Print (e.g., "G28XY" or "G27") + #define EVENT_GCODE_SD_STOP "G28X\nM84" // G-code to run on Stop Print (e.g., "G28XY" or "G27") /** * Continue after Power-Loss (Creality3D) @@ -932,8 +929,8 @@ #if ENABLED(POWER_LOSS_RECOVERY) //#define POWER_LOSS_PIN 44 // Pin to detect power loss //#define POWER_LOSS_STATE HIGH // State of pin indicating power loss - //#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume - //#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power. + //#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume + //#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power. // Without a POWER_LOSS_PIN the following option helps reduce wear on the SD card, // especially with "vase mode" printing. Set too high and vases cannot be continued. @@ -984,12 +981,15 @@ // Enable this option to scroll long filenames in the SD card menu #define SCROLL_LONG_FILENAMES + // Leave the heaters on after Stop Print (not recommended!) + //#define SD_ABORT_NO_COOLDOWN + /** * This option allows you to abort SD printing when any endstop is triggered. * This feature must be enabled with "M540 S1" or from the LCD menu. * To have any effect, endstops must be enabled during SD printing. */ - //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + //#define SD_ABORT_ON_ENDSTOP_HIT /** * This option makes it easier to print the same SD Card file again. @@ -1119,6 +1119,7 @@ #define STATUS_HOTEND_INVERTED // Show solid nozzle bitmaps when heating (Requires STATUS_HOTEND_ANIM) #define STATUS_HOTEND_ANIM // Use a second bitmap to indicate hotend heating #define STATUS_BED_ANIM // Use a second bitmap to indicate bed heating + #define STATUS_CHAMBER_ANIM // Use a second bitmap to indicate chamber heating //#define STATUS_ALT_BED_BITMAP // Use the alternative bed bitmap //#define STATUS_ALT_FAN_BITMAP // Use the alternative fan bitmap //#define STATUS_FAN_FRAMES 3 // :[0,1,2,3,4] Number of fan animation frames @@ -1308,7 +1309,8 @@ /** * Minimum stepper driver pulse width (in µs) * 0 : Smallest possible width the MCU can produce, compatible with TMC2xxx drivers - * 1 : Minimum for A4988, A5984, and LV8729 stepper drivers + * 0 : Minimum 500ns for LV8729, adjusted in stepper.h + * 1 : Minimum for A4988 and A5984 stepper drivers * 2 : Minimum for DRV8825 stepper drivers * 3 : Minimum for TB6600 stepper drivers * 30 : Minimum for TB6560 stepper drivers @@ -1323,8 +1325,8 @@ * 500000 : Maximum for A4988 stepper driver * 400000 : Maximum for TMC2xxx stepper drivers * 250000 : Maximum for DRV8825 stepper driver + * 200000 : Maximum for LV8729 stepper driver * 150000 : Maximum for TB6600 stepper driver - * 130000 : Maximum for LV8729 stepper driver * 15000 : Maximum for TB6560 stepper driver * * Override the default value based on the driver type set in Configuration.h. @@ -1461,7 +1463,7 @@ #if EXTRUDERS > 1 // Z raise distance for tool-change, as needed for some extruders #define TOOLCHANGE_ZRAISE 1 // (mm) - #define TOOLCHANGE_RETURN_NEXT_MOVE // Instead of returning to old position, wait for next move command + #define TOOLCHANGE_NO_RETURN // Don't return to the previous position on tool-change // Retract and prime filament on tool-change #define TOOLCHANGE_FILAMENT_SWAP @@ -1860,6 +1862,12 @@ //#define Z_STALL_SENSITIVITY 8 #endif + /** + * Beta feature! + * Create a 50/50 square wave step pulse optimal for stepper drivers. + */ + //#define SQUARE_WAVE_STEPPING + /** * Enable M122 debugging command for TMC stepper drivers. * M122 S0/1 will enable continous reporting. @@ -2140,6 +2148,21 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * Coolant Control + * + * Add the M7, M8, and M9 commands to turn mist or flood coolant on and off. + * + * Note: COOLANT_MIST_PIN and/or COOLANT_FLOOD_PIN must also be defined. + */ +//#define COOLANT_CONTROL +#if ENABLED(COOLANT_CONTROL) + #define COOLANT_MIST // Enable if mist coolant is present + #define COOLANT_FLOOD // Enable if flood coolant is present + #define COOLANT_MIST_INVERT false // Set "true" if the on/off function is reversed + #define COOLANT_FLOOD_INVERT false // Set "true" if the on/off function is reversed +#endif + /** * Filament Width Sensor * @@ -2263,7 +2286,7 @@ #define CUSTOM_USER_MENUS #if ENABLED(CUSTOM_USER_MENUS) //#define USER_SCRIPT_DONE "M117 User Script Done" - #define CUSTOM_USER_MENU_TITLE "Commissioning" + #define CUSTOM_USER_MENU_TITLE "Setup" #define USER_SCRIPT_AUDIBLE_FEEDBACK #define USER_SCRIPT_RETURN // Return to status screen after a script @@ -2273,7 +2296,7 @@ #define COMMFANNSPEED "M106 S128 \n" #endif - #define USER_DESC_1 "Mesh Commission" + #define USER_DESC_1 "Mesh Setup" #define USER_DESC_3 "Prep for Z Adjust" #if ENABLED(ABL_Bilinear) #define USER_GCODE_1 "M502 \n M500 \n M501 \n M190 S75 \n G28 \n G29 \n M500 \n G28 \n M420 S1 \n " COMMFANNSPEED " M109 S225 \n G1 X100 Y 100 \n G1 Z0 \n M77 \n M117 Set Z Offset" @@ -2286,8 +2309,8 @@ #define USER_DESC_4 "Fill Mesh Points" #define USER_GCODE_4 "G29 P3 \n G29 P3 \n G29 P3 \n G29 T" - #define USER_DESC_2 "PID Tune" - #define USER_GCODE_2 "M106 S128 \n M303 C8 S225 E1 U \n M500 \n M117 PID Tune Done" + #define USER_DESC_2 "PID Bed" + #define USER_GCODE_2 "M303 C4 S75 E-1 U \n M500 \n M117 PID Tune Done" #define USER_DESC_5 "Run Mesh Validation" #define USER_GCODE_5 "G26" @@ -2378,7 +2401,7 @@ //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given // axis after which the printer will abort. Comment out to - // disable abort behaviour. + // disable abort behavior. #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault // for this amount of time (in ms) before the encoder @@ -2438,7 +2461,7 @@ //#define NANODLP_Z_SYNC #if ENABLED(NANODLP_Z_SYNC) //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. - // Default behaviour is limited to Z axis only. + // Default behavior is limited to Z axis only. #endif /** diff --git a/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp b/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp index 592a4bca68..995228171d 100644 --- a/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp +++ b/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp @@ -21,12 +21,12 @@ */ /** - * Originally from Arduino Sd2Card Library + * Adapted from Arduino Sd2Card Library * Copyright (C) 2009 by William Greiman */ /** - * Description: HAL for AVR - SPI functions + * HAL for AVR - SPI functions */ #ifdef __AVR__ @@ -37,35 +37,24 @@ #include "../../inc/MarlinConfig.h" -// -------------------------------------------------------------------------- -// Public Variables -// -------------------------------------------------------------------------- - - -// -------------------------------------------------------------------------- -// Public functions -// -------------------------------------------------------------------------- - -void spiBegin (void) { - SET_OUTPUT(SS_PIN); - WRITE(SS_PIN, HIGH); +void spiBegin(void) { + OUT_WRITE(SS_PIN, HIGH); SET_OUTPUT(SCK_PIN); SET_INPUT(MISO_PIN); SET_OUTPUT(MOSI_PIN); #if DISABLED(SOFTWARE_SPI) // SS must be in output mode even it is not chip select - SET_OUTPUT(SS_PIN); + //SET_OUTPUT(SS_PIN); // set SS high - may be chip select for another SPI device - #if SET_SPI_SS_HIGH - WRITE(SS_PIN, HIGH); - #endif // SET_SPI_SS_HIGH + //#if SET_SPI_SS_HIGH + //WRITE(SS_PIN, HIGH); + //#endif // set a default rate spiInit(1); - #endif // SOFTWARE_SPI + #endif } - #if DISABLED(SOFTWARE_SPI, FORCE_SOFT_SPI) //------------------------------------------------------------------------------ @@ -190,22 +179,26 @@ void spiBegin (void) { } -#else +#else // SOFTWARE_SPI || FORCE_SOFT_SPI - /** nop to tune soft SPI timing */ + //------------------------------------------------------------------------------ + // Software SPI + //------------------------------------------------------------------------------ + + // nop to tune soft SPI timing #define nop asm volatile ("\tnop\n") - /** Set SPI rate */ + // Set SPI rate void spiInit(uint8_t spiRate) { UNUSED(spiRate); // nothing to do } - /** Begin SPI transaction, set clock, bit order, data mode */ + // Begin SPI transaction, set clock, bit order, data mode void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { UNUSED(spiBeginTransaction); // nothing to do } - /** Soft SPI receive byte */ + // Soft SPI receive byte uint8_t spiRec() { uint8_t data = 0; // no interrupts during byte receive - about 8µs @@ -230,13 +223,13 @@ void spiBegin (void) { return data; } - /** Soft SPI read data */ + // Soft SPI read data void spiRead(uint8_t* buf, uint16_t nbyte) { for (uint16_t i = 0; i < nbyte; i++) buf[i] = spiRec(); } - /** Soft SPI send byte */ + // Soft SPI send byte void spiSend(uint8_t data) { // no interrupts during byte send - about 8µs cli(); @@ -257,13 +250,13 @@ void spiBegin (void) { sei(); } - /** Soft SPI send block */ + // Soft SPI send block void spiSendBlock(uint8_t token, const uint8_t* buf) { spiSend(token); for (uint16_t i = 0; i < 512; i++) spiSend(buf[i]); } -#endif // SOFTWARE_SPI, FORCE_SOFT_SPI +#endif // SOFTWARE_SPI || FORCE_SOFT_SPI #endif // __AVR__ diff --git a/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h b/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h index cabf830c90..89933c3673 100644 --- a/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h +++ b/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h @@ -37,9 +37,10 @@ */ #include "../../core/macros.h" -#include #include "../../module/endstops.h" +#include + // One ISR for all EXT-Interrupts void endstop_ISR(void) { endstops.update(); } diff --git a/Marlin/src/HAL/HAL_AVR/fastio_AVR.h b/Marlin/src/HAL/HAL_AVR/fastio_AVR.h index f0ef7af1c8..8fdd0909da 100644 --- a/Marlin/src/HAL/HAL_AVR/fastio_AVR.h +++ b/Marlin/src/HAL/HAL_AVR/fastio_AVR.h @@ -27,9 +27,10 @@ * Contributed by Triffid_Hunter and modified by Kliment, thinkyhead, Bob-the-Kuhn, et.al. */ -#include #include "../../core/macros.h" +#include + #define AVR_AT90USB1286_FAMILY (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__)) #define AVR_ATmega1284_FAMILY (defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)) #define AVR_ATmega2560_FAMILY (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)) diff --git a/Marlin/src/HAL/HAL_DUE/DebugMonitor_Due.cpp b/Marlin/src/HAL/HAL_DUE/DebugMonitor_Due.cpp index 89206fa94c..135b5f7797 100644 --- a/Marlin/src/HAL/HAL_DUE/DebugMonitor_Due.cpp +++ b/Marlin/src/HAL/HAL_DUE/DebugMonitor_Due.cpp @@ -24,11 +24,12 @@ #include "../../core/macros.h" #include "../../core/serial.h" -#include #include "../shared/backtrace/unwinder.h" #include "../shared/backtrace/unwmemaccess.h" +#include + // Debug monitor that dumps to the Programming port all status when // an exception or WDT timeout happens - And then resets the board diff --git a/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.cpp b/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.cpp index 9d2233d914..43c8e572b6 100644 --- a/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.cpp +++ b/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.cpp @@ -46,7 +46,6 @@ #define NUM_HARDWARE_TIMERS 9 -#define PRESCALER 2 // -------------------------------------------------------------------------- // Types // -------------------------------------------------------------------------- diff --git a/Marlin/src/HAL/HAL_DUE/ServoTimers.h b/Marlin/src/HAL/HAL_DUE/ServoTimers.h index 8d5d0fa583..84129ef2b6 100644 --- a/Marlin/src/HAL/HAL_DUE/ServoTimers.h +++ b/Marlin/src/HAL/HAL_DUE/ServoTimers.h @@ -87,5 +87,21 @@ #define HANDLER_FOR_TIMER5 TC0_Handler #endif -//typedef enum { _timer1, _timer2, _timer3, _timer4, _timer5, _Nbr_16timers } timer16_Sequence_t; -typedef enum { _timer3, _timer5, _Nbr_16timers } timer16_Sequence_t; +typedef enum : unsigned char { + #ifdef _useTimer1 + _timer1, + #endif + #ifdef _useTimer2 + _timer2, + #endif + #ifdef _useTimer3 + _timer3, + #endif + #ifdef _useTimer4 + _timer4, + #endif + #ifdef _useTimer5 + _timer5, + #endif + _Nbr_16timers +} timer16_Sequence_t; diff --git a/Marlin/src/HAL/HAL_DUE/spi_pins.h b/Marlin/src/HAL/HAL_DUE/spi_pins.h index c805b0c1ea..69bcd39e78 100644 --- a/Marlin/src/HAL/HAL_DUE/spi_pins.h +++ b/Marlin/src/HAL/HAL_DUE/spi_pins.h @@ -26,19 +26,22 @@ * * Available chip select pins for HW SPI are 4 10 52 77 */ -#if (SDSS == 4) || (SDSS == 10) || (SDSS == 52) || (SDSS == 77) - #if (SDSS == 4) +#if SDSS == 4 || SDSS == 10 || SDSS == 52 || SDSS == 77 || SDSS == 87 + #if SDSS == 4 #define SPI_PIN 87 #define SPI_CHAN 1 - #elif (SDSS == 10) + #elif SDSS == 10 #define SPI_PIN 77 #define SPI_CHAN 0 - #elif (SDSS == 52) + #elif SDSS == 52 #define SPI_PIN 86 #define SPI_CHAN 2 - #else + #elif SDSS == 77 #define SPI_PIN 77 #define SPI_CHAN 0 + #else + #define SPI_PIN 87 + #define SPI_CHAN 1 #endif #define SCK_PIN 76 #define MISO_PIN 74 diff --git a/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_sw_spi.cpp b/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_sw_spi.cpp index 802e11757f..319ee8d4ac 100644 --- a/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_sw_spi.cpp +++ b/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_sw_spi.cpp @@ -57,7 +57,7 @@ #include "../../inc/MarlinConfigPre.h" -#if HAS_GRAPHICAL_LCD && !ENABLED(U8GLIB_ST7920) +#if HAS_GRAPHICAL_LCD && DISABLED(U8GLIB_ST7920) #undef SPI_SPEED #define SPI_SPEED 2 // About 2 MHz @@ -144,5 +144,5 @@ uint8_t u8g_com_HAL_DUE_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void return 1; } -#endif // HAS_GRAPHICAL_LCD +#endif // HAS_GRAPHICAL_LCD && !U8GLIB_ST7920 #endif // ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/HAL_DUE/usb/udi_composite_desc.c b/Marlin/src/HAL/HAL_DUE/usb/udi_composite_desc.c index 3c5f001a26..07bdd1b9d6 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/udi_composite_desc.c +++ b/Marlin/src/HAL/HAL_DUE/usb/udi_composite_desc.c @@ -67,9 +67,9 @@ UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { .bLength = sizeof(usb_dev_desc_t), .bDescriptorType = USB_DT_DEVICE, .bcdUSB = LE16(USB_V2_0), - .bDeviceClass = 0, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, + .bDeviceClass = CDC_CLASS_MULTI, + .bDeviceSubClass = CDC_SUBCLASS_ACM, + .bDeviceProtocol = CDC_PROTOCOL_V25TER, .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, .idVendor = LE16(USB_DEVICE_VENDOR_ID), .idProduct = LE16(USB_DEVICE_PRODUCT_ID), @@ -101,9 +101,9 @@ UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { .bLength = sizeof(usb_dev_qual_desc_t), .bDescriptorType = USB_DT_DEVICE_QUALIFIER, .bcdUSB = LE16(USB_V2_0), - .bDeviceClass = 0, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, + .bDeviceClass = CDC_CLASS_MULTI, + .bDeviceSubClass = CDC_SUBCLASS_ACM, + .bDeviceProtocol = CDC_PROTOCOL_V25TER, .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, .bNumConfigurations = 1 }; diff --git a/Marlin/src/HAL/HAL_DUE/usb/usb_protocol_cdc.h b/Marlin/src/HAL/HAL_DUE/usb/usb_protocol_cdc.h index 875e7e4dda..49fc7387ef 100644 --- a/Marlin/src/HAL/HAL_DUE/usb/usb_protocol_cdc.h +++ b/Marlin/src/HAL/HAL_DUE/usb/usb_protocol_cdc.h @@ -61,6 +61,8 @@ #define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class #define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface #define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface +#define CDC_CLASS_MULTI 0xEF //!< CDC Multi-interface Function + //@} //! \name USB CDC Subclass IDs diff --git a/Marlin/src/HAL/HAL_ESP32/HAL.cpp b/Marlin/src/HAL/HAL_ESP32/HAL.cpp index d7b763f041..7776eeaa13 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL.cpp +++ b/Marlin/src/HAL/HAL_ESP32/HAL.cpp @@ -148,7 +148,7 @@ adc1_channel_t get_channel(int pin) { void HAL_adc_init() { // Configure ADC adc1_config_width(ADC_WIDTH_12Bit); - + // Configure channels only if used as (re-)configuring a pin for ADC that is used elsewhere might have adverse effects #if HAS_TEMP_ADC_0 adc1_config_channel_atten(get_channel(TEMP_0_PIN), ADC_ATTEN_11db); @@ -193,6 +193,9 @@ void HAL_adc_start_conversion(uint8_t adc_pin) { } void analogWrite(int pin, int value) { + + if (!PWM_PIN(pin)) return; + static int cnt_channel = 1, pin_to_channel[40] = {}; if (pin_to_channel[pin] == 0) { diff --git a/Marlin/src/HAL/HAL_ESP32/HAL_Servo_ESP32.cpp b/Marlin/src/HAL/HAL_ESP32/HAL_Servo_ESP32.cpp index bf3d228a6a..52e54d4719 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL_Servo_ESP32.cpp +++ b/Marlin/src/HAL/HAL_ESP32/HAL_Servo_ESP32.cpp @@ -27,7 +27,9 @@ #include "HAL_Servo_ESP32.h" -int Servo::channel_next_free = 0; +// Adjacent channels (0/1, 2/3 etc.) share the same timer and therefore the same frequency and resolution settings on ESP32, +// so we only allocate servo channels up high to avoid side effects with regards to analogWrite (fans, leds, laser pwm etc.) +int Servo::channel_next_free = 12; Servo::Servo() { this->channel = channel_next_free++; @@ -42,7 +44,7 @@ int8_t Servo::attach(const int pin) { return true; } -void Servo::detach() { ledcDetachPin(this->pin) } +void Servo::detach() { ledcDetachPin(this->pin); } int Servo::read() { return this->degrees; } diff --git a/Marlin/src/HAL/HAL_ESP32/HAL_spi_ESP32.cpp b/Marlin/src/HAL/HAL_ESP32/HAL_spi_ESP32.cpp index d48b14d610..730fd43aa4 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL_spi_ESP32.cpp +++ b/Marlin/src/HAL/HAL_ESP32/HAL_spi_ESP32.cpp @@ -29,7 +29,7 @@ #include "HAL.h" #include "../shared/HAL_SPI.h" -#include "pins_arduino.h" +#include #include "spi_pins.h" #include "../../core/macros.h" #include @@ -62,8 +62,7 @@ void spiBegin() { #error "SS_PIN not defined!" #endif - WRITE(SS_PIN, HIGH); - SET_OUTPUT(SS_PIN); + OUT_WRITE(SS_PIN, HIGH); } void spiInit(uint8_t spiRate) { diff --git a/Marlin/src/HAL/HAL_ESP32/i2s.cpp b/Marlin/src/HAL/HAL_ESP32/i2s.cpp index 87c3959e7c..6143775a13 100644 --- a/Marlin/src/HAL/HAL_ESP32/i2s.cpp +++ b/Marlin/src/HAL/HAL_ESP32/i2s.cpp @@ -21,10 +21,11 @@ */ #ifdef ARDUINO_ARCH_ESP32 +#include "../../inc/MarlinConfigPre.h" + #include "i2s.h" #include "../shared/Marduino.h" -#include "../../core/macros.h" #include "driver/periph_ctrl.h" #include "rom/lldesc.h" #include "soc/i2s_struct.h" diff --git a/Marlin/src/HAL/HAL_ESP32/i2s.h b/Marlin/src/HAL/HAL_ESP32/i2s.h index 42c35aa12d..42153e3296 100644 --- a/Marlin/src/HAL/HAL_ESP32/i2s.h +++ b/Marlin/src/HAL/HAL_ESP32/i2s.h @@ -33,9 +33,3 @@ uint8_t i2s_state(uint8_t pin); void i2s_write(uint8_t pin, uint8_t val); void i2s_push_sample(); - -// pin definitions - -#define I2S_WS 25 -#define I2S_BCK 26 -#define I2S_DATA 27 diff --git a/Marlin/src/HAL/HAL_LINUX/hardware/Heater.cpp b/Marlin/src/HAL/HAL_LINUX/hardware/Heater.cpp index 0e2f94c356..a07f6ab202 100644 --- a/Marlin/src/HAL/HAL_LINUX/hardware/Heater.cpp +++ b/Marlin/src/HAL/HAL_LINUX/hardware/Heater.cpp @@ -49,7 +49,7 @@ void Heater::update() { last = now; heat += (heater_state - heat) * (delta / 1000000000.0); - if (heat < room_temp_raw) heat = room_temp_raw; + NOLESS(heat, room_temp_raw); Gpio::pin_map[analogInputToDigitalPin(adc_pin)].value = 0xFFFF - (uint16_t)heat; } } diff --git a/Marlin/src/HAL/HAL_LINUX/spi_pins.h b/Marlin/src/HAL/HAL_LINUX/spi_pins.h index fe510ddcff..22893ac2c3 100644 --- a/Marlin/src/HAL/HAL_LINUX/spi_pins.h +++ b/Marlin/src/HAL/HAL_LINUX/spi_pins.h @@ -21,7 +21,8 @@ */ #pragma once -#include "src/core/macros.h" +#include "../../core/macros.h" +#include "../../inc/MarlinConfigPre.h" #if BOTH(SDSUPPORT, DOGLCD) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN) #define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently diff --git a/Marlin/src/HAL/HAL_LPC1768/main.cpp b/Marlin/src/HAL/HAL_LPC1768/main.cpp index cc74eedc1b..258e150e29 100644 --- a/Marlin/src/HAL/HAL_LPC1768/main.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/main.cpp @@ -78,13 +78,11 @@ void HAL_init() { //_DBG("\n\nDebug running\n"); // Initialise the SD card chip select pins as soon as possible #if PIN_EXISTS(SS) - WRITE(SS_PIN, HIGH); - SET_OUTPUT(SS_PIN); + OUT_WRITE(SS_PIN, HIGH); #endif #if defined(ONBOARD_SD_CS) && ONBOARD_SD_CS > -1 - WRITE(ONBOARD_SD_CS, HIGH); - SET_OUTPUT(ONBOARD_SD_CS); + OUT_WRITE(ONBOARD_SD_CS, HIGH); #endif USB_Init(); // USB Initialization diff --git a/Marlin/src/HAL/HAL_LPC1768/spi_pins.h b/Marlin/src/HAL/HAL_LPC1768/spi_pins.h index c0a072851e..51cb195fb9 100644 --- a/Marlin/src/HAL/HAL_LPC1768/spi_pins.h +++ b/Marlin/src/HAL/HAL_LPC1768/spi_pins.h @@ -21,7 +21,7 @@ */ #pragma once -#include "src/core/macros.h" +#include "../../core/macros.h" #if ENABLED(SDSUPPORT) && HAS_GRAPHICAL_LCD && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN) #define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently diff --git a/Marlin/src/HAL/HAL_STM32/HAL.h b/Marlin/src/HAL/HAL_STM32/HAL.h index c84fe325a2..bc0ad10115 100644 --- a/Marlin/src/HAL/HAL_STM32/HAL.h +++ b/Marlin/src/HAL/HAL_STM32/HAL.h @@ -28,6 +28,7 @@ // Includes // -------------------------------------------------------------------------- +#include "../../core/macros.h" #include "../shared/Marduino.h" #include "../shared/math_32bit.h" #include "../shared/HAL_SPI.h" diff --git a/Marlin/src/HAL/HAL_STM32/HAL_spi_STM32.cpp b/Marlin/src/HAL/HAL_STM32/HAL_spi_STM32.cpp index 86cdb57811..41562b8ccd 100644 --- a/Marlin/src/HAL/HAL_STM32/HAL_spi_STM32.cpp +++ b/Marlin/src/HAL/HAL_STM32/HAL_spi_STM32.cpp @@ -69,8 +69,7 @@ void spiBegin(void) { #error "SS_PIN not defined!" #endif - SET_OUTPUT(SS_PIN); - WRITE(SS_PIN, HIGH); + OUT_WRITE(SS_PIN, HIGH); } /** Configure SPI for specified SPI speed */ diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL.cpp index 89bece08bb..a3b3318d2f 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/HAL.cpp @@ -32,9 +32,10 @@ // -------------------------------------------------------------------------- #include "HAL.h" -#include #include "../../inc/MarlinConfig.h" +#include + // -------------------------------------------------------------------------- // Externals // -------------------------------------------------------------------------- @@ -45,8 +46,7 @@ #define __I #define __IO volatile - typedef struct - { + typedef struct { __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ @@ -161,12 +161,11 @@ enum TEMP_PINS : char { #if ENABLED(FILAMENT_WIDTH_SENSOR) FILWIDTH, #endif - ADC_PIN_COUNT + ADC_PIN_COUNT }; uint16_t HAL_adc_results[ADC_PIN_COUNT]; - // -------------------------------------------------------------------------- // Function prototypes // -------------------------------------------------------------------------- @@ -209,6 +208,9 @@ static void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { void HAL_init(void) { NVIC_SetPriorityGrouping(0x3); + #if PIN_EXISTS(LED) + OUT_WRITE(LED_PIN, LOW); + #endif } /* VGPV Done with defines @@ -313,4 +315,15 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) { uint16_t HAL_adc_get_result(void) { return HAL_adc_result; } +uint16_t analogRead(pin_t pin) { + const bool is_analog = _GET_MODE(pin) == GPIO_INPUT_ANALOG; + return is_analog ? analogRead(uint8_t(pin)) : 0; +} + +// Wrapper to maple unprotected analogWrite +void analogWrite(pin_t pin, int pwm_val8) { + if (PWM_PIN(pin) && IS_OUTPUT(pin)) + analogWrite(uint8_t(pin), pwm_val8); +} + #endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL.h b/Marlin/src/HAL/HAL_STM32F1/HAL.h index f47c38a163..8ad09e64d7 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL.h +++ b/Marlin/src/HAL/HAL_STM32F1/HAL.h @@ -255,6 +255,9 @@ void HAL_adc_init(void); void HAL_adc_start_conversion(const uint8_t adc_pin); uint16_t HAL_adc_get_result(void); +uint16_t analogRead(pin_t pin); // need HAL_ANALOG_SELECT() first +void analogWrite(pin_t pin, int pwm_val8); // PWM only! mul by 257 in maple!? + #define GET_PIN_MAP_PIN(index) index #define GET_PIN_MAP_INDEX(pin) pin #define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_Servo_Stm32f1.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL_Servo_Stm32f1.cpp index ef81db69f3..8ab9331201 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_Servo_Stm32f1.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/HAL_Servo_Stm32f1.cpp @@ -30,6 +30,7 @@ uint8_t ServoCount = 0; #include "HAL_Servo_STM32F1.h" +#include "HAL_timers_STM32F1.h" //#include "Servo.h" @@ -46,7 +47,7 @@ uint8_t ServoCount = 0; * * This uses the smallest prescaler that allows an overflow < 2^16. */ -#define MAX_OVERFLOW ((1 << 16) - 1) +#define MAX_OVERFLOW UINT16_MAX //((1 << 16) - 1) #define CYC_MSEC (1000 * CYCLES_PER_MICROSECOND) #define TAU_MSEC 20 #define TAU_USEC (TAU_MSEC * 1000) @@ -62,22 +63,45 @@ uint8_t ServoCount = 0; #define US_TO_ANGLE(us) ((int16_t)(map((us), SERVO_DEFAULT_MIN_PW, SERVO_DEFAULT_MAX_PW, \ this->minAngle, this->maxAngle))) +void libServo::servoWrite(uint8_t pin, uint16_t duty_cycle) { + #ifdef SERVO0_TIMER_NUM + if (this->servoIndex == 0) { + this->pwmSetDuty(duty_cycle); + return; + } + #endif + + timer_dev *tdev = PIN_MAP[pin].timer_device; + uint8_t tchan = PIN_MAP[pin].timer_channel; + if (tdev) timer_set_compare(tdev, tchan, duty_cycle); +} + libServo::libServo() { this->servoIndex = ServoCount < MAX_SERVOS ? ServoCount++ : INVALID_SERVO; } bool libServo::attach(const int32_t pin, const int32_t minAngle, const int32_t maxAngle) { if (this->servoIndex >= MAX_SERVOS) return false; - if (!PWM_PIN(pin)) return false; + if (pin >= BOARD_NR_GPIO_PINS) return false; this->minAngle = minAngle; this->maxAngle = maxAngle; + this->angle = -1; + + #ifdef SERVO0_TIMER_NUM + if (this->servoIndex == 0 && this->setupSoftPWM(pin)) { + this->pin = pin; // set attached() + return true; + } + #endif + + if (!PWM_PIN(pin)) return false; timer_dev *tdev = PIN_MAP[pin].timer_device; - uint8_t tchan = PIN_MAP[pin].timer_channel; + //uint8_t tchan = PIN_MAP[pin].timer_channel; - pinMode(pin, PWM); - pwmWrite(pin, 0); + SET_PWM(pin); + servoWrite(pin, 0); timer_pause(tdev); timer_set_prescaler(tdev, SERVO_PRESCALER - 1); // prescaler is 1-based @@ -92,12 +116,16 @@ bool libServo::attach(const int32_t pin, const int32_t minAngle, const int32_t m bool libServo::detach() { if (!this->attached()) return false; - pwmWrite(this->pin, 0); + this->angle = -1; + servoWrite(this->pin, 0); return true; } int32_t libServo::read() const { if (this->attached()) { + #ifdef SERVO0_TIMER_NUM + if (this->servoIndex == 0) return this->angle; + #endif timer_dev *tdev = PIN_MAP[this->pin].timer_device; uint8_t tchan = PIN_MAP[this->pin].timer_channel; return US_TO_ANGLE(COMPARE_TO_US(timer_get_compare(tdev, tchan))); @@ -110,13 +138,95 @@ void libServo::move(const int32_t value) { static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); if (this->attached()) { - pwmWrite(this->pin, US_TO_COMPARE(ANGLE_TO_US(constrain(value, this->minAngle, this->maxAngle)))); + this->angle = constrain(value, this->minAngle, this->maxAngle); + servoWrite(this->pin, US_TO_COMPARE(ANGLE_TO_US(this->angle))); safe_delay(servo_delay[this->servoIndex]); #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) this->detach(); #endif } } + +#ifdef SERVO0_TIMER_NUM + extern "C" void Servo_IRQHandler(void) { + static timer_dev *tdev = get_timer_dev(SERVO0_TIMER_NUM); + uint16_t SR = timer_get_status(tdev); + if (SR & TIMER_SR_CC1IF) { // channel 1 off + #ifdef SERVO0_PWM_OD + OUT_WRITE_OD(SERVO0_PIN, 1); // off + #else + OUT_WRITE(SERVO0_PIN, 0); + #endif + timer_reset_status_bit(tdev, TIMER_SR_CC1IF_BIT); + } + if (SR & TIMER_SR_CC2IF) { // channel 2 resume + #ifdef SERVO0_PWM_OD + OUT_WRITE_OD(SERVO0_PIN, 0); // on + #else + OUT_WRITE(SERVO0_PIN, 1); + #endif + timer_reset_status_bit(tdev, TIMER_SR_CC2IF_BIT); + } + } + + bool libServo::setupSoftPWM(const int32_t pin) { + timer_dev *tdev = get_timer_dev(SERVO0_TIMER_NUM); + if (!tdev) return false; + #ifdef SERVO0_PWM_OD + OUT_WRITE_OD(pin, 1); + #else + OUT_WRITE(pin, 0); + #endif + + timer_pause(tdev); + timer_set_mode(tdev, 1, TIMER_OUTPUT_COMPARE); // counter with isr + timer_oc_set_mode(tdev, 1, TIMER_OC_MODE_FROZEN, 0); // no pin output change + timer_oc_set_mode(tdev, 2, TIMER_OC_MODE_FROZEN, 0); // no pin output change + timer_set_prescaler(tdev, SERVO_PRESCALER - 1); // prescaler is 1-based + timer_set_reload(tdev, SERVO_OVERFLOW); + timer_set_compare(tdev, 1, SERVO_OVERFLOW); + timer_set_compare(tdev, 2, SERVO_OVERFLOW); + timer_attach_interrupt(tdev, 1, Servo_IRQHandler); + timer_attach_interrupt(tdev, 2, Servo_IRQHandler); + timer_generate_update(tdev); + timer_resume(tdev); + + return true; + } + + void libServo::pwmSetDuty(const uint16_t duty_cycle) { + timer_dev *tdev = get_timer_dev(SERVO0_TIMER_NUM); + timer_set_compare(tdev, 1, duty_cycle); + timer_generate_update(tdev); + if (duty_cycle) { + timer_enable_irq(tdev, 1); + timer_enable_irq(tdev, 2); + } + else { + timer_disable_irq(tdev, 1); + timer_disable_irq(tdev, 2); + #ifdef SERVO0_PWM_OD + OUT_WRITE_OD(this->pin, 1); // off + #else + OUT_WRITE(this->pin, 0); + #endif + } + } + + void libServo::pauseSoftPWM() { // detach + timer_dev *tdev = get_timer_dev(SERVO0_TIMER_NUM); + timer_pause(tdev); + pwmSetDuty(0); + } + +#else + + bool libServo::setupSoftPWM(const int32_t pin) { return false; } + void libServo::pwmSetDuty(const uint16_t duty_cycle) {} + void libServo::pauseSoftPWM() {} + +#endif + #endif // HAS_SERVOS #endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_Servo_Stm32f1.h b/Marlin/src/HAL/HAL_STM32F1/HAL_Servo_Stm32f1.h index ac83f086ee..d7b6bfc201 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_Servo_Stm32f1.h +++ b/Marlin/src/HAL/HAL_STM32F1/HAL_Servo_Stm32f1.h @@ -46,8 +46,15 @@ class libServo { void move(const int32_t value); int32_t read() const; private: + void servoWrite(uint8_t pin, const uint16_t duty_cycle); + uint8_t servoIndex; // index into the channel data for this servo int32_t pin = NOT_ATTACHED; int32_t minAngle; int32_t maxAngle; + int32_t angle; + + bool setupSoftPWM(const int32_t pin); + void pauseSoftPWM(); + void pwmSetDuty(const uint16_t duty_cycle); }; diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_sdio_STM32F1.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL_sdio_STM32F1.cpp index a6627f0e61..54859a6f74 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_sdio_STM32F1.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/HAL_sdio_STM32F1.cpp @@ -40,7 +40,7 @@ bool SDIO_Init(void) { dma_init(SDIO_DMA_DEV); dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - dma_set_priority(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, DMA_PRIORITY_VERY_HIGH); + dma_set_priority(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, DMA_PRIORITY_MEDIUM); if (!SDIO_CmdGoIdleState()) return false; if (!SDIO_CmdGoIdleState()) return false; /* Hotplugged cards tends to miss first CMD0, so give them a second chance. */ diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp index cbc6c7fe1a..bcf27ae3f8 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp @@ -36,19 +36,14 @@ // Includes // -------------------------------------------------------------------------- -#include "HAL.h" -#include "../shared/HAL_SPI.h" -#include "pins_arduino.h" -#include "spi_pins.h" -#include "../../core/macros.h" +#include "../../inc/MarlinConfig.h" #include + // -------------------------------------------------------------------------- // Public Variables // -------------------------------------------------------------------------- -static SPISettings spiConfig; - // -------------------------------------------------------------------------- // Public functions // -------------------------------------------------------------------------- @@ -81,8 +76,7 @@ void spiBegin() { #if !PIN_EXISTS(SS) #error "SS_PIN not defined!" #endif - SET_OUTPUT(SS_PIN); - WRITE(SS_PIN, HIGH); + OUT_WRITE(SS_PIN, HIGH); } /** @@ -104,8 +98,11 @@ void spiInit(uint8_t spiRate) { case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; default: clock = SPI_CLOCK_DIV2; // Default from the SPI library } - spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0); + SPI.setModule(SPI_DEVICE); SPI.begin(); + SPI.setClockDivider(clock); + SPI.setBitOrder(MSBFIRST); + SPI.setDataMode(SPI_MODE0); } /** @@ -116,9 +113,7 @@ void spiInit(uint8_t spiRate) { * @details */ uint8_t spiRec(void) { - SPI.beginTransaction(spiConfig); uint8_t returnByte = SPI.transfer(0xFF); - SPI.endTransaction(); return returnByte; } @@ -132,9 +127,7 @@ uint8_t spiRec(void) { * @details Uses DMA */ void spiRead(uint8_t* buf, uint16_t nbyte) { - SPI.beginTransaction(spiConfig); SPI.dmaTransfer(0, const_cast(buf), nbyte); - SPI.endTransaction(); } /** @@ -145,9 +138,7 @@ void spiRead(uint8_t* buf, uint16_t nbyte) { * @details */ void spiSend(uint8_t b) { - SPI.beginTransaction(spiConfig); SPI.send(b); - SPI.endTransaction(); } /** @@ -159,27 +150,25 @@ void spiSend(uint8_t b) { * @details Use DMA */ void spiSendBlock(uint8_t token, const uint8_t* buf) { - SPI.beginTransaction(spiConfig); SPI.send(token); SPI.dmaSend(const_cast(buf), 512); - SPI.endTransaction(); } -/** - * @brief Begin SPI transaction, set clock, bit order, data mode - * - * @param spiClock Clock setting - * @param bitOrder Bit Order setting - * @param dataMode Data Mode setting - * @return Nothing - * - * @details Uses an SPI Config via SPISettings - */ -void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { - spiConfig = SPISettings(spiClock, (BitOrder)bitOrder, dataMode); - SPI.beginTransaction(spiConfig); +#if ENABLED(SPI_EEPROM) + +// Read single byte from specified SPI channel +uint8_t spiRec(uint32_t chan) { return SPI.transfer(ff); } + +// Write single byte to specified SPI channel +void spiSend(uint32_t chan, byte b) { SPI.send(b); } + +// Write buffer to specified SPI channel +void spiSend(uint32_t chan, const uint8_t* buf, size_t n) { + for (size_t p = 0; p < n; p++) spiSend(chan, buf[p]); } +#endif // SPI_EEPROM + #endif // SOFTWARE_SPI #endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h b/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h index ad225a8f9a..a7bfab8023 100644 --- a/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h +++ b/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h @@ -30,7 +30,7 @@ #include #define READ(IO) (PIN_MAP[IO].gpio_device->regs->IDR & (1U << PIN_MAP[IO].gpio_bit) ? HIGH : LOW) -#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << (16 * !((bool)V))) +#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << ((V) ? 0 : 16)) #define TOGGLE(IO) (PIN_MAP[IO].gpio_device->regs->ODR = PIN_MAP[IO].gpio_device->regs->ODR ^ (1U << PIN_MAP[IO].gpio_bit)) #define WRITE_VAR(IO,V) WRITE(IO,V) @@ -49,7 +49,7 @@ #define SET_PWM_OD(IO) pinMode(IO, PWM_OPEN_DRAIN) #define IS_INPUT(IO) (_GET_MODE(IO) == GPIO_INPUT_FLOATING || _GET_MODE(IO) == GPIO_INPUT_ANALOG || _GET_MODE(IO) == GPIO_INPUT_PU || _GET_MODE(IO) == GPIO_INPUT_PD) -#define IS_OUTPUT(IO) (_GET_MODE(IO) == GPIO_OUTPUT_PP) +#define IS_OUTPUT(IO) (_GET_MODE(IO) == GPIO_OUTPUT_PP || _GET_MODE(IO) == GPIO_OUTPUT_OD) #define PWM_PIN(IO) (PIN_MAP[IO].timer_device != nullptr) diff --git a/Marlin/src/HAL/HAL_STM32F1/persistent_store_eeprom.cpp b/Marlin/src/HAL/HAL_STM32F1/persistent_store_eeprom.cpp new file mode 100644 index 0000000000..f3fb2409d0 --- /dev/null +++ b/Marlin/src/HAL/HAL_STM32F1/persistent_store_eeprom.cpp @@ -0,0 +1,66 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * 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 . + * + */ + +#ifdef __STM32F1__ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(EEPROM_SETTINGS) && EITHER(SPI_EEPROM, I2C_EEPROM) + +#include "../shared/persistent_store_api.h" + +bool PersistentStore::access_start() { return true; } +bool PersistentStore::access_finish() { return true; } + +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + while (size--) { + uint8_t * const p = (uint8_t * const)pos; + uint8_t v = *value; + // EEPROM has only ~100,000 write cycles, + // so only write bytes that have changed! + if (v != eeprom_read_byte(p)) { + eeprom_write_byte(p, v); + if (eeprom_read_byte(p) != v) { + SERIAL_ECHO_MSG(MSG_ERR_EEPROM_WRITE); + return true; + } + } + crc16(crc, &v, 1); + pos++; + value++; + }; + return false; +} + +bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool set/*=true*/) { + do { + uint8_t c = eeprom_read_byte((uint8_t*)pos); + if (set && value) *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } while (--size); + return false; +} + +size_t PersistentStore::capacity() { return E2END + 1; } + +#endif // EEPROM_SETTINGS && EITHER(SPI_EEPROM, I2C_EEPROM) +#endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/persistent_store_sdcard.cpp b/Marlin/src/HAL/HAL_STM32F1/persistent_store_sdcard.cpp index 5ef638263b..5774581865 100644 --- a/Marlin/src/HAL/HAL_STM32F1/persistent_store_sdcard.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/persistent_store_sdcard.cpp @@ -28,7 +28,7 @@ #include "../../inc/MarlinConfig.h" -#if ENABLED(EEPROM_SETTINGS) && DISABLED(FLASH_EEPROM_EMULATION) +#if ENABLED(EEPROM_SETTINGS) && NONE(FLASH_EEPROM_EMULATION, SPI_EEPROM, I2C_EEPROM) #include "../shared/persistent_store_api.h" diff --git a/Marlin/src/HAL/HAL_STM32F1/pinsDebug.h b/Marlin/src/HAL/HAL_STM32F1/pinsDebug.h index e5022f79a4..310861c85d 100644 --- a/Marlin/src/HAL/HAL_STM32F1/pinsDebug.h +++ b/Marlin/src/HAL/HAL_STM32F1/pinsDebug.h @@ -1 +1,127 @@ -#error Debug pins is not supported on this Platform! +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * 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 . + * + */ + +/** + * Support routines for STM32F1 + */ +#ifdef __STM32F1__ + +/** + * Translation of routines & variables used by pinsDebug.h + */ +#include "fastio_STM32F1.h" + +extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS]; + +#define NUM_DIGITAL_PINS BOARD_NR_GPIO_PINS +#define NUMBER_PINS_TOTAL BOARD_NR_GPIO_PINS +#define VALID_PIN(pin) (pin >= 0 && pin < BOARD_NR_GPIO_PINS) +#define GET_ARRAY_PIN(p) pin_t(pin_array[p].pin) +#define pwm_status(pin) PWM_PIN(pin) +#define digitalRead_mod(p) extDigitalRead(p) +#define NAME_FORMAT(p) PSTR("%-##p##s") +#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3hd "), int16_t(p)); SERIAL_ECHO(buffer); }while(0) +#define PRINT_PORT(p) print_port(p) +#define PRINT_ARRAY_NAME(x) do {sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer);} while (0) +#define MULTI_NAME_PAD 20 // spaces needed to be pretty if not first name assigned to a pin + +// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities +#ifndef M43_NEVER_TOUCH + #define M43_NEVER_TOUCH(Q) (Q >= 9 && Q <= 12) // SERIAL/USB pins PA9(TX) PA10(RX) +#endif + +static inline int8_t get_pin_mode(pin_t pin) { + return VALID_PIN(pin) ? _GET_MODE(pin) : -1; +} + +static inline pin_t DIGITAL_PIN_TO_ANALOG_PIN(pin_t pin) { + if (!VALID_PIN(pin)) return -1; + int8_t adc_channel = int8_t(PIN_MAP[pin].adc_channel); + #ifdef NUM_ANALOG_INPUTS + if (adc_channel >= NUM_ANALOG_INPUTS) adc_channel = ADCx; + #endif + return pin_t(adc_channel); +} + +static inline bool IS_ANALOG(pin_t pin) { + if (!VALID_PIN(pin)) return false; + if (PIN_MAP[pin].adc_channel != ADCx) { + #ifdef NUM_ANALOG_INPUTS + if (PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS) return false; + #endif + return _GET_MODE(pin) == GPIO_INPUT_ANALOG && !M43_NEVER_TOUCH(pin); + } + return false; +} + +static inline bool GET_PINMODE(pin_t pin) { + return VALID_PIN(pin) ? !IS_INPUT(pin) : false; +} + +static inline bool GET_ARRAY_IS_DIGITAL(int16_t array_pin) { + pin_t pin = GET_ARRAY_PIN(array_pin); + bool isDigital = !IS_ANALOG(pin); + #ifdef NUM_ANALOG_INPUTS + if (!isDigital && PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS) + isDigital = true; + #endif + return isDigital; +} + +static inline void pwm_details(pin_t pin) { + if (PWM_PIN(pin)) { + char buffer[16], num = '?'; + timer_dev * const tdev = PIN_MAP[pin].timer_device; + const uint8_t channel = PIN_MAP[pin].timer_channel; + if (tdev == &timer1) num = '1'; + else if (tdev == &timer1) num = '1'; + else if (tdev == &timer2) num = '2'; + else if (tdev == &timer3) num = '3'; + else if (tdev == &timer4) num = '4'; + #ifdef STM32_HIGH_DENSITY + else if (tdev == &timer5) num = '5'; + else if (tdev == &timer8) num = '8'; + #endif + sprintf_P(buffer, PSTR(" TIM%c CH%c"), num, ('0' + channel)); + SERIAL_ECHO(buffer); + } +} + +static inline void print_port(pin_t pin) { + char buffer[8]; + char port = 'A' + char(pin >> 4); // pin div 16 + /* seems not to be required for our devices + gpio_dev* gp = PIN_MAP[pin].gpio_device; + if (gp == &gpioa) port = 'A'; + else if (gp == &gpiob) port = 'B'; + else if (gp == &gpioc) port = 'C'; + else if (gp == &gpiod) port = 'D'; + #if STM32_NR_GPIO_PORTS > 4 + else if (gp == &gpioe) port = 'E'; + else if (gp == &gpiof) port = 'F'; + else if (gp == &gpiog) port = 'G'; + #endif + */ + const int16_t gbit = PIN_MAP[pin].gpio_bit; + sprintf_P(buffer, PSTR("P%c%hd "), port, gbit); + if (gbit < 10) SERIAL_CHAR(' '); + SERIAL_ECHO(buffer); +} + +#endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/spi_pins.h b/Marlin/src/HAL/HAL_STM32F1/spi_pins.h index 97005a309e..b830f0e255 100644 --- a/Marlin/src/HAL/HAL_STM32F1/spi_pins.h +++ b/Marlin/src/HAL/HAL_STM32F1/spi_pins.h @@ -23,11 +23,36 @@ */ /** - * Define SPI Pins: SCK, MISO, MOSI, SS + * STM32F1 Default SPI Pins * - * Any PIN can be used for Chip Select (SS) + * SS SCK MISO MOSI + * +-----------------------------+ + * SPI1 | PA4 PA5 PA6 PA7 | + * SPI2 | PB12 PB13 PB14 PB15 | + * SPI3 | PA15 PB3 PB4 PB5 | + * +-----------------------------+ + * Any pin can be used for Chip Select (SS_PIN) + * SPI1 is enabled by default */ -#define SCK_PIN PA5 -#define MISO_PIN PA6 -#define MOSI_PIN PA7 -#define SS_PIN PA4 +#ifndef SCK_PIN + #define SCK_PIN PA5 +#endif +#ifndef MISO_PIN + #define MISO_PIN PA6 +#endif +#ifndef MOSI_PIN + #define MOSI_PIN PA7 +#endif +#ifndef SS_PIN + #define SS_PIN PA4 +#endif +#undef SDSS +#define SDSS SS_PIN + +#if ENABLED(ENABLE_SPI3) + #define SPI_DEVICE 3 +#elif ENABLED(ENABLE_SPI2) + #define SPI_DEVICE 2 +#else + #define SPI_DEVICE 1 +#endif diff --git a/Marlin/src/HAL/HAL_STM32F1/stm32f1_flag_script.py b/Marlin/src/HAL/HAL_STM32F1/stm32f1_flag_script.py index ce5a066741..5bb2f18fb6 100644 --- a/Marlin/src/HAL/HAL_STM32F1/stm32f1_flag_script.py +++ b/Marlin/src/HAL/HAL_STM32F1/stm32f1_flag_script.py @@ -9,7 +9,6 @@ if __name__ == "__main__": "-mcpu=cortex-m3", "-mthumb", - "-ffreestanding", "-fsigned-char", "-fno-move-loop-invariants", "-fno-strict-aliasing", diff --git a/Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_fsmc.cpp b/Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_fsmc.cpp index 49aced9102..4c96968350 100644 --- a/Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_fsmc.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_fsmc.cpp @@ -28,7 +28,7 @@ #include "../../inc/MarlinConfig.h" -#if defined(ARDUINO_ARCH_STM32F1) && (defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)) +#if defined(ARDUINO_ARCH_STM32F1) && PIN_EXISTS(FSMC_CS) // FSMC on 100/144 pins SoCs #if HAS_GRAPHICAL_LCD @@ -45,7 +45,7 @@ void LCD_IO_Init(uint8_t cs, uint8_t rs); void LCD_IO_WriteData(uint16_t RegValue); -void LCD_IO_WriteReg(uint8_t Reg); +void LCD_IO_WriteReg(uint16_t Reg); uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize); static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT @@ -250,8 +250,8 @@ void LCD_IO_WriteData(uint16_t RegValue) { __DSB(); } -void LCD_IO_WriteReg(uint8_t Reg) { - LCD->REG = (uint16_t)Reg; +void LCD_IO_WriteReg(uint16_t Reg) { + LCD->REG = Reg; __DSB(); } @@ -272,4 +272,4 @@ uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize) { #endif // HAS_GRAPHICAL_LCD -#endif // ARDUINO_ARCH_STM32F1 && (STM32_HIGH_DENSITY || STM32_XL_DENSITY) +#endif // ARDUINO_ARCH_STM32F1 && FSMC_CS_PIN diff --git a/Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_swspi.cpp b/Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_swspi.cpp new file mode 100644 index 0000000000..f9e736c14c --- /dev/null +++ b/Marlin/src/HAL/HAL_STM32F1/u8g_com_stm32duino_swspi.cpp @@ -0,0 +1,165 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * 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 . + * + */ +#ifdef __STM32F1__ + +#include "../../inc/MarlinConfig.h" + +#if HAS_GRAPHICAL_LCD && ENABLED(FORCE_SOFT_SPI) + +#include "HAL.h" +#include + +#undef SPI_SPEED +#define SPI_SPEED 0 // Fastest +//#define SPI_SPEED 2 // Slower + +static uint8_t SPI_speed = SPI_SPEED; + +static inline uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t miso_pin=-1) { + for (uint8_t i = 0; i < 8; i++) { + if (spi_speed == 0) { + WRITE(DOGLCD_MOSI, !!(b & 0x80)); + WRITE(DOGLCD_SCK, HIGH); + b <<= 1; + if (miso_pin >= 0 && READ(miso_pin)) b |= 1; + WRITE(DOGLCD_SCK, LOW); + } + else { + const uint8_t state = (b & 0x80) ? HIGH : LOW; + for (uint8_t j = 0; j < spi_speed; j++) + WRITE(DOGLCD_MOSI, state); + + for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++) + WRITE(DOGLCD_SCK, HIGH); + + b <<= 1; + if (miso_pin >= 0 && READ(miso_pin)) b |= 1; + + for (uint8_t j = 0; j < spi_speed; j++) + WRITE(DOGLCD_SCK, LOW); + } + } + return b; +} + +static inline uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t miso_pin=-1) { + for (uint8_t i = 0; i < 8; i++) { + const uint8_t state = (b & 0x80) ? HIGH : LOW; + if (spi_speed == 0) { + WRITE(DOGLCD_SCK, LOW); + WRITE(DOGLCD_MOSI, state); + WRITE(DOGLCD_MOSI, state); // need some setup time + WRITE(DOGLCD_SCK, HIGH); + } + else { + for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++) + WRITE(DOGLCD_SCK, LOW); + + for (uint8_t j = 0; j < spi_speed; j++) + WRITE(DOGLCD_MOSI, state); + + for (uint8_t j = 0; j < spi_speed; j++) + WRITE(DOGLCD_SCK, HIGH); + } + b <<= 1; + if (miso_pin >= 0 && READ(miso_pin)) b |= 1; + } + return b; +} + +static void u8g_sw_spi_HAL_STM32F1_shift_out(uint8_t val) { + #if ENABLED(FYSETC_MINI_12864) + swSpiTransfer_mode_3(val, SPI_speed); + #else + swSpiTransfer_mode_0(val, SPI_speed); + #endif +} + +static uint8_t swSpiInit(const uint8_t spi_speed) { + #if PIN_EXISTS(LCD_RESET) + SET_OUTPUT(LCD_RESET_PIN); + #endif + SET_OUTPUT(DOGLCD_A0); + OUT_WRITE(DOGLCD_SCK, LOW); + OUT_WRITE(DOGLCD_MOSI, LOW); + OUT_WRITE(DOGLCD_CS, HIGH); + return spi_speed; +} + +uint8_t u8g_com_HAL_STM32F1_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { + switch (msg) { + case U8G_COM_MSG_INIT: + SPI_speed = swSpiInit(SPI_SPEED); + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + #if PIN_EXISTS(LCD_RESET) + WRITE(LCD_RESET_PIN, arg_val); + #endif + break; + + case U8G_COM_MSG_CHIP_SELECT: + #if ENABLED(FYSETC_MINI_12864) // This LCD SPI is running mode 3 while SD card is running mode 0 + if (arg_val) { // SCK idle state needs to be set to the proper idle state before + // the next chip select goes active + WRITE(DOGLCD_SCK, HIGH); // Set SCK to mode 3 idle state before CS goes active + WRITE(DOGLCD_CS, LOW); + } + else { + WRITE(DOGLCD_CS, HIGH); + WRITE(DOGLCD_SCK, LOW); // Set SCK to mode 0 idle state after CS goes inactive + } + #else + WRITE(DOGLCD_CS, !arg_val); + #endif + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_sw_spi_HAL_STM32F1_shift_out(arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: { + uint8_t *ptr = (uint8_t *)arg_ptr; + while (arg_val > 0) { + u8g_sw_spi_HAL_STM32F1_shift_out(*ptr++); + arg_val--; + } + } break; + + case U8G_COM_MSG_WRITE_SEQ_P: { + uint8_t *ptr = (uint8_t *)arg_ptr; + while (arg_val > 0) { + u8g_sw_spi_HAL_STM32F1_shift_out(u8g_pgm_read(ptr)); + ptr++; + arg_val--; + } + } break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + WRITE(DOGLCD_A0, arg_val); + break; + } + return 1; +} + +#endif // HAS_GRAPHICAL_LCD +#endif // STM32F1 diff --git a/Marlin/src/HAL/HAL_STM32F1/watchdog_Stm32f1.cpp b/Marlin/src/HAL/HAL_STM32F1/watchdog_Stm32f1.cpp index 0cbfb7fa5e..64e9bd7c6b 100644 --- a/Marlin/src/HAL/HAL_STM32F1/watchdog_Stm32f1.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/watchdog_Stm32f1.cpp @@ -34,7 +34,7 @@ #include "watchdog_STM32F1.h" void watchdog_reset() { - #if PIN_EXISTS(LED) + #if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED) TOGGLE(LED_PIN); // heartbeat indicator #endif iwdg_feed(); diff --git a/Marlin/src/HAL/HAL_STM32F4/HAL_spi_STM32F4.cpp b/Marlin/src/HAL/HAL_STM32F4/HAL_spi_STM32F4.cpp index 8365b8370b..7347d060fb 100644 --- a/Marlin/src/HAL/HAL_STM32F4/HAL_spi_STM32F4.cpp +++ b/Marlin/src/HAL/HAL_STM32F4/HAL_spi_STM32F4.cpp @@ -38,7 +38,7 @@ #include "HAL.h" #include "../shared/HAL_SPI.h" -#include "pins_arduino.h" +#include #include "spi_pins.h" #include "../../core/macros.h" #include diff --git a/Marlin/src/HAL/HAL_STM32F7/HAL_spi_STM32F7.cpp b/Marlin/src/HAL/HAL_STM32F7/HAL_spi_STM32F7.cpp index 78b312470a..9a06a5ccd5 100644 --- a/Marlin/src/HAL/HAL_STM32F7/HAL_spi_STM32F7.cpp +++ b/Marlin/src/HAL/HAL_STM32F7/HAL_spi_STM32F7.cpp @@ -38,7 +38,7 @@ #include "HAL.h" #include "../shared/HAL_SPI.h" -#include "pins_arduino.h" +#include #include "spi_pins.h" #include "../../core/macros.h" #include @@ -81,8 +81,7 @@ void spiBegin(void) { #error SS_PIN not defined! #endif - SET_OUTPUT(SS_PIN); - WRITE(SS_PIN, HIGH); + OUT_WRITE(SS_PIN, HIGH); } /** Configure SPI for specified SPI speed */ diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/HAL_spi_Teensy.cpp b/Marlin/src/HAL/HAL_TEENSY31_32/HAL_spi_Teensy.cpp index 331703dc55..22e6f620c7 100644 --- a/Marlin/src/HAL/HAL_TEENSY31_32/HAL_spi_Teensy.cpp +++ b/Marlin/src/HAL/HAL_TEENSY31_32/HAL_spi_Teensy.cpp @@ -38,14 +38,12 @@ void spiBegin(void) { #if !PIN_EXISTS(SS) #error "SS_PIN not defined!" #endif - SET_OUTPUT(SS_PIN); - WRITE(SS_PIN, HIGH); + OUT_WRITE(SS_PIN, HIGH); SET_OUTPUT(SCK_PIN); SET_INPUT(MISO_PIN); SET_OUTPUT(MOSI_PIN); - //#if DISABLED(SOFTWARE_SPI) - #if 0 + #if 0 && DISABLED(SOFTWARE_SPI) // set SS high - may be chip select for another SPI device #if SET_SPI_SS_HIGH WRITE(SS_PIN, HIGH); diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_Servo_Teensy.h b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_Servo_Teensy.h index d02cdc9f74..4ed5eeb11b 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_Servo_Teensy.h +++ b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_Servo_Teensy.h @@ -23,7 +23,7 @@ #include -// Inherit and expand on the official library +// Inherit and expand on core Servo library class libServo : public Servo { public: int8_t attach(const int pin); @@ -32,5 +32,5 @@ class libServo : public Servo { private: uint16_t min_ticks; uint16_t max_ticks; - uint8_t servoIndex; // index into the channel data for this servo + uint8_t servoIndex; // Index into the channel data for this servo }; diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_spi_Teensy.cpp b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_spi_Teensy.cpp index 6220225a1d..b5a7f46cb0 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_spi_Teensy.cpp +++ b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_spi_Teensy.cpp @@ -1,3 +1,24 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 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 . + * + */ #if defined(__MK64FX512__) || defined(__MK66FX1M0__) #include "HAL.h" @@ -8,32 +29,27 @@ static SPISettings spiConfig; -// Standard SPI functions -/** Initialize SPI bus */ void spiBegin(void) { #if !PIN_EXISTS(SS) #error SS_PIN not defined! #endif - SET_OUTPUT(SS_PIN); - WRITE(SS_PIN, HIGH); + OUT_WRITE(SS_PIN, HIGH); SET_OUTPUT(SCK_PIN); SET_INPUT(MISO_PIN); SET_OUTPUT(MOSI_PIN); - //#if DISABLED(SOFTWARE_SPI) - #if 0 + #if 0 && DISABLED(SOFTWARE_SPI) // set SS high - may be chip select for another SPI device #if SET_SPI_SS_HIGH WRITE(SS_PIN, HIGH); - #endif // SET_SPI_SS_HIGH + #endif // set a default rate spiInit(SPI_HALF_SPEED); // 1 - #endif // SOFTWARE_SPI + #endif } -/** Configure SPI for specified SPI speed */ void spiInit(uint8_t spiRate) { - // Use datarates Marlin uses + // Use Marlin data-rates uint32_t clock; switch (spiRate) { case SPI_FULL_SPEED: clock = 10000000; break; @@ -49,44 +65,39 @@ void spiInit(uint8_t spiRate) { SPI.begin(); } -//------------------------------------------------------------------------------ -/** SPI receive a byte */ uint8_t spiRec(void) { SPI.beginTransaction(spiConfig); uint8_t returnByte = SPI.transfer(0xFF); SPI.endTransaction(); return returnByte; -// SPDR = 0xFF; -// while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } -// return SPDR; + //SPDR = 0xFF; + //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + //return SPDR; } -//------------------------------------------------------------------------------ -/** SPI read data */ + void spiRead(uint8_t* buf, uint16_t nbyte) { SPI.beginTransaction(spiConfig); SPI.transfer(buf, nbyte); SPI.endTransaction(); -//if (nbyte-- == 0) return; -// SPDR = 0xFF; -//for (uint16_t i = 0; i < nbyte; i++) { -// while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } -// buf[i] = SPDR; -// SPDR = 0xFF; -//} -//while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } -//buf[nbyte] = SPDR; + //if (nbyte-- == 0) return; + // SPDR = 0xFF; + //for (uint16_t i = 0; i < nbyte; i++) { + // while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + // buf[i] = SPDR; + // SPDR = 0xFF; + //} + //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + //buf[nbyte] = SPDR; } -//------------------------------------------------------------------------------ -/** SPI send a byte */ + void spiSend(uint8_t b) { SPI.beginTransaction(spiConfig); SPI.transfer(b); SPI.endTransaction(); -// SPDR = b; -// while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + //SPDR = b; + //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } } -//------------------------------------------------------------------------------ -/** SPI send block */ + void spiSendBlock(uint8_t token, const uint8_t* buf) { SPI.beginTransaction(spiConfig); SPDR = token; @@ -100,11 +111,9 @@ void spiSendBlock(uint8_t token, const uint8_t* buf) { SPI.endTransaction(); } - -/** Begin SPI transaction, set clock, bit order, data mode */ +// Begin SPI transaction, set clock, bit order, data mode void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { spiConfig = SPISettings(spiClock, bitOrder, dataMode); - SPI.beginTransaction(spiConfig); } diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.cpp b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.cpp index 471d823da5..4c84715a26 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.cpp +++ b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.cpp @@ -20,7 +20,6 @@ * */ - /** * Teensy3.5 __MK64FX512__ * Teensy3.6 __MK66FX1M0__ diff --git a/Marlin/src/HAL/shared/SpiEeprom.cpp b/Marlin/src/HAL/shared/SpiEeprom.cpp index 525c8c0a7d..0efbe2d1c8 100644 --- a/Marlin/src/HAL/shared/SpiEeprom.cpp +++ b/Marlin/src/HAL/shared/SpiEeprom.cpp @@ -115,5 +115,4 @@ void eeprom_update_block(const void* src, void* eeprom_address, size_t n) { delay(7); // wait for page write to complete } - -#endif // ENABLED(SPI_EEPROM) +#endif // SPI_EEPROM diff --git a/Marlin/src/HAL/shared/persistent_store_api.h b/Marlin/src/HAL/shared/persistent_store_api.h index de9f1c1090..1e1bc983b0 100644 --- a/Marlin/src/HAL/shared/persistent_store_api.h +++ b/Marlin/src/HAL/shared/persistent_store_api.h @@ -25,6 +25,8 @@ #include #include +#include "../../libs/crc16.h" + class PersistentStore { public: static bool access_start(); diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp index c1f87f55dc..d94f0d183e 100644 --- a/Marlin/src/Marlin.cpp +++ b/Marlin/src/Marlin.cpp @@ -73,10 +73,6 @@ #include "feature/mixing.h" #endif -#if ENABLED(BEZIER_CURVE_SUPPORT) - #include "module/planner_bezier.h" -#endif - #if ENABLED(MAX7219_DEBUG) #include "feature/Max7219_Debug_LEDs.h" #endif @@ -93,10 +89,6 @@ #include "module/servo.h" #endif -#if HAS_DIGIPOTSS - #include -#endif - #if ENABLED(DAC_STEPPER_CURRENT) #include "feature/dac/stepper_dac.h" #endif @@ -110,7 +102,7 @@ #include "feature/I2CPositionEncoder.h" #endif -#if HAS_TRINAMIC +#if HAS_TRINAMIC && DISABLED(PS_DEFAULT_OFF) #include "feature/tmc_util.h" #endif @@ -179,10 +171,6 @@ bool Running = true; -#if ENABLED(TEMPERATURE_UNITS_SUPPORT) - TempUnit input_temp_units = TEMPUNIT_C; -#endif - // For M109 and M190, this flag may be cleared (by M108) to exit the wait loop bool wait_for_heatup = true; @@ -381,7 +369,7 @@ void disable_all_steppers() { #endif // HOST_ACTION_COMMANDS if (run_runout_script) - enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT)); + queue.inject_P(PSTR(FILAMENT_RUNOUT_SCRIPT)); } #endif // HAS_FILAMENT_SENSOR @@ -437,7 +425,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) { runout.run(); #endif - if (commands_in_queue < BUFSIZE) get_available_commands(); + if (queue.length < BUFSIZE) queue.get_available_commands(); const millis_t ms = millis(); @@ -520,7 +508,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) { const int HOME_DEBOUNCE_DELAY = 2500; if (!IS_SD_PRINTING() && !READ(HOME_PIN)) { if (!homeDebounceCount) { - enqueue_and_echo_commands_P(PSTR("G28")); + queue.inject_P(PSTR("G28")); LCD_MESSAGEPGM(MSG_AUTO_HOME); } if (homeDebounceCount < HOME_DEBOUNCE_DELAY) @@ -809,7 +797,7 @@ void stop() { #endif if (IsRunning()) { - Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart + queue.stop(); SERIAL_ERROR_MSG(MSG_ERR_STOPPED); LCD_MESSAGEPGM(MSG_STOPPED); safe_delay(350); // allow enough time for messages to get out before stopping @@ -873,6 +861,10 @@ void setup() { setup_killpin(); + #if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) + tmc_serial_begin(); + #endif + setup_powerhold(); #if HAS_STEPPER_RESET @@ -904,9 +896,6 @@ void setup() { #endif tmc_init_cs_pins(); #endif - #if HAS_DRIVER(TMC2208) - tmc2208_serial_begin(); - #endif #ifdef BOARD_INIT BOARD_INIT(); @@ -937,8 +926,6 @@ void setup() { SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(MSG_FREE_MEMORY, freeMemory(), MSG_PLANNER_BUFFER_BYTES, (int)sizeof(block_t) * (BLOCK_BUFFER_SIZE)); - queue_setup(); - // UI must be initialized before EEPROM // (because EEPROM code calls the UI). ui.init(); @@ -948,7 +935,7 @@ void setup() { ui.show_bootscreen(); #endif - #if ENABLED(SDIO_SUPPORT) && SD_DETECT_PIN == -1 + #if ENABLED(SDIO_SUPPORT) && !PIN_EXISTS(SD_DETECT) // Auto-mount the SD for EEPROM.dat emulation if (!card.isDetected()) card.initsd(); #endif @@ -996,6 +983,13 @@ void setup() { #endif #endif + #if ENABLED(COOLANT_MIST) + OUT_WRITE(COOLANT_MIST_PIN, COOLANT_MIST_INVERT); // Init Mist Coolant OFF + #endif + #if ENABLED(COOLANT_FLOOD) + OUT_WRITE(COOLANT_FLOOD_PIN, COOLANT_FLOOD_INVERT); // Init Flood Coolant OFF + #endif + #if HAS_BED_PROBE endstops.enable_z_probe(false); #endif @@ -1130,6 +1124,7 @@ void loop() { for (;;) { #if ENABLED(SDSUPPORT) + card.checkautostart(); if (card.flag.abort_sd_printing) { @@ -1138,23 +1133,26 @@ void loop() { true #endif ); - clear_command_queue(); + queue.clear(); quickstop_stepper(); print_job_timer.stop(); - thermalManager.disable_all_heaters(); + #if DISABLED(SD_ABORT_NO_COOLDOWN) + thermalManager.disable_all_heaters(); + #endif thermalManager.zero_fan_speeds(); wait_for_heatup = false; #if ENABLED(POWER_LOSS_RECOVERY) card.removeJobRecoveryFile(); #endif #ifdef EVENT_GCODE_SD_STOP - enqueue_and_echo_commands_P(PSTR(EVENT_GCODE_SD_STOP)); + queue.inject_P(PSTR(EVENT_GCODE_SD_STOP)); #endif } + #endif // SDSUPPORT - if (commands_in_queue < BUFSIZE) get_available_commands(); - advance_command_queue(); + if (queue.length < BUFSIZE) queue.get_available_commands(); + queue.advance(); endstops.event_handler(); idle(); } diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h index 4a7fb642b9..31906b9aed 100644 --- a/Marlin/src/core/boards.h +++ b/Marlin/src/core/boards.h @@ -27,254 +27,259 @@ // RAMPS 1.3 / 1.4 - ATmega1280, ATmega2560 // -#define BOARD_RAMPS_OLD 3 // MEGA/RAMPS up to 1.2 +#define BOARD_RAMPS_OLD 3 // MEGA/RAMPS up to 1.2 -#define BOARD_RAMPS_13_EFB 33 // RAMPS 1.3 (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_13_EEB 34 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_13_EFF 35 // RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_13_EEF 36 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_13_SF 38 // RAMPS 1.3 (Power outputs: Spindle, Controller Fan) +#define BOARD_RAMPS_13_EFB 33 // RAMPS 1.3 (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_13_EEB 34 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_13_EFF 35 // RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_13_EEF 36 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_13_SF 38 // RAMPS 1.3 (Power outputs: Spindle, Controller Fan) -#define BOARD_RAMPS_14_EFB 43 // RAMPS 1.4 (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_14_EEB 44 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_14_EFF 45 // RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_14_EEF 46 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_14_SF 48 // RAMPS 1.4 (Power outputs: Spindle, Controller Fan) +#define BOARD_RAMPS_14_EFB 43 // RAMPS 1.4 (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_14_EEB 44 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_14_EFF 45 // RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_14_EEF 46 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_14_SF 48 // RAMPS 1.4 (Power outputs: Spindle, Controller Fan) -#define BOARD_RAMPS_PLUS_EFB 143 // RAMPS Plus 3DYMY (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_PLUS_EEB 144 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_PLUS_EFF 145 // RAMPS Plus 3DYMY (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_PLUS_EEF 146 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_PLUS_SF 148 // RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan) +#define BOARD_RAMPS_PLUS_EFB 143 // RAMPS Plus 3DYMY (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_PLUS_EEB 144 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_PLUS_EFF 145 // RAMPS Plus 3DYMY (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_PLUS_EEF 146 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_PLUS_SF 148 // RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan) // // RAMPS Derivatives - ATmega1280, ATmega2560 // -#define BOARD_3DRAG 77 // 3Drag Controller -#define BOARD_K8200 78 // Velleman K8200 Controller (derived from 3Drag Controller) -#define BOARD_K8400 79 // Velleman K8400 Controller (derived from 3Drag Controller) -#define BOARD_BAM_DICE 401 // 2PrintBeta BAM&DICE with STK drivers -#define BOARD_BAM_DICE_DUE 402 // 2PrintBeta BAM&DICE Due with STK drivers -#define BOARD_MKS_BASE 40 // MKS BASE v1.0 -#define BOARD_MKS_BASE_14 404 // MKS v1.4 A4982 stepper drivers -#define BOARD_MKS_BASE_15 405 // MKS v1.5 with Allegro A4982 stepper drivers -#define BOARD_MKS_BASE_HEROIC 41 // MKS BASE 1.0 with Heroic HR4982 stepper drivers -#define BOARD_MKS_GEN_13 47 // MKS GEN v1.3 or 1.4 -#define BOARD_MKS_GEN_L 53 // MKS GEN L -#define BOARD_KFB_2 136 // Bigtreetech or BIQU KFB2.0 -#define BOARD_ZRIB_V20 504 // zrib V2.0 control board (Chinese knock off RAMPS replica) -#define BOARD_FELIX2 37 // Felix 2.0+ Electronics Board (RAMPS like) -#define BOARD_RIGIDBOARD 42 // Invent-A-Part RigidBoard -#define BOARD_RIGIDBOARD_V2 52 // Invent-A-Part RigidBoard V2 -#define BOARD_SAINSMART_2IN1 49 // Sainsmart 2-in-1 board -#define BOARD_ULTIMAKER 7 // Ultimaker -#define BOARD_ULTIMAKER_OLD 71 // Ultimaker (Older electronics. Pre 1.5.4. This is rare) -#define BOARD_AZTEEG_X3 67 // Azteeg X3 -#define BOARD_AZTEEG_X3_PRO 68 // Azteeg X3 Pro -#define BOARD_ULTIMAIN_2 72 // Ultimainboard 2.x (Uses TEMP_SENSOR 20) -#define BOARD_RUMBA 80 // Rumba -#define BOARD_RUMBA_RAISE3D 333 // Raise3D N series Rumba derivative -#define BOARD_RL200 801 // Rapide Lite 200 (v1, low-cost RUMBA clone with drv) -#define BOARD_FORMBOT_TREX2PLUS 95 // Formbot T-Rex 2 Plus -#define BOARD_FORMBOT_TREX3 96 // Formbot T-Rex 3 -#define BOARD_FORMBOT_RAPTOR 97 // Formbot Raptor -#define BOARD_FORMBOT_RAPTOR2 98 // Formbot Raptor 2 -#define BOARD_BQ_ZUM_MEGA_3D 503 // bq ZUM Mega 3D -#define BOARD_MAKEBOARD_MINI 431 // MakeBoard Mini v2.1.2 is a control board sold by MicroMake -#define BOARD_TRIGORILLA_13 343 // TriGorilla Anycubic version 1.3 based on RAMPS EFB -#define BOARD_TRIGORILLA_14 443 // TriGorilla Anycubic version 1.4 based on RAMPS EFB -#define BOARD_RAMPS_ENDER_4 243 // Creality: Ender-4, CR-8 -#define BOARD_RAMPS_CREALITY 244 // Creality: CR10S, CR20, CR-X -#define BOARD_FYSETC_F6_13 541 // Fysetc F6 -#define BOARD_DUPLICATOR_I3_PLUS 31 // Wanhao Duplicator i3 Plus -#define BOARD_VORON 441 // VORON Design -#define BOARD_TRONXY_V3_1_0 442 // Tronxy TRONXY-V3-1.0 +#define BOARD_3DRAG 77 // 3Drag Controller +#define BOARD_K8200 78 // Velleman K8200 Controller (derived from 3Drag Controller) +#define BOARD_K8400 79 // Velleman K8400 Controller (derived from 3Drag Controller) +#define BOARD_BAM_DICE 401 // 2PrintBeta BAM&DICE with STK drivers +#define BOARD_BAM_DICE_DUE 402 // 2PrintBeta BAM&DICE Due with STK drivers +#define BOARD_MKS_BASE 40 // MKS BASE v1.0 +#define BOARD_MKS_BASE_14 404 // MKS v1.4 A4982 stepper drivers +#define BOARD_MKS_BASE_15 405 // MKS v1.5 with Allegro A4982 stepper drivers +#define BOARD_MKS_BASE_HEROIC 41 // MKS BASE 1.0 with Heroic HR4982 stepper drivers +#define BOARD_MKS_GEN_13 47 // MKS GEN v1.3 or 1.4 +#define BOARD_MKS_GEN_L 53 // MKS GEN L +#define BOARD_KFB_2 136 // Bigtreetech or BIQU KFB2.0 +#define BOARD_ZRIB_V20 504 // zrib V2.0 control board (Chinese knock off RAMPS replica) +#define BOARD_FELIX2 37 // Felix 2.0+ Electronics Board (RAMPS like) +#define BOARD_RIGIDBOARD 42 // Invent-A-Part RigidBoard +#define BOARD_RIGIDBOARD_V2 52 // Invent-A-Part RigidBoard V2 +#define BOARD_SAINSMART_2IN1 49 // Sainsmart 2-in-1 board +#define BOARD_ULTIMAKER 7 // Ultimaker +#define BOARD_ULTIMAKER_OLD 71 // Ultimaker (Older electronics. Pre 1.5.4. This is rare) +#define BOARD_AZTEEG_X3 67 // Azteeg X3 +#define BOARD_AZTEEG_X3_PRO 68 // Azteeg X3 Pro +#define BOARD_ULTIMAIN_2 72 // Ultimainboard 2.x (Uses TEMP_SENSOR 20) +#define BOARD_RUMBA 80 // Rumba +#define BOARD_RUMBA_RAISE3D 333 // Raise3D N series Rumba derivative +#define BOARD_RL200 801 // Rapide Lite 200 (v1, low-cost RUMBA clone with drv) +#define BOARD_FORMBOT_TREX2PLUS 95 // Formbot T-Rex 2 Plus +#define BOARD_FORMBOT_TREX3 96 // Formbot T-Rex 3 +#define BOARD_FORMBOT_RAPTOR 97 // Formbot Raptor +#define BOARD_FORMBOT_RAPTOR2 98 // Formbot Raptor 2 +#define BOARD_BQ_ZUM_MEGA_3D 503 // bq ZUM Mega 3D +#define BOARD_MAKEBOARD_MINI 431 // MakeBoard Mini v2.1.2 is a control board sold by MicroMake +#define BOARD_TRIGORILLA_13 343 // TriGorilla Anycubic version 1.3 based on RAMPS EFB +#define BOARD_TRIGORILLA_14 443 // ... Ver 1.4 +#define BOARD_TRIGORILLA_14_11 444 // ... Rev 1.1 (new servo pin order) +#define BOARD_RAMPS_ENDER_4 243 // Creality: Ender-4, CR-8 +#define BOARD_RAMPS_CREALITY 244 // Creality: CR10S, CR20, CR-X +#define BOARD_RAMPS_DAGOMA 245 // Dagoma F5 +#define BOARD_FYSETC_F6_13 541 // Fysetc F6 +#define BOARD_DUPLICATOR_I3_PLUS 31 // Wanhao Duplicator i3 Plus +#define BOARD_VORON 441 // VORON Design +#define BOARD_TRONXY_V3_1_0 442 // Tronxy TRONXY-V3-1.0 +#define BOARD_Z_BOLT_X_SERIES 550 // Z-Bolt X Series // // Other ATmega1280, ATmega2560 // -#define BOARD_CNCONTROLS_11 111 // Cartesio CN Controls V11 -#define BOARD_CNCONTROLS_12 112 // Cartesio CN Controls V12 -#define BOARD_CHEAPTRONIC 2 // Cheaptronic v1.0 -#define BOARD_CHEAPTRONIC_V2 21 // Cheaptronic v2.0 -#define BOARD_MIGHTYBOARD_REVE 200 // Makerbot Mightyboard Revision E -#define BOARD_MEGATRONICS 70 // Megatronics -#define BOARD_MEGATRONICS_2 701 // Megatronics v2.0 -#define BOARD_MEGATRONICS_3 703 // Megatronics v3.0 -#define BOARD_MEGATRONICS_31 704 // Megatronics v3.1 -#define BOARD_MEGATRONICS_32 705 // Megatronics v3.2 -#define BOARD_RAMBO 301 // Rambo -#define BOARD_MINIRAMBO 302 // Mini-Rambo -#define BOARD_MINIRAMBO_10A 303 // Mini-Rambo 1.0a -#define BOARD_EINSY_RAMBO 304 // Einsy Rambo -#define BOARD_EINSY_RETRO 305 // Einsy Retro -#define BOARD_ELEFU_3 21 // Elefu Ra Board (v3) -#define BOARD_LEAPFROG 999 // Leapfrog -#define BOARD_MEGACONTROLLER 310 // Mega controller -#define BOARD_SCOOVO_X9H 321 // abee Scoovo X9H -#define BOARD_GT2560_REV_A 74 // Geeetech GT2560 Rev. A -#define BOARD_GT2560_REV_A_PLUS 75 // Geeetech GT2560 Rev. A+ (with auto level probe) -#define BOARD_GT2560_V3 76 // Geeetech GT2560 Rev B for A10(M/D) -#define BOARD_GT2560_V3_MC2 73 // Geeetech GT2560 Rev B for Mecreator2 -#define BOARD_GT2560_V3_A20 86 // Geeetech GT2560 Rev B for A20(M/D) -#define BOARD_EINSTART_S 666 // Einstart retrofit +#define BOARD_CNCONTROLS_11 111 // Cartesio CN Controls V11 +#define BOARD_CNCONTROLS_12 112 // Cartesio CN Controls V12 +#define BOARD_CHEAPTRONIC 2 // Cheaptronic v1.0 +#define BOARD_CHEAPTRONIC_V2 21 // Cheaptronic v2.0 +#define BOARD_MIGHTYBOARD_REVE 200 // Makerbot Mightyboard Revision E +#define BOARD_MEGATRONICS 70 // Megatronics +#define BOARD_MEGATRONICS_2 701 // Megatronics v2.0 +#define BOARD_MEGATRONICS_3 703 // Megatronics v3.0 +#define BOARD_MEGATRONICS_31 704 // Megatronics v3.1 +#define BOARD_MEGATRONICS_32 705 // Megatronics v3.2 +#define BOARD_RAMBO 301 // Rambo +#define BOARD_MINIRAMBO 302 // Mini-Rambo +#define BOARD_MINIRAMBO_10A 303 // Mini-Rambo 1.0a +#define BOARD_EINSY_RAMBO 304 // Einsy Rambo +#define BOARD_EINSY_RETRO 305 // Einsy Retro +#define BOARD_ELEFU_3 23 // Elefu Ra Board (v3) +#define BOARD_LEAPFROG 999 // Leapfrog +#define BOARD_MEGACONTROLLER 310 // Mega controller +#define BOARD_SCOOVO_X9H 321 // abee Scoovo X9H +#define BOARD_GT2560_REV_A 74 // Geeetech GT2560 Rev. A +#define BOARD_GT2560_REV_A_PLUS 75 // Geeetech GT2560 Rev. A+ (with auto level probe) +#define BOARD_GT2560_V3 76 // Geeetech GT2560 Rev B for A10(M/D) +#define BOARD_GT2560_V3_MC2 73 // Geeetech GT2560 Rev B for Mecreator2 +#define BOARD_GT2560_V3_A20 86 // Geeetech GT2560 Rev B for A20(M/D) +#define BOARD_EINSTART_S 666 // Einstart retrofit // // ATmega1281, ATmega2561 // -#define BOARD_MINITRONICS 702 // Minitronics v1.0/1.1 -#define BOARD_SILVER_GATE 25 // Silvergate v1.0 +#define BOARD_MINITRONICS 702 // Minitronics v1.0/1.1 +#define BOARD_SILVER_GATE 25 // Silvergate v1.0 // // Sanguinololu and Derivatives - ATmega644P, ATmega1284P // -#define BOARD_SANGUINOLOLU_11 6 // Sanguinololu < 1.2 -#define BOARD_SANGUINOLOLU_12 62 // Sanguinololu 1.2 and above -#define BOARD_MELZI 63 // Melzi -#define BOARD_MELZI_MAKR3D 66 // Melzi with ATmega1284 (MaKr3d version) -#define BOARD_MELZI_CREALITY 89 // Melzi Creality3D board (for CR-10 etc) -#define BOARD_MELZI_MALYAN 92 // Melzi Malyan M150 board -#define BOARD_MELZI_TRONXY 505 // Tronxy X5S -#define BOARD_STB_11 64 // STB V1.1 -#define BOARD_AZTEEG_X1 65 // Azteeg X1 -#define BOARD_ANET_10 69 // Anet 1.0 (Melzi clone) +#define BOARD_SANGUINOLOLU_11 6 // Sanguinololu < 1.2 +#define BOARD_SANGUINOLOLU_12 62 // Sanguinololu 1.2 and above +#define BOARD_MELZI 63 // Melzi +#define BOARD_MELZI_MAKR3D 66 // Melzi with ATmega1284 (MaKr3d version) +#define BOARD_MELZI_CREALITY 89 // Melzi Creality3D board (for CR-10 etc) +#define BOARD_MELZI_MALYAN 92 // Melzi Malyan M150 board +#define BOARD_MELZI_TRONXY 505 // Tronxy X5S +#define BOARD_STB_11 64 // STB V1.1 +#define BOARD_AZTEEG_X1 65 // Azteeg X1 +#define BOARD_ANET_10 69 // Anet 1.0 (Melzi clone) // // Other ATmega644P, ATmega644, ATmega1284P // -#define BOARD_GEN3_MONOLITHIC 22 // Gen3 Monolithic Electronics -#define BOARD_GEN3_PLUS 9 // Gen3+ -#define BOARD_GEN6 5 // Gen6 -#define BOARD_GEN6_DELUXE 51 // Gen6 deluxe -#define BOARD_GEN7_CUSTOM 10 // Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics" -#define BOARD_GEN7_12 11 // Gen7 v1.1, v1.2 -#define BOARD_GEN7_13 12 // Gen7 v1.3 -#define BOARD_GEN7_14 13 // Gen7 v1.4 -#define BOARD_OMCA_A 90 // Alpha OMCA board -#define BOARD_OMCA 91 // Final OMCA board -#define BOARD_SETHI 20 // Sethi 3D_1 +#define BOARD_GEN3_MONOLITHIC 22 // Gen3 Monolithic Electronics +#define BOARD_GEN3_PLUS 9 // Gen3+ +#define BOARD_GEN6 5 // Gen6 +#define BOARD_GEN6_DELUXE 51 // Gen6 deluxe +#define BOARD_GEN7_CUSTOM 10 // Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics" +#define BOARD_GEN7_12 11 // Gen7 v1.1, v1.2 +#define BOARD_GEN7_13 12 // Gen7 v1.3 +#define BOARD_GEN7_14 13 // Gen7 v1.4 +#define BOARD_OMCA_A 90 // Alpha OMCA board +#define BOARD_OMCA 91 // Final OMCA board +#define BOARD_SETHI 20 // Sethi 3D_1 // // Teensyduino - AT90USB1286, AT90USB1286P // -#define BOARD_TEENSYLU 8 // Teensylu -#define BOARD_PRINTRBOARD 81 // Printrboard (AT90USB1286) -#define BOARD_PRINTRBOARD_REVF 811 // Printrboard Revision F (AT90USB1286) -#define BOARD_BRAINWAVE 82 // Brainwave (AT90USB646) -#define BOARD_BRAINWAVE_PRO 85 // Brainwave Pro (AT90USB1286) -#define BOARD_SAV_MKI 83 // SAV Mk-I (AT90USB1286) -#define BOARD_TEENSY2 84 // Teensy++2.0 (AT90USB1286) -#define BOARD_5DPRINT 88 // 5DPrint D8 Driver Board +#define BOARD_TEENSYLU 8 // Teensylu +#define BOARD_PRINTRBOARD 81 // Printrboard (AT90USB1286) +#define BOARD_PRINTRBOARD_REVF 811 // Printrboard Revision F (AT90USB1286) +#define BOARD_BRAINWAVE 82 // Brainwave (AT90USB646) +#define BOARD_BRAINWAVE_PRO 85 // Brainwave Pro (AT90USB1286) +#define BOARD_SAV_MKI 83 // SAV Mk-I (AT90USB1286) +#define BOARD_TEENSY2 84 // Teensy++2.0 (AT90USB1286) +#define BOARD_5DPRINT 88 // 5DPrint D8 Driver Board // // LPC1768 ARM Cortex M3 // -#define BOARD_RAMPS_14_RE_ARM_EFB 1743 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_14_RE_ARM_EEB 1744 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_14_RE_ARM_EFF 1745 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_14_RE_ARM_EEF 1746 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_14_RE_ARM_SF 1748 // Re-ARM with RAMPS 1.4 (Power outputs: Spindle, Controller Fan) -#define BOARD_MKS_SBASE 1750 // MKS-Sbase (Power outputs: Hotend0, Hotend1, Bed, Fan) -#define BOARD_AZSMZ_MINI 1751 // AZSMZ Mini -#define BOARD_AZTEEG_X5_GT 1752 // Azteeg X5 GT (Power outputs: Hotend0, Hotend1, Bed, Fan) -#define BOARD_BIQU_BQ111_A4 1753 // BIQU BQ111-A4 (Power outputs: Hotend, Fan, Bed) -#define BOARD_SELENA_COMPACT 1754 // Selena Compact (Power outputs: Hotend0, Hotend1, Bed0, Bed1, Fan0, Fan1) -#define BOARD_COHESION3D_REMIX 1755 // Cohesion3D ReMix -#define BOARD_COHESION3D_MINI 1756 // Cohesion3D Mini -#define BOARD_SMOOTHIEBOARD 1757 // Smoothieboard -#define BOARD_AZTEEG_X5_MINI_WIFI 1758 // Azteeg X5 Mini Wifi (Power outputs: Hotend0, Bed, Fan) -#define BOARD_BIQU_SKR_V1_1 1759 // BIQU SKR_V1.1 (Power outputs: Hotend0,Hotend1, Fan, Bed) -#define BOARD_BIQU_B300_V1_0 1760 // BIQU B300_V1.0 (Power outputs: Hotend0, Fan, Bed, SPI Driver) -#define BOARD_BIGTREE_SKR_V1_3 1761 // BIGTREE SKR_V1.3 (Power outputs: Hotend0, Hotend1, Fan, Bed) -#define BOARD_AZTEEG_X5_MINI 1762 // Azteeg X5 Mini (Power outputs: Hotend0, Bed, Fan) -#define BOARD_MKS_SGEN 1763 // MKS-SGen (Power outputs: Hotend0, Hotend1, Bed, Fan) +#define BOARD_RAMPS_14_RE_ARM_EFB 1743 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_14_RE_ARM_EEB 1744 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_14_RE_ARM_EFF 1745 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_14_RE_ARM_EEF 1746 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_14_RE_ARM_SF 1748 // Re-ARM with RAMPS 1.4 (Power outputs: Spindle, Controller Fan) +#define BOARD_MKS_SBASE 1750 // MKS-Sbase (Power outputs: Hotend0, Hotend1, Bed, Fan) +#define BOARD_AZSMZ_MINI 1751 // AZSMZ Mini +#define BOARD_AZTEEG_X5_GT 1752 // Azteeg X5 GT (Power outputs: Hotend0, Hotend1, Bed, Fan) +#define BOARD_BIQU_BQ111_A4 1753 // BIQU BQ111-A4 (Power outputs: Hotend, Fan, Bed) +#define BOARD_SELENA_COMPACT 1754 // Selena Compact (Power outputs: Hotend0, Hotend1, Bed0, Bed1, Fan0, Fan1) +#define BOARD_COHESION3D_REMIX 1755 // Cohesion3D ReMix +#define BOARD_COHESION3D_MINI 1756 // Cohesion3D Mini +#define BOARD_SMOOTHIEBOARD 1757 // Smoothieboard +#define BOARD_AZTEEG_X5_MINI_WIFI 1758 // Azteeg X5 Mini Wifi (Power outputs: Hotend0, Bed, Fan) +#define BOARD_BIQU_SKR_V1_1 1759 // BIQU SKR_V1.1 (Power outputs: Hotend0,Hotend1, Fan, Bed) +#define BOARD_BIQU_B300_V1_0 1760 // BIQU B300_V1.0 (Power outputs: Hotend0, Fan, Bed, SPI Driver) +#define BOARD_BIGTREE_SKR_V1_3 1761 // BIGTREE SKR_V1.3 (Power outputs: Hotend0, Hotend1, Fan, Bed) +#define BOARD_AZTEEG_X5_MINI 1762 // Azteeg X5 Mini (Power outputs: Hotend0, Bed, Fan) +#define BOARD_MKS_SGEN 1763 // MKS-SGen (Power outputs: Hotend0, Hotend1, Bed, Fan) // // SAM3X8E ARM Cortex M3 // -#define BOARD_DUE3DOM 1411 // DUE3DOM for Arduino DUE -#define BOARD_DUE3DOM_MINI 1412 // DUE3DOM MINI for Arduino DUE -#define BOARD_RADDS 1502 // RADDS -#define BOARD_RAMPS_FD_V1 1503 // RAMPS-FD v1 -#define BOARD_RAMPS_FD_V2 1504 // RAMPS-FD v2 -#define BOARD_RAMPS_SMART_EFB 1523 // RAMPS-SMART (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_SMART_EEB 1524 // RAMPS-SMART (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_SMART_EFF 1525 // RAMPS-SMART (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_SMART_EEF 1526 // RAMPS-SMART (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_SMART_SF 1528 // RAMPS-SMART (Power outputs: Spindle, Controller Fan) -#define BOARD_RAMPS_DUO_EFB 1533 // RAMPS Duo (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_DUO_EEB 1534 // RAMPS Duo (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_DUO_EFF 1535 // RAMPS Duo (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_DUO_EEF 1536 // RAMPS Duo (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_DUO_SF 1538 // RAMPS Duo (Power outputs: Spindle, Controller Fan) -#define BOARD_RAMPS4DUE_EFB 1543 // RAMPS4DUE (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS4DUE_EEB 1544 // RAMPS4DUE (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS4DUE_EFF 1545 // RAMPS4DUE (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS4DUE_EEF 1546 // RAMPS4DUE (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS4DUE_SF 1548 // RAMPS4DUE (Power outputs: Spindle, Controller Fan) -#define BOARD_RURAMPS4D_11 1550 // RuRAMPS4Duo v1.1 (Power outputs: Hotend0, Hotend1, Hotend2, Fan0, Fan1, Bed) -#define BOARD_RURAMPS4D_13 1551 // RuRAMPS4Duo v1.3 (Power outputs: Hotend0, Hotend1, Hotend2, Fan0, Fan1, Bed) -#define BOARD_ULTRATRONICS_PRO 1560 // ReprapWorld Ultratronics Pro V1.0 -#define BOARD_ARCHIM1 1591 // UltiMachine Archim1 (with DRV8825 drivers) -#define BOARD_ARCHIM2 1592 // UltiMachine Archim2 (with TMC2130 drivers) -#define BOARD_ALLIGATOR 1602 // Alligator Board R2 +#define BOARD_DUE3DOM 1411 // DUE3DOM for Arduino DUE +#define BOARD_DUE3DOM_MINI 1412 // DUE3DOM MINI for Arduino DUE +#define BOARD_RADDS 1502 // RADDS +#define BOARD_RAMPS_FD_V1 1503 // RAMPS-FD v1 +#define BOARD_RAMPS_FD_V2 1504 // RAMPS-FD v2 +#define BOARD_RAMPS_SMART_EFB 1523 // RAMPS-SMART (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_SMART_EEB 1524 // RAMPS-SMART (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_SMART_EFF 1525 // RAMPS-SMART (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_SMART_EEF 1526 // RAMPS-SMART (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_SMART_SF 1528 // RAMPS-SMART (Power outputs: Spindle, Controller Fan) +#define BOARD_RAMPS_DUO_EFB 1533 // RAMPS Duo (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_DUO_EEB 1534 // RAMPS Duo (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_DUO_EFF 1535 // RAMPS Duo (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_DUO_EEF 1536 // RAMPS Duo (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_DUO_SF 1538 // RAMPS Duo (Power outputs: Spindle, Controller Fan) +#define BOARD_RAMPS4DUE_EFB 1543 // RAMPS4DUE (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS4DUE_EEB 1544 // RAMPS4DUE (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS4DUE_EFF 1545 // RAMPS4DUE (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS4DUE_EEF 1546 // RAMPS4DUE (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS4DUE_SF 1548 // RAMPS4DUE (Power outputs: Spindle, Controller Fan) +#define BOARD_RURAMPS4D_11 1550 // RuRAMPS4Duo v1.1 (Power outputs: Hotend0, Hotend1, Hotend2, Fan0, Fan1, Bed) +#define BOARD_RURAMPS4D_13 1551 // RuRAMPS4Duo v1.3 (Power outputs: Hotend0, Hotend1, Hotend2, Fan0, Fan1, Bed) +#define BOARD_ULTRATRONICS_PRO 1560 // ReprapWorld Ultratronics Pro V1.0 +#define BOARD_ARCHIM1 1591 // UltiMachine Archim1 (with DRV8825 drivers) +#define BOARD_ARCHIM2 1592 // UltiMachine Archim2 (with TMC2130 drivers) +#define BOARD_ALLIGATOR 1602 // Alligator Board R2 // // SAM3X8C ARM Cortex M3 // -#define BOARD_PRINTRBOARD_G2 1620 // PRINTRBOARD G2 -#define BOARD_ADSK 1610 // Arduino DUE Shield Kit (ADSK) +#define BOARD_PRINTRBOARD_G2 1620 // PRINTRBOARD G2 +#define BOARD_ADSK 1610 // Arduino DUE Shield Kit (ADSK) // // STM32 ARM Cortex-M3 // -#define BOARD_STM32F1R 1800 // STM32R Libmaple based STM32F1 controller -#define BOARD_MALYAN_M200 1801 // STM32C8T6 Libmaple based stm32f1 controller -#define BOARD_STM3R_MINI 1803 // STM32 Libmaple based stm32f1 controller -#define BOARD_GTM32_PRO_VB 1805 // STM32f103VET6 controller -#define BOARD_MORPHEUS 1806 // STM32F103C8/STM32F103CB Libmaple based stm32f1 controller -#define BOARD_MKS_ROBIN 1808 // MKS Robin / STM32F103ZET6 +#define BOARD_STM32F1R 1800 // STM32R Libmaple based STM32F1 controller +#define BOARD_MALYAN_M200 1801 // STM32C8T6 Libmaple based stm32f1 controller +#define BOARD_STM3R_MINI 1803 // STM32 Libmaple based stm32f1 controller +#define BOARD_GTM32_PRO_VB 1805 // STM32f103VET6 controller +#define BOARD_MORPHEUS 1806 // STM32F103C8/STM32F103CB Libmaple based stm32f1 controller +#define BOARD_MKS_ROBIN 1808 // MKS Robin / STM32F103ZET6 +#define BOARD_BIGTREE_SKR_MINI_V1_1 1814 // STM32F103RC +#define BOARD_JGAURORA_A5S_A1 1820 // JGAurora A5S A1 / STM32F103ZET6 // // STM32 ARM Cortex-M4F // -#define BOARD_TEENSY31_32 1552 // Teensy3.1 and Teensy3.2 -#define BOARD_TEENSY35_36 841 // Teensy3.5 and Teensy3.6 -#define BOARD_BEAST 1802 // STM32FxxxVxT6 Libmaple based stm32f4 controller -#define BOARD_STM32F4 1804 // STM32 STM32GENERIC based STM32F4 controller -#define BOARD_ARMED 1807 // Arm'ed STM32F4 based controller -#define BOARD_RUMBA32 1809 // RUMBA32 STM32F4 based controller -#define BOARD_BLACK_STM32F407VE 1810 // BLACK_STM32F407VE -#define BOARD_BLACK_STM32F407ZE 1811 // BLACK_STM32F407ZE -#define BOARD_STEVAL 1866 // STEVAL-3DP001V1 3D PRINTER BOARD +#define BOARD_TEENSY31_32 1552 // Teensy3.1 and Teensy3.2 +#define BOARD_TEENSY35_36 841 // Teensy3.5 and Teensy3.6 +#define BOARD_BEAST 1802 // STM32FxxxVxT6 Libmaple based stm32f4 controller +#define BOARD_STM32F4 1804 // STM32 STM32GENERIC based STM32F4 controller +#define BOARD_ARMED 1807 // Arm'ed STM32F4 based controller +#define BOARD_RUMBA32 1809 // RUMBA32 STM32F4 based controller +#define BOARD_BLACK_STM32F407VE 1810 // BLACK_STM32F407VE +#define BOARD_BLACK_STM32F407ZE 1811 // BLACK_STM32F407ZE +#define BOARD_STEVAL 1866 // STEVAL-3DP001V1 3D PRINTER BOARD // // ARM Cortex M7 // -#define BOARD_THE_BORG 1860 // THE-BORG (Power outputs: Hotend0, Hotend1, Bed, Fan) -#define BOARD_REMRAM_V1 1862 // RemRam v1 +#define BOARD_THE_BORG 1860 // THE-BORG (Power outputs: Hotend0, Hotend1, Bed, Fan) +#define BOARD_REMRAM_V1 1862 // RemRam v1 // // Espressif ESP32 WiFi // -#define BOARD_ESP32 1900 +#define BOARD_ESP32 1900 // // Simulations // -#define BOARD_LINUX_RAMPS 2000 +#define BOARD_LINUX_RAMPS 2000 #define MB(board) (defined(BOARD_##board) && MOTHERBOARD==BOARD_##board) diff --git a/Marlin/src/core/drivers.h b/Marlin/src/core/drivers.h index a686ea584f..9eca0a7168 100644 --- a/Marlin/src/core/drivers.h +++ b/Marlin/src/core/drivers.h @@ -37,6 +37,8 @@ #define _TMC2160_STANDALONE 2161 #define _TMC2208 2208 #define _TMC2208_STANDALONE 0x00A +#define _TMC2209 2209 +#define _TMC2209_STANDALONE 0x00D #define _TMC26X 0x10B #define _TMC26X_STANDALONE 0x00B #define _TMC2660 2660 @@ -77,6 +79,7 @@ #define HAS_TRINAMIC ( HAS_DRIVER(TMC2130) \ || HAS_DRIVER(TMC2160) \ || HAS_DRIVER(TMC2208) \ + || HAS_DRIVER(TMC2209) \ || HAS_DRIVER(TMC2660) \ || HAS_DRIVER(TMC5130) \ || HAS_DRIVER(TMC5160) ) @@ -84,6 +87,7 @@ #define AXIS_IS_TMC(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \ || AXIS_DRIVER_TYPE(A,TMC2160) \ || AXIS_DRIVER_TYPE(A,TMC2208) \ + || AXIS_DRIVER_TYPE(A,TMC2209) \ || AXIS_DRIVER_TYPE(A,TMC2660) \ || AXIS_DRIVER_TYPE(A,TMC5130) \ || AXIS_DRIVER_TYPE(A,TMC5160) ) @@ -96,8 +100,12 @@ || AXIS_DRIVER_TYPE(A,TMC5130) \ || AXIS_DRIVER_TYPE(A,TMC5160) ) +#define AXIS_HAS_UART(A) ( AXIS_DRIVER_TYPE(A,TMC2208) \ + || AXIS_DRIVER_TYPE(A,TMC2209) ) + #define AXIS_HAS_STALLGUARD(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \ || AXIS_DRIVER_TYPE(A,TMC2160) \ + || AXIS_DRIVER_TYPE(A,TMC2209) \ || AXIS_DRIVER_TYPE(A,TMC2660) \ || AXIS_DRIVER_TYPE(A,TMC5130) \ || AXIS_DRIVER_TYPE(A,TMC5160) ) @@ -105,5 +113,6 @@ #define AXIS_HAS_STEALTHCHOP(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \ || AXIS_DRIVER_TYPE(A,TMC2160) \ || AXIS_DRIVER_TYPE(A,TMC2208) \ + || AXIS_DRIVER_TYPE(A,TMC2209) \ || AXIS_DRIVER_TYPE(A,TMC5130) \ || AXIS_DRIVER_TYPE(A,TMC5160) ) diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h index 3805c216fe..c12b9fd046 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -56,7 +56,13 @@ #define NANOSECONDS_PER_CYCLE (1000000000.0 / F_CPU) // Remove compiler warning on an unused variable -#define UNUSED(X) (void)X +#ifndef UNUSED + #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) + #define UNUSED(X) (void)X + #else + #define UNUSED(x) ((void)(x)) + #endif +#endif // Macros to make a string from a macro #define STRINGIFY_(M) #M diff --git a/Marlin/src/core/utility.cpp b/Marlin/src/core/utility.cpp index 0bc029cece..b8e42c61f1 100644 --- a/Marlin/src/core/utility.cpp +++ b/Marlin/src/core/utility.cpp @@ -35,293 +35,13 @@ void safe_delay(millis_t ms) { thermalManager.manage_heater(); // This keeps us safe if too many small safe_delay() calls are made } -#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE) - - void crc16(uint16_t *crc, const void * const data, uint16_t cnt) { - uint8_t *ptr = (uint8_t *)data; - while (cnt--) { - *crc = (uint16_t)(*crc ^ (uint16_t)(((uint16_t)*ptr++) << 8)); - for (uint8_t i = 0; i < 8; i++) - *crc = (uint16_t)((*crc & 0x8000) ? ((uint16_t)(*crc << 1) ^ 0x1021) : (*crc << 1)); - } - } - -#endif // EEPROM_SETTINGS || SD_FIRMWARE_UPDATE - -#if ANY(ULTRA_LCD, DEBUG_LEVELING_FEATURE, EXTENSIBLE_UI) - - char conv[8] = { 0 }; - - #define DIGIT(n) ('0' + (n)) - #define DIGIMOD(n, f) DIGIT((n)/(f) % 10) - #define RJDIGIT(n, f) ((n) >= (f) ? DIGIMOD(n, f) : ' ') - #define MINUSOR(n, alt) (n >= 0 ? (alt) : (n = -n, '-')) - - // Convert a full-range unsigned 8bit int to a percentage - char* ui8tostr4pct(const uint8_t i) { - const uint8_t n = ui8_to_percent(i); - conv[3] = RJDIGIT(n, 100); - conv[4] = RJDIGIT(n, 10); - conv[5] = DIGIMOD(n, 1); - conv[6] = '%'; - return &conv[3]; - } - - // Convert unsigned 8bit int to string 123 format - char* ui8tostr3(const uint8_t i) { - conv[4] = RJDIGIT(i, 100); - conv[5] = RJDIGIT(i, 10); - conv[6] = DIGIMOD(i, 1); - return &conv[4]; - } - - // Convert signed 8bit int to rj string with 123 or -12 format - char* i8tostr3(const int8_t x) { - int xx = x; - conv[4] = MINUSOR(xx, RJDIGIT(xx, 100)); - conv[5] = RJDIGIT(xx, 10); - conv[6] = DIGIMOD(xx, 1); - return &conv[4]; - } - - // Convert unsigned 16bit int to string 123 format - char* ui16tostr3(const uint16_t xx) { - conv[4] = RJDIGIT(xx, 100); - conv[5] = RJDIGIT(xx, 10); - conv[6] = DIGIMOD(xx, 1); - return &conv[4]; - } - - // Convert unsigned 16bit int to string 1234 format - char* ui16tostr4(const uint16_t xx) { - conv[3] = RJDIGIT(xx, 1000); - conv[4] = RJDIGIT(xx, 100); - conv[5] = RJDIGIT(xx, 10); - conv[6] = DIGIMOD(xx, 1); - return &conv[3]; - } - - // Convert signed 16bit int to rj string with 123 or -12 format - char* i16tostr3(const int16_t x) { - int xx = x; - conv[4] = MINUSOR(xx, RJDIGIT(xx, 100)); - conv[5] = RJDIGIT(xx, 10); - conv[6] = DIGIMOD(xx, 1); - return &conv[4]; - } - - // Convert unsigned 16bit int to lj string with 123 format - char* i16tostr3left(const int16_t i) { - char *str = &conv[6]; - *str = DIGIMOD(i, 1); - if (i >= 10) { - *(--str) = DIGIMOD(i, 10); - if (i >= 100) - *(--str) = DIGIMOD(i, 100); - } - return str; - } - - // Convert signed 16bit int to rj string with 1234, _123, -123, _-12, or __-1 format - char* i16tostr4sign(const int16_t i) { - const bool neg = i < 0; - const int ii = neg ? -i : i; - if (i >= 1000) { - conv[3] = DIGIMOD(ii, 1000); - conv[4] = DIGIMOD(ii, 100); - conv[5] = DIGIMOD(ii, 10); - } - else if (ii >= 100) { - conv[3] = neg ? '-' : ' '; - conv[4] = DIGIMOD(ii, 100); - conv[5] = DIGIMOD(ii, 10); - } - else { - conv[3] = ' '; - conv[4] = ' '; - if (ii >= 10) { - conv[4] = neg ? '-' : ' '; - conv[5] = DIGIMOD(ii, 10); - } - else { - conv[5] = neg ? '-' : ' '; - } - } - conv[6] = DIGIMOD(ii, 1); - return &conv[3]; - } - - // Convert unsigned float to string with 1.23 format - char* ftostr12ns(const float &f) { - const long i = ((f < 0 ? -f : f) * 1000 + 5) / 10; - conv[3] = DIGIMOD(i, 100); - conv[4] = '.'; - conv[5] = DIGIMOD(i, 10); - conv[6] = DIGIMOD(i, 1); - return &conv[3]; - } - - // Convert signed float to fixed-length string with 12.34 / -2.34 format or 123.45 / -23.45 format - char* ftostr42_52(const float &f) { - if (f <= -10 || f >= 100) return ftostr52(f); // need more digits - long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; - conv[2] = (f >= 0 && f < 10) ? ' ' : MINUSOR(i, DIGIMOD(i, 1000)); - conv[3] = DIGIMOD(i, 100); - conv[4] = '.'; - conv[5] = DIGIMOD(i, 10); - conv[6] = DIGIMOD(i, 1); - return &conv[2]; - } - - // Convert signed float to fixed-length string with 023.45 / -23.45 format - char* ftostr52(const float &f) { - long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; - conv[1] = MINUSOR(i, DIGIMOD(i, 10000)); - conv[2] = DIGIMOD(i, 1000); - conv[3] = DIGIMOD(i, 100); - conv[4] = '.'; - conv[5] = DIGIMOD(i, 10); - conv[6] = DIGIMOD(i, 1); - return &conv[1]; - } - - #if ENABLED(LCD_DECIMAL_SMALL_XY) - - // Convert float to rj string with 1234, _123, -123, _-12, 12.3, _1.2, or -1.2 format - char* ftostr4sign(const float &f) { - const int i = (f * 100 + (f < 0 ? -5: 5)) / 10; - if (!WITHIN(i, -99, 999)) return i16tostr4sign((int)f); - const bool neg = i < 0; - const int ii = neg ? -i : i; - conv[3] = neg ? '-' : (ii >= 100 ? DIGIMOD(ii, 100) : ' '); - conv[4] = DIGIMOD(ii, 10); - conv[5] = '.'; - conv[6] = DIGIMOD(ii, 1); - return &conv[3]; - } - - #endif // LCD_DECIMAL_SMALL_XY - - // Convert float to fixed-length string with +123.4 / -123.4 format - char* ftostr41sign(const float &f) { - int i = (f * 100 + (f < 0 ? -5: 5)) / 10; - conv[1] = MINUSOR(i, '+'); - conv[2] = DIGIMOD(i, 1000); - conv[3] = DIGIMOD(i, 100); - conv[4] = DIGIMOD(i, 10); - conv[5] = '.'; - conv[6] = DIGIMOD(i, 1); - return &conv[1]; - } - - // Convert signed float to string (6 digit) with -1.234 / _0.000 / +1.234 format - char* ftostr43sign(const float &f, char plus/*=' '*/) { - long i = (f * 10000 + (f < 0 ? -5: 5)) / 10; - conv[1] = i ? MINUSOR(i, plus) : ' '; - conv[2] = DIGIMOD(i, 1000); - conv[3] = '.'; - conv[4] = DIGIMOD(i, 100); - conv[5] = DIGIMOD(i, 10); - conv[6] = DIGIMOD(i, 1); - return &conv[1]; - } - - // Convert signed float to string (5 digit) with -1.2345 / _0.0000 / +1.2345 format - char* ftostr54sign(const float &f, char plus/*=' '*/) { - long i = (f * 100000 + (f < 0 ? -5: 5)) / 10; - conv[0] = i ? MINUSOR(i, plus) : ' '; - conv[1] = DIGIMOD(i, 10000); - conv[2] = '.'; - conv[3] = DIGIMOD(i, 1000); - conv[4] = DIGIMOD(i, 100); - conv[5] = DIGIMOD(i, 10); - conv[6] = DIGIMOD(i, 1); - return &conv[0]; - } - - // Convert unsigned float to rj string with 12345 format - char* ftostr5rj(const float &f) { - const long i = ((f < 0 ? -f : f) * 10 + 5) / 10; - conv[2] = RJDIGIT(i, 10000); - conv[3] = RJDIGIT(i, 1000); - conv[4] = RJDIGIT(i, 100); - conv[5] = RJDIGIT(i, 10); - conv[6] = DIGIMOD(i, 1); - return &conv[2]; - } - - // Convert signed float to string with +1234.5 format - char* ftostr51sign(const float &f) { - long i = (f * 100 + (f < 0 ? -5: 5)) / 10; - conv[0] = MINUSOR(i, '+'); - conv[1] = DIGIMOD(i, 10000); - conv[2] = DIGIMOD(i, 1000); - conv[3] = DIGIMOD(i, 100); - conv[4] = DIGIMOD(i, 10); - conv[5] = '.'; - conv[6] = DIGIMOD(i, 1); - return conv; - } - - // Convert signed float to string with +123.45 format - char* ftostr52sign(const float &f) { - long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; - conv[0] = MINUSOR(i, '+'); - conv[1] = DIGIMOD(i, 10000); - conv[2] = DIGIMOD(i, 1000); - conv[3] = DIGIMOD(i, 100); - conv[4] = '.'; - conv[5] = DIGIMOD(i, 10); - conv[6] = DIGIMOD(i, 1); - return conv; - } - - // Convert unsigned float to string with 1234.5 format omitting trailing zeros - char* ftostr51rj(const float &f) { - const long i = ((f < 0 ? -f : f) * 100 + 5) / 10; - conv[0] = ' '; - conv[1] = RJDIGIT(i, 10000); - conv[2] = RJDIGIT(i, 1000); - conv[3] = RJDIGIT(i, 100); - conv[4] = DIGIMOD(i, 10); - conv[5] = '.'; - conv[6] = DIGIMOD(i, 1); - return conv; - } - - // Convert signed float to space-padded string with -_23.4_ format - char* ftostr52sp(const float &f) { - long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; - uint8_t dig; - conv[0] = MINUSOR(i, ' '); - conv[1] = RJDIGIT(i, 10000); - conv[2] = RJDIGIT(i, 1000); - conv[3] = DIGIMOD(i, 100); - - if ((dig = i % 10)) { // second digit after decimal point? - conv[4] = '.'; - conv[5] = DIGIMOD(i, 10); - conv[6] = DIGIT(dig); - } - else { - if ((dig = (i / 10) % 10)) { // first digit after decimal point? - conv[4] = '.'; - conv[5] = DIGIT(dig); - } - else // nothing after decimal point - conv[4] = conv[5] = ' '; - conv[6] = ' '; - } - return conv; - } - -#endif // ULTRA_LCD - #if ENABLED(DEBUG_LEVELING_FEATURE) #include "../module/probe.h" #include "../module/motion.h" #include "../module/stepper.h" + #include "../module/stepper.h" + #include "../libs/numtostr.h" #include "../feature/bedlevel/bedlevel.h" void log_machine_info() { @@ -346,10 +66,14 @@ void safe_delay(millis_t ms) { "BLTOUCH" #elif HAS_Z_SERVO_PROBE "SERVO PROBE" + #elif ENABLED(TOUCH_MI_PROBE) + "TOUCH_MI_PROBE" #elif ENABLED(Z_PROBE_SLED) "Z_PROBE_SLED" #elif ENABLED(Z_PROBE_ALLEN_KEY) "Z_PROBE_ALLEN_KEY" + #elif ENABLED(SOLENOID_PROBE) + "SOLENOID_PROBE" #else "NONE" #endif diff --git a/Marlin/src/core/utility.h b/Marlin/src/core/utility.h index 8cfb43109f..2e226e2ba2 100644 --- a/Marlin/src/core/utility.h +++ b/Marlin/src/core/utility.h @@ -37,93 +37,10 @@ inline void serial_delay(const millis_t ms) { #endif } -#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE) - void crc16(uint16_t *crc, const void * const data, uint16_t cnt); -#endif - -#if EITHER(AUTO_BED_LEVELING_UBL, G26_MESH_VALIDATION) - /** - * These support functions allow the use of large bit arrays of flags that take very - * little RAM. Currently they are limited to being 16x16 in size. Changing the declaration - * to unsigned long will allow us to go to 32x32 if higher resolution Mesh's are needed - * in the future. - */ - FORCE_INLINE void bitmap_clear(uint16_t bits[16], const uint8_t x, const uint8_t y) { CBI(bits[y], x); } - FORCE_INLINE void bitmap_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { SBI(bits[y], x); } - FORCE_INLINE bool is_bitmap_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { return TEST(bits[y], x); } -#endif - -#if ANY(ULTRA_LCD, DEBUG_LEVELING_FEATURE, EXTENSIBLE_UI) - - // Convert a full-range unsigned 8bit int to a percentage - char* ui8tostr4pct(const uint8_t i); - - // Convert uint8_t to string with 123 format - char* ui8tostr3(const uint8_t x); - - // Convert int8_t to string with 123 format - char* i8tostr3(const int8_t x); - - // Convert uint16_t to string with 123 format - char* ui16tostr3(const uint16_t x); - - // Convert uint16_t to string with 1234 format - char* ui16tostr4(const uint16_t x); - - // Convert int16_t to string with 123 format - char* i16tostr3(const int16_t x); - - // Convert unsigned int to lj string with 123 format - char* i16tostr3left(const int16_t xx); - - // Convert signed int to rj string with _123, -123, _-12, or __-1 format - char* i16tostr4sign(const int16_t x); - - // Convert unsigned float to string with 1.23 format - char* ftostr12ns(const float &x); - - // Convert signed float to fixed-length string with 12.34 / -2.34 or 023.45 / -23.45 format - char* ftostr42_52(const float &x); - - // Convert signed float to fixed-length string with 023.45 / -23.45 format - char* ftostr52(const float &x); - - // Convert float to fixed-length string with +123.4 / -123.4 format - char* ftostr41sign(const float &x); - - // Convert signed float to string (6 digit) with -1.234 / _0.000 / +1.234 format - char* ftostr43sign(const float &x, char plus=' '); - - // Convert signed float to string (5 digit) with -1.2345 / _0.0000 / +1.2345 format - char* ftostr54sign(const float &x, char plus=' '); - - // Convert unsigned float to rj string with 12345 format - char* ftostr5rj(const float &x); - - // Convert signed float to string with +1234.5 format - char* ftostr51sign(const float &x); - - // Convert signed float to space-padded string with -_23.4_ format - char* ftostr52sp(const float &x); - - // Convert signed float to string with +123.45 format - char* ftostr52sign(const float &x); - - // Convert unsigned float to string with 1234.5 format omitting trailing zeros - char* ftostr51rj(const float &x); - - // Convert float to rj string with 123 or -12 format - FORCE_INLINE char* ftostr3(const float &x) { return i16tostr3(int16_t(x + (x < 0 ? -0.5f : 0.5f))); } - - #if ENABLED(LCD_DECIMAL_SMALL_XY) - // Convert float to rj string with 1234, _123, 12.3, _1.2, -123, _-12, or -1.2 format - char* ftostr4sign(const float &fx); - #else - // Convert float to rj string with 1234, _123, -123, __12, _-12, ___1, or __-1 format - FORCE_INLINE char* ftostr4sign(const float &x) { return i16tostr4sign(int16_t(x + (x < 0 ? -0.5f : 0.5f))); } - #endif - -#endif // ULTRA_LCD +// 16x16 bit arrays +FORCE_INLINE void bitmap_clear(uint16_t bits[16], const uint8_t x, const uint8_t y) { CBI(bits[y], x); } +FORCE_INLINE void bitmap_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { SBI(bits[y], x); } +FORCE_INLINE bool is_bitmap_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { return TEST(bits[y], x); } #if ENABLED(DEBUG_LEVELING_FEATURE) void log_machine_info(); @@ -148,4 +65,3 @@ public: // Converts from an uint8_t in the range of 0-255 to an uint8_t // in the range 0-100 while avoiding rounding artifacts constexpr uint8_t ui8_to_percent(const uint8_t i) { return (int(i) * 100 + 127) / 255; } -constexpr uint8_t all_on = 0xFF, all_off = 0x00; diff --git a/Marlin/src/feature/backlash.h b/Marlin/src/feature/backlash.h index f2dffe1311..623a5fa0ff 100644 --- a/Marlin/src/feature/backlash.h +++ b/Marlin/src/feature/backlash.h @@ -24,6 +24,8 @@ #include "../inc/MarlinConfigPre.h" #include "../module/planner.h" +constexpr uint8_t all_on = 0xFF, all_off = 0x00; + class Backlash { public: #ifdef BACKLASH_DISTANCE_MM diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp index 09bb7a23e1..7a1eb112fc 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp @@ -313,6 +313,7 @@ // Check for commands that require the printer to be homed if (may_move) { + planner.synchronize(); if (axis_unhomed_error()) gcode.home_all_axes(); #if ENABLED(DUAL_X_CARRIAGE) if (active_extruder != 0) tool_change(0); @@ -1449,7 +1450,7 @@ #if HAS_LCD_MENU ui.status_printf_P(0, PSTR(MSG_LCD_TILTING_MESH " 3/3")); #endif - + measured_z = probe_pt(PROBE_PT_3_X, PROBE_PT_3_Y, PROBE_PT_STOW, g29_verbose_level); //z3 = measured_z; if (isnan(measured_z)) @@ -1477,7 +1478,7 @@ else { // !do_3_pt_leveling bool zig_zag = false; - + uint16_t total_points = g29_grid_size * g29_grid_size, current = 1; for (uint8_t ix = 0; ix < g29_grid_size; ix++) { diff --git a/Marlin/src/feature/bltouch.cpp b/Marlin/src/feature/bltouch.cpp index abaeb153ee..8c6a858181 100644 --- a/Marlin/src/feature/bltouch.cpp +++ b/Marlin/src/feature/bltouch.cpp @@ -53,6 +53,9 @@ void BLTouch::init(const bool set_voltage/*=false*/) { // This mode will stay active until manual SET_OD_MODE or power cycle // BLTOUCH V3.1: SET_5V_MODE or SET_OD_MODE (if enabled). // At power on, the probe will default to the eeprom settings configured by the user + _reset(); + _stow(); + #if ENABLED(BLTOUCH_FORCE_MODE_SET) constexpr bool should_set = true; @@ -84,9 +87,6 @@ void BLTouch::init(const bool set_voltage/*=false*/) { || true #endif )); - - _reset(); - _stow(); } void BLTouch::clear() { diff --git a/Marlin/src/feature/bltouch.h b/Marlin/src/feature/bltouch.h index b349c61804..8c05008d6e 100644 --- a/Marlin/src/feature/bltouch.h +++ b/Marlin/src/feature/bltouch.h @@ -36,24 +36,22 @@ typedef unsigned char BLTCommand; #define BLTOUCH_RESET 160 /** - * The following commands may require different delays. + * The following commands require different minimum delays. * - * ANTClabs recommends 2000ms for 5V/OD commands. However it is - * not common for other commands to immediately follow these, - * and testing has shown that these complete in 500ms reliably. + * 500ms required for a reliable Reset. * - * AntClabs recommends 750ms for Deploy/Stow, otherwise you will - * not catch an alarm state until the following move command. + * 750ms required for Deploy/Stow, otherwise the alarm state + * will not be seen until the following move command. */ #ifndef BLTOUCH_SET5V_DELAY - #define BLTOUCH_SET5V_DELAY BLTOUCH_DELAY + #define BLTOUCH_SET5V_DELAY 150 #endif #ifndef BLTOUCH_SETOD_DELAY - #define BLTOUCH_SETOD_DELAY BLTOUCH_DELAY + #define BLTOUCH_SETOD_DELAY 150 #endif #ifndef BLTOUCH_MODE_STORE_DELAY - #define BLTOUCH_MODE_STORE_DELAY BLTOUCH_DELAY + #define BLTOUCH_MODE_STORE_DELAY 150 #endif #ifndef BLTOUCH_DEPLOY_DELAY #define BLTOUCH_DEPLOY_DELAY 750 @@ -62,7 +60,7 @@ typedef unsigned char BLTCommand; #define BLTOUCH_STOW_DELAY 750 #endif #ifndef BLTOUCH_RESET_DELAY - #define BLTOUCH_RESET_DELAY BLTOUCH_DELAY + #define BLTOUCH_RESET_DELAY 500 #endif class BLTouch { diff --git a/Marlin/src/feature/caselight.cpp b/Marlin/src/feature/caselight.cpp index 1256acb6d7..4a4b8034f4 100644 --- a/Marlin/src/feature/caselight.cpp +++ b/Marlin/src/feature/caselight.cpp @@ -69,12 +69,15 @@ void update_case_light() { #else // !CASE_LIGHT_USE_NEOPIXEL - if (PWM_PIN(CASE_LIGHT_PIN)) - analogWrite(CASE_LIGHT_PIN, n10ct); - else { - const bool s = case_light_on ? !INVERT_CASE_LIGHT : INVERT_CASE_LIGHT; - WRITE(CASE_LIGHT_PIN, s ? HIGH : LOW); - } + #if DISABLED(CASE_LIGHT_NO_BRIGHTNESS) + if (PWM_PIN(CASE_LIGHT_PIN)) + analogWrite(CASE_LIGHT_PIN, n10ct); + else + #endif + { + const bool s = case_light_on ? !INVERT_CASE_LIGHT : INVERT_CASE_LIGHT; + WRITE(CASE_LIGHT_PIN, s ? HIGH : LOW); + } #endif // !CASE_LIGHT_USE_NEOPIXEL } diff --git a/Marlin/src/feature/dac/dac_mcp4728.cpp b/Marlin/src/feature/dac/dac_mcp4728.cpp index 689be54f96..727f792eef 100644 --- a/Marlin/src/feature/dac/dac_mcp4728.cpp +++ b/Marlin/src/feature/dac/dac_mcp4728.cpp @@ -58,7 +58,7 @@ void mcp4728_init() { * Write input resister value to specified channel using fastwrite method. * Channel : 0-3, Values : 0-4095 */ -uint8_t mcp4728_analogWrite(uint8_t channel, uint16_t value) { +uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value) { mcp4728_values[channel] = value; return mcp4728_fastWrite(); } @@ -81,7 +81,7 @@ uint8_t mcp4728_eepromWrite() { /** * Write Voltage reference setting to all input regiters */ -uint8_t mcp4728_setVref_all(uint8_t value) { +uint8_t mcp4728_setVref_all(const uint8_t value) { Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); Wire.write(VREFWRITE | (value ? 0x0F : 0x00)); return Wire.endTransmission(); @@ -89,7 +89,7 @@ uint8_t mcp4728_setVref_all(uint8_t value) { /** * Write Gain setting to all input regiters */ -uint8_t mcp4728_setGain_all(uint8_t value) { +uint8_t mcp4728_setGain_all(const uint8_t value) { Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); Wire.write(GAINWRITE | (value ? 0x0F : 0x00)); return Wire.endTransmission(); @@ -98,25 +98,24 @@ uint8_t mcp4728_setGain_all(uint8_t value) { /** * Return Input Register value */ -uint16_t mcp4728_getValue(uint8_t channel) { return mcp4728_values[channel]; } +uint16_t mcp4728_getValue(const uint8_t channel) { return mcp4728_values[channel]; } #if 0 /** * Steph: Might be useful in the future * Return Vout */ -uint16_t mcp4728_getVout(uint8_t channel) { - uint32_t vref = 2048, - vOut = (vref * mcp4728_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096; - if (vOut > defaultVDD) vOut = defaultVDD; - return vOut; +uint16_t mcp4728_getVout(const uint8_t channel) { + const uint32_t vref = 2048, + vOut = (vref * mcp4728_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096; + return MIN(vOut, defaultVDD); } #endif /** * Returns DAC values as a 0-100 percentage of drive strength */ -uint8_t mcp4728_getDrvPct(uint8_t channel) { return uint8_t(100.0 * mcp4728_values[channel] / (DAC_STEPPER_MAX) + 0.5); } +uint8_t mcp4728_getDrvPct(const uint8_t channel) { return uint8_t(100.0 * mcp4728_values[channel] / (DAC_STEPPER_MAX) + 0.5); } /** * Receives all Drive strengths as 0-100 percent values, updates @@ -144,7 +143,7 @@ uint8_t mcp4728_fastWrite() { /** * Common function for simple general commands */ -uint8_t mcp4728_simpleCommand(byte simpleCommand) { +uint8_t mcp4728_simpleCommand(const byte simpleCommand) { Wire.beginTransmission(I2C_ADDRESS(GENERALCALL)); Wire.write(simpleCommand); return Wire.endTransmission(); diff --git a/Marlin/src/feature/dac/dac_mcp4728.h b/Marlin/src/feature/dac/dac_mcp4728.h index c1fd6151ec..6184e5c598 100644 --- a/Marlin/src/feature/dac/dac_mcp4728.h +++ b/Marlin/src/feature/dac/dac_mcp4728.h @@ -46,12 +46,12 @@ #define DAC_DEV_ADDRESS (BASE_ADDR | DAC_OR_ADDRESS) void mcp4728_init(); -uint8_t mcp4728_analogWrite(uint8_t channel, uint16_t value); +uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value); uint8_t mcp4728_eepromWrite(); -uint8_t mcp4728_setVref_all(uint8_t value); -uint8_t mcp4728_setGain_all(uint8_t value); -uint16_t mcp4728_getValue(uint8_t channel); +uint8_t mcp4728_setVref_all(const uint8_t value); +uint8_t mcp4728_setGain_all(const uint8_t value); +uint16_t mcp4728_getValue(const uint8_t channel); uint8_t mcp4728_fastWrite(); -uint8_t mcp4728_simpleCommand(byte simpleCommand); -uint8_t mcp4728_getDrvPct(uint8_t channel); +uint8_t mcp4728_simpleCommand(const byte simpleCommand); +uint8_t mcp4728_getDrvPct(const uint8_t channel); void mcp4728_setDrvPct(uint8_t pct[XYZE]); diff --git a/Marlin/src/feature/host_actions.cpp b/Marlin/src/feature/host_actions.cpp index 1154553e27..6893f2c593 100644 --- a/Marlin/src/feature/host_actions.cpp +++ b/Marlin/src/feature/host_actions.cpp @@ -142,7 +142,7 @@ void host_action(const char * const pstr, const bool eol) { break; case PROMPT_PAUSE_RESUME: msg = PSTR("LCD_PAUSE_RESUME"); - enqueue_and_echo_commands_P(PSTR("M24")); + queue.inject_P(PSTR("M24")); break; case PROMPT_INFO: msg = PSTR("GCODE_INFO"); diff --git a/Marlin/src/feature/leds/leds.cpp b/Marlin/src/feature/leds/leds.cpp index d54bd9486e..de5c6c81cd 100644 --- a/Marlin/src/feature/leds/leds.cpp +++ b/Marlin/src/feature/leds/leds.cpp @@ -71,6 +71,9 @@ void LEDLights::setup() { #if ENABLED(NEOPIXEL_LED) setup_neopixel(); #endif + #if ENABLED(PCA9533) + RGBinit(); + #endif #if ENABLED(LED_USER_PRESET_STARTUP) set_default(); #endif @@ -115,7 +118,9 @@ void LEDLights::set_color(const LEDColor &incol // This variant uses 3-4 separate pins for the RGB(W) components. // If the pins can do PWM then their intensity will be set. - #define UPDATE_RGBW(C,c) do{ if (PWM_PIN(RGB_LED_##C##_PIN)) analogWrite(RGB_LED_##C##_PIN, incol.c); else WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); }while(0) + #define UPDATE_RGBW(C,c) do { if (PWM_PIN(RGB_LED_##C##_PIN)) \ + analogWrite(pin_t(RGB_LED_##C##_PIN), incol.c); \ + else WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); } while(0) UPDATE_RGBW(R,r); UPDATE_RGBW(G,g); UPDATE_RGBW(B,b); @@ -145,4 +150,18 @@ void LEDLights::set_color(const LEDColor &incol void LEDLights::toggle() { if (lights_on) set_off(); else update(); } #endif +#ifdef LED_BACKLIGHT_TIMEOUT + + millis_t LEDLights::led_off_time; // = 0 + + void LEDLights::update_timeout(const bool power_on) { + const millis_t ms = millis(); + if (power_on) + reset_timeout(ms); + else if (ELAPSED(ms, led_off_time)) + set_off(); + } + +#endif + #endif // HAS_COLOR_LEDS diff --git a/Marlin/src/feature/leds/leds.h b/Marlin/src/feature/leds/leds.h index eafede7dc9..e3b060e267 100644 --- a/Marlin/src/feature/leds/leds.h +++ b/Marlin/src/feature/leds/leds.h @@ -201,6 +201,17 @@ public: static void toggle(); // swap "off" with color static inline void update() { set_color(color); } #endif + + #ifdef LED_BACKLIGHT_TIMEOUT + private: + static millis_t led_off_time; + public: + static inline void reset_timeout(const millis_t &ms) { + led_off_time = ms + LED_BACKLIGHT_TIMEOUT; + if (!lights_on) set_default(); + } + static void update_timeout(const bool power_on); + #endif }; extern LEDLights leds; diff --git a/Marlin/src/feature/leds/neopixel.cpp b/Marlin/src/feature/leds/neopixel.cpp index ee2854c27a..1c1afcc5fc 100644 --- a/Marlin/src/feature/leds/neopixel.cpp +++ b/Marlin/src/feature/leds/neopixel.cpp @@ -36,10 +36,20 @@ Adafruit_NeoPixel pixels(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE + NEO_KHZ800); +#ifdef NEOPIXEL_BKGD_LED_INDEX + void set_neopixel_color_background() { + uint8_t background_color[4] = NEOPIXEL_BKGD_COLOR; + pixels.setPixelColor(NEOPIXEL_BKGD_LED_INDEX, pixels.Color(background_color[0], background_color[1], background_color[2], background_color[3])); + } +#endif + void set_neopixel_color(const uint32_t color) { for (uint16_t i = 0; i < pixels.numPixels(); ++i) { #ifdef NEOPIXEL_BKGD_LED_INDEX - if (NEOPIXEL_BKGD_LED_INDEX == i) i++; + if (i == NEOPIXEL_BKGD_LED_INDEX && color != 0x000000) { + set_neopixel_color_background(); + continue; + } #endif pixels.setPixelColor(i, color); } @@ -52,14 +62,6 @@ void set_neopixel_color_startup(const uint32_t color) { pixels.show(); } -#ifdef NEOPIXEL_BKGD_LED_INDEX - void set_neopixel_color_background() { - uint8_t background_color[4] = NEOPIXEL_BKGD_COLOR; - pixels.setPixelColor(NEOPIXEL_BKGD_LED_INDEX, pixels.Color(background_color[0], background_color[1], background_color[2], background_color[3])); - pixels.show(); - } -#endif - void setup_neopixel() { SET_OUTPUT(NEOPIXEL_PIN); pixels.setBrightness(NEOPIXEL_BRIGHTNESS); // 0 - 255 range diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 4ebc41028c..131acdd7c9 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -681,8 +681,11 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le // Resume the print job timer if it was running if (print_job_timer.isPaused()) print_job_timer.start(); - #if HAS_LCD_MENU - ui.return_to_status(); + #if HAS_DISPLAY + ui.reset_status(); + #if HAS_LCD_MENU + ui.return_to_status(); + #endif #endif } diff --git a/Marlin/src/feature/power_loss_recovery.cpp b/Marlin/src/feature/power_loss_recovery.cpp index 906315d284..2fa184890e 100644 --- a/Marlin/src/feature/power_loss_recovery.cpp +++ b/Marlin/src/feature/power_loss_recovery.cpp @@ -98,7 +98,7 @@ void PrintJobRecovery::check() { if (card.isDetected()) { load(); if (!valid()) return purge(); - enqueue_and_echo_commands_P(PSTR("M1000 S")); + queue.inject_P(PSTR("M1000 S")); } } } @@ -209,9 +209,9 @@ void PrintJobRecovery::save(const bool force/*=false*/, const bool save_queue/*= info.relative_modes_e = gcode.axis_relative_modes[E_AXIS]; // Commands in the queue - info.commands_in_queue = save_queue ? commands_in_queue : 0; - info.cmd_queue_index_r = cmd_queue_index_r; - COPY(info.command_queue, command_queue); + info.queue_length = save_queue ? queue.length : 0; + info.queue_index_r = queue.index_r; + COPY(info.queue_buffer, queue.buffer); // Elapsed print job time info.print_job_elapsed = print_job_timer.duration(); @@ -278,7 +278,7 @@ void PrintJobRecovery::resume() { // Pretend that all axes are homed axis_homed = axis_known_position = xyz_bits; - char cmd[50], str_1[16], str_2[16]; + char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16]; // Select the previously active tool (with no_move) #if EXTRUDERS > 1 @@ -361,7 +361,12 @@ void PrintJobRecovery::resume() { // Move back to the saved Z dtostrf(info.current_position[Z_AXIS], 1, 3, str_1); - sprintf_P(cmd, PSTR("G1 Z%s F200"), str_1); + #if Z_HOME_DIR > 0 + sprintf_P(cmd, PSTR("G1 Z%s F200"), str_1); + #else + gcode.process_subcommands_now_P(PSTR("G1 Z0 F200")); + sprintf_P(cmd, PSTR("G92.9 Z%s"), str_1); + #endif gcode.process_subcommands_now(cmd); // Un-retract @@ -397,9 +402,9 @@ void PrintJobRecovery::resume() { #endif // Process commands from the old pending queue - uint8_t c = info.commands_in_queue, r = info.cmd_queue_index_r; + uint8_t c = info.queue_length, r = info.queue_index_r; for (; c--; r = (r + 1) % BUFSIZE) - gcode.process_subcommands_now(info.command_queue[r]); + gcode.process_subcommands_now(info.queue_buffer[r]); // Resume the SD file from the last position char *fn = info.sd_filename; @@ -479,9 +484,9 @@ void PrintJobRecovery::resume() { DEBUG_EOL(); DEBUG_ECHOLNPAIR("retract_hop: ", info.retract_hop); #endif - DEBUG_ECHOLNPAIR("cmd_queue_index_r: ", int(info.cmd_queue_index_r)); - DEBUG_ECHOLNPAIR("commands_in_queue: ", int(info.commands_in_queue)); - for (uint8_t i = 0; i < info.commands_in_queue; i++) DEBUG_ECHOLNPAIR("> ", info.command_queue[i]); + DEBUG_ECHOLNPAIR("queue_index_r: ", int(info.queue_index_r)); + DEBUG_ECHOLNPAIR("queue_length: ", int(info.queue_length)); + for (uint8_t i = 0; i < info.queue_length; i++) DEBUG_ECHOLNPAIR("> ", info.queue_buffer[i]); DEBUG_ECHOLNPAIR("sd_filename: ", info.sd_filename); DEBUG_ECHOLNPAIR("sdpos: ", info.sdpos); DEBUG_ECHOLNPAIR("print_job_elapsed: ", info.print_job_elapsed); diff --git a/Marlin/src/feature/power_loss_recovery.h b/Marlin/src/feature/power_loss_recovery.h index e7f8c09124..b7684fccb6 100644 --- a/Marlin/src/feature/power_loss_recovery.h +++ b/Marlin/src/feature/power_loss_recovery.h @@ -87,8 +87,8 @@ typedef struct { bool relative_mode, relative_modes_e; // Command queue - uint8_t commands_in_queue, cmd_queue_index_r; - char command_queue[BUFSIZE][MAX_CMD_SIZE]; + uint8_t queue_length, queue_index_r; + char queue_buffer[BUFSIZE][MAX_CMD_SIZE]; // SD Filename and position char sd_filename[MAXPATHNAMELENGTH]; diff --git a/Marlin/src/feature/prusa_MMU2/mmu2.cpp b/Marlin/src/feature/prusa_MMU2/mmu2.cpp index b3eb60bf5e..0870b168ba 100644 --- a/Marlin/src/feature/prusa_MMU2/mmu2.cpp +++ b/Marlin/src/feature/prusa_MMU2/mmu2.cpp @@ -650,7 +650,7 @@ void MMU2::set_filament_type(uint8_t index, uint8_t filamentType) { } void MMU2::filament_runout() { - enqueue_and_echo_commands_P(PSTR(MMU2_FILAMENT_RUNOUT_SCRIPT)); + queue.inject_P(PSTR(MMU2_FILAMENT_RUNOUT_SCRIPT)); planner.synchronize(); } diff --git a/Marlin/src/feature/tmc_util.cpp b/Marlin/src/feature/tmc_util.cpp index 50ed030a19..b91be7e9a1 100644 --- a/Marlin/src/feature/tmc_util.cpp +++ b/Marlin/src/feature/tmc_util.cpp @@ -69,7 +69,7 @@ #endif ; #if ENABLED(TMC_DEBUG) - #if HAS_TMCX1X0 || HAS_DRIVER(TMC2208) + #if HAS_TMCX1X0 || HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) uint8_t cs_actual; #endif #if HAS_STALLGUARD @@ -95,38 +95,40 @@ constexpr uint8_t STST_bp = 31; #endif TMC_driver_data data; - data.drv_status = st.DRV_STATUS(); + const auto ds = data.drv_status = st.DRV_STATUS(); #ifdef __AVR__ + // 8-bit optimization saves up to 70 bytes of PROGMEM per axis uint8_t spart; #if ENABLED(TMC_DEBUG) - data.sg_result = data.drv_status & SG_RESULT_bm; - spart = data.drv_status >> 8; - data.is_stealth = !!(spart & _BV(STEALTH_bp - 8)); - spart = data.drv_status >> 16; + data.sg_result = ds & SG_RESULT_bm; + spart = ds >> 8; + data.is_stealth = TEST(spart, STEALTH_bp - 8); + spart = ds >> 16; data.cs_actual = spart & (CS_ACTUAL_bm >> 16); #endif - spart = data.drv_status >> 24; - data.is_ot = !!(spart & _BV(OT_bp - 24)); - data.is_otpw = !!(spart & _BV(OTPW_bp - 24)); + spart = ds >> 24; + data.is_ot = TEST(spart, OT_bp - 24); + data.is_otpw = TEST(spart, OTPW_bp - 24); data.is_s2g = !!(spart & (S2G_bm >> 24)); #if ENABLED(TMC_DEBUG) - data.is_stall = !!(spart & _BV(STALL_GUARD_bp - 24)); - data.is_standstill = !!(spart & _BV(STST_bp - 24)); + data.is_stall = TEST(spart, STALL_GUARD_bp - 24); + data.is_standstill = TEST(spart, STST_bp - 24); data.sg_result_reasonable = !data.is_standstill; // sg_result has no reasonable meaning while standstill #endif + #else // !__AVR__ - data.is_ot = !!(data.drv_status & _BV(OT_bp)); - data.is_otpw = !!(data.drv_status & _BV(OTPW_bp)); - data.is_s2g = !!(data.drv_status & S2G_bm); + data.is_ot = TEST(ds, OT_bp); + data.is_otpw = TEST(ds, OTPW_bp); + data.is_s2g = !!(ds & S2G_bm); #if ENABLED(TMC_DEBUG) constexpr uint8_t CS_ACTUAL_sb = 16; - data.sg_result = data.drv_status & SG_RESULT_bm; - data.is_stealth = !!(data.drv_status & _BV(STEALTH_bp)); - data.cs_actual = (data.drv_status & CS_ACTUAL_bm) >> CS_ACTUAL_sb; - data.is_stall = !!(data.drv_status & _BV(STALL_GUARD_bp)); - data.is_standstill = !!(data.drv_status & _BV(STST_bp)); + data.sg_result = ds & SG_RESULT_bm; + data.is_stealth = TEST(ds, STEALTH_bp); + data.cs_actual = (ds & CS_ACTUAL_bm) >> CS_ACTUAL_sb; + data.is_stall = TEST(ds, STALL_GUARD_bp); + data.is_standstill = TEST(ds, STST_bp); data.sg_result_reasonable = !data.is_standstill; // sg_result has no reasonable meaning while standstill #endif @@ -137,7 +139,7 @@ #endif // HAS_TMCX1X0 - #if HAS_DRIVER(TMC2208) + #if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) #if ENABLED(TMC_DEBUG) static uint32_t get_pwm_scale(TMC2208Stepper &st) { return st.pwm_scale_sum(); } @@ -147,25 +149,25 @@ constexpr uint8_t OTPW_bp = 0, OT_bp = 1; constexpr uint8_t S2G_bm = 0b11110; // 2..5 TMC_driver_data data; - data.drv_status = st.DRV_STATUS(); - data.is_otpw = !!(data.drv_status & _BV(OTPW_bp)); - data.is_ot = !!(data.drv_status & _BV(OT_bp)); - data.is_s2g = !!(data.drv_status & S2G_bm); + const auto ds = data.drv_status = st.DRV_STATUS(); + data.is_otpw = TEST(ds, OTPW_bp); + data.is_ot = TEST(ds, OT_bp); + data.is_s2g = !!(ds & S2G_bm); #if ENABLED(TMC_DEBUG) constexpr uint32_t CS_ACTUAL_bm = 0x1F0000; // 16:20 constexpr uint8_t STEALTH_bp = 30, STST_bp = 31; #ifdef __AVR__ // 8-bit optimization saves up to 12 bytes of PROGMEM per axis - uint8_t spart = data.drv_status >> 16; + uint8_t spart = ds >> 16; data.cs_actual = spart & (CS_ACTUAL_bm >> 16); - spart = data.drv_status >> 24; - data.is_stealth = !!(spart & _BV(STEALTH_bp - 24)); - data.is_standstill = !!(spart & _BV(STST_bp - 24)); + spart = ds >> 24; + data.is_stealth = TEST(spart, STEALTH_bp - 24); + data.is_standstill = TEST(spart, STST_bp - 24); #else constexpr uint8_t CS_ACTUAL_sb = 16; - data.cs_actual = (data.drv_status & CS_ACTUAL_bm) >> CS_ACTUAL_sb; - data.is_stealth = !!(data.drv_status & _BV(STEALTH_bp)); - data.is_standstill = !!(data.drv_status & _BV(STST_bp)); + data.cs_actual = (ds & CS_ACTUAL_bm) >> CS_ACTUAL_sb; + data.is_stealth = TEST(ds, STEALTH_bp); + data.is_standstill = TEST(ds, STST_bp); #endif #if HAS_STALLGUARD data.sg_result_reasonable = false; @@ -174,7 +176,7 @@ return data; } - #endif // TMC2208 + #endif // TMC2208 || TMC2209 #if HAS_DRIVER(TMC2660) @@ -186,18 +188,18 @@ constexpr uint8_t OT_bp = 1, OTPW_bp = 2; constexpr uint8_t S2G_bm = 0b11000; TMC_driver_data data; - data.drv_status = st.DRVSTATUS(); - uint8_t spart = data.drv_status & 0xFF; - data.is_otpw = !!(spart & _BV(OTPW_bp)); - data.is_ot = !!(spart & _BV(OT_bp)); - data.is_s2g = !!(data.drv_status & S2G_bm); + const auto ds = data.drv_status = st.DRVSTATUS(); + uint8_t spart = ds & 0xFF; + data.is_otpw = TEST(spart, OTPW_bp); + data.is_ot = TEST(spart, OT_bp); + data.is_s2g = !!(ds & S2G_bm); #if ENABLED(TMC_DEBUG) constexpr uint8_t STALL_GUARD_bp = 0; constexpr uint8_t STST_bp = 7, SG_RESULT_sp = 10; constexpr uint32_t SG_RESULT_bm = 0xFFC00; // 10:19 - data.is_stall = !!(spart & _BV(STALL_GUARD_bp)); - data.is_standstill = !!(spart & _BV(STST_bp)); - data.sg_result = (data.drv_status & SG_RESULT_bm) >> SG_RESULT_sp; + data.is_stall = TEST(spart, STALL_GUARD_bp); + data.is_standstill = TEST(spart, STST_bp); + data.sg_result = (ds & SG_RESULT_bm) >> SG_RESULT_sp; data.sg_result_reasonable = true; #endif return data; @@ -228,9 +230,7 @@ SERIAL_ECHO(timestamp); SERIAL_ECHOPGM(": "); st.printLabel(); - SERIAL_ECHOPGM(" driver overtemperature warning! ("); - SERIAL_ECHO(st.getMilliamps()); - SERIAL_ECHOLNPGM("mA)"); + SERIAL_ECHOLNPAIR(" driver overtemperature warning! (", st.getMilliamps(), "mA)"); } template @@ -239,7 +239,7 @@ st.printLabel(); SERIAL_CHAR(':'); SERIAL_PRINT(pwm_scale, DEC); #if ENABLED(TMC_DEBUG) - #if HAS_TMCX1X0 || HAS_DRIVER(TMC2208) + #if HAS_TMCX1X0 || HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) SERIAL_CHAR('/'); SERIAL_PRINT(data.cs_actual, DEC); #endif #if HAS_STALLGUARD @@ -386,7 +386,7 @@ if ((report_tmc_status_interval = update_interval)) SERIAL_ECHOLNPGM("axis:pwm_scale" #if HAS_STEALTHCHOP - "/current_scale" + "/curr_scale" #endif #if HAS_STALLGUARD "/mech_load" @@ -398,6 +398,7 @@ enum TMC_debug_enum : char { TMC_CODES, + TMC_UART_ADDR, TMC_ENABLED, TMC_CURRENT, TMC_RMS_CURRENT, @@ -482,9 +483,9 @@ #if HAS_TMCX1X0 static void _tmc_parse_drv_status(TMC2130Stepper &st, const TMC_drv_status_enum i) { switch (i) { - case TMC_STALLGUARD: if (st.stallguard()) SERIAL_CHAR('X'); break; - case TMC_SG_RESULT: SERIAL_PRINT(st.sg_result(), DEC); break; - case TMC_FSACTIVE: if (st.fsactive()) SERIAL_CHAR('X'); break; + case TMC_STALLGUARD: if (st.stallguard()) SERIAL_CHAR('*'); break; + case TMC_SG_RESULT: SERIAL_PRINT(st.sg_result(), DEC); break; + case TMC_FSACTIVE: if (st.fsactive()) SERIAL_CHAR('*'); break; case TMC_DRV_CS_ACTUAL: SERIAL_PRINT(st.cs_actual(), DEC); break; default: break; } @@ -515,22 +516,37 @@ } #endif - #if HAS_DRIVER(TMC2208) + #if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) static void _tmc_status(TMC2208Stepper &st, const TMC_debug_enum i) { switch (i) { case TMC_PWM_SCALE: SERIAL_PRINT(st.pwm_scale_sum(), DEC); break; case TMC_STEALTHCHOP: serialprint_truefalse(st.stealth()); break; - case TMC_S2VSA: if (st.s2vsa()) SERIAL_CHAR('X'); break; - case TMC_S2VSB: if (st.s2vsb()) SERIAL_CHAR('X'); break; + case TMC_S2VSA: if (st.s2vsa()) SERIAL_CHAR('*'); break; + case TMC_S2VSB: if (st.s2vsb()) SERIAL_CHAR('*'); break; default: break; } } + + #if HAS_DRIVER(TMC2209) + template + static void _tmc_status(TMCMarlin &st, const TMC_debug_enum i) { + switch (i) { + case TMC_SGT: SERIAL_PRINT(st.SGTHRS(), DEC); break; + case TMC_UART_ADDR: SERIAL_PRINT(st.get_address(), DEC); break; + default: + TMC2208Stepper *parent = &st; + _tmc_status(*parent, i); + break; + } + } + #endif + static void _tmc_parse_drv_status(TMC2208Stepper &st, const TMC_drv_status_enum i) { switch (i) { - case TMC_T157: if (st.t157()) SERIAL_CHAR('X'); break; - case TMC_T150: if (st.t150()) SERIAL_CHAR('X'); break; - case TMC_T143: if (st.t143()) SERIAL_CHAR('X'); break; - case TMC_T120: if (st.t120()) SERIAL_CHAR('X'); break; + case TMC_T157: if (st.t157()) SERIAL_CHAR('*'); break; + case TMC_T150: if (st.t150()) SERIAL_CHAR('*'); break; + case TMC_T143: if (st.t143()) SERIAL_CHAR('*'); break; + case TMC_T120: if (st.t120()) SERIAL_CHAR('*'); break; case TMC_DRV_CS_ACTUAL: SERIAL_PRINT(st.cs_actual(), DEC); break; default: break; } @@ -565,24 +581,16 @@ case TMC_VSENSE: print_vsense(st); break; case TMC_MICROSTEPS: SERIAL_ECHO(st.microsteps()); break; case TMC_TSTEP: { - uint32_t tstep_value = st.TSTEP(); - if (tstep_value == 0xFFFFF) SERIAL_ECHOPGM("max"); - else SERIAL_ECHO(tstep_value); - } - break; - case TMC_TPWMTHRS: { - uint32_t tpwmthrs_val = st.TPWMTHRS(); - SERIAL_ECHO(tpwmthrs_val); - } - break; - case TMC_TPWMTHRS_MMS: { - uint32_t tpwmthrs_val = st.get_pwm_thrs(); - if (tpwmthrs_val) - SERIAL_ECHO(tpwmthrs_val); - else - SERIAL_CHAR('-'); - } - break; + const uint32_t tstep_value = st.TSTEP(); + if (tstep_value != 0xFFFFF) SERIAL_ECHO(tstep_value); else SERIAL_ECHOPGM("max"); + } break; + #if ENABLED(HYBRID_THRESHOLD) + case TMC_TPWMTHRS: SERIAL_ECHO(uint32_t(st.TPWMTHRS())); break; + case TMC_TPWMTHRS_MMS: { + const uint32_t tpwmthrs_val = st.get_pwm_thrs(); + if (tpwmthrs_val) SERIAL_ECHO(tpwmthrs_val); else SERIAL_CHAR('-'); + } break; + #endif case TMC_OTPW: serialprint_truefalse(st.otpw()); break; #if ENABLED(MONITOR_DRIVER_STATUS) case TMC_OTPW_TRIGGERED: serialprint_truefalse(st.getOTPW()); break; @@ -628,13 +636,13 @@ SERIAL_CHAR('\t'); switch (i) { case TMC_DRV_CODES: st.printLabel(); break; - case TMC_STST: if (st.stst()) SERIAL_CHAR('X'); break; - case TMC_OLB: if (st.olb()) SERIAL_CHAR('X'); break; - case TMC_OLA: if (st.ola()) SERIAL_CHAR('X'); break; - case TMC_S2GB: if (st.s2gb()) SERIAL_CHAR('X'); break; - case TMC_S2GA: if (st.s2ga()) SERIAL_CHAR('X'); break; - case TMC_DRV_OTPW: if (st.otpw()) SERIAL_CHAR('X'); break; - case TMC_OT: if (st.ot()) SERIAL_CHAR('X'); break; + case TMC_STST: if (st.stst()) SERIAL_CHAR('*'); break; + case TMC_OLB: if (st.olb()) SERIAL_CHAR('*'); break; + case TMC_OLA: if (st.ola()) SERIAL_CHAR('*'); break; + case TMC_S2GB: if (st.s2gb()) SERIAL_CHAR('*'); break; + case TMC_S2GA: if (st.s2ga()) SERIAL_CHAR('*'); break; + case TMC_DRV_OTPW: if (st.otpw()) SERIAL_CHAR('*'); break; + case TMC_OT: if (st.ot()) SERIAL_CHAR('*'); break; case TMC_DRV_STATUS_HEX: { const uint32_t drv_status = st.DRV_STATUS(); SERIAL_CHAR('\t'); @@ -767,6 +775,9 @@ #define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM, print_x, print_y, print_z, print_e); }while(0) #define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM, print_x, print_y, print_z, print_e); }while(0) TMC_REPORT("\t", TMC_CODES); + #if HAS_DRIVER(TMC2209) + TMC_REPORT("Address\t", TMC_UART_ADDR); + #endif TMC_REPORT("Enabled\t", TMC_ENABLED); TMC_REPORT("Set current", TMC_CURRENT); TMC_REPORT("RMS current", TMC_RMS_CURRENT); @@ -778,7 +789,7 @@ #endif TMC_REPORT("CS actual\t", TMC_CS_ACTUAL); TMC_REPORT("PWM scale", TMC_PWM_SCALE); - #if HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2224) || HAS_DRIVER(TMC2660) || HAS_DRIVER(TMC2208) + #if HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2224) || HAS_DRIVER(TMC2660) || HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) TMC_REPORT("vsense\t", TMC_VSENSE); #endif TMC_REPORT("stealthChop", TMC_STEALTHCHOP); @@ -810,7 +821,7 @@ DRV_REPORT("s2ga\t", TMC_S2GA); DRV_REPORT("otpw\t", TMC_DRV_OTPW); DRV_REPORT("ot\t", TMC_OT); - #if HAS_DRIVER(TMC2208) + #if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) DRV_REPORT("157C\t", TMC_T157); DRV_REPORT("150C\t", TMC_T150); DRV_REPORT("143C\t", TMC_T143); @@ -834,7 +845,7 @@ } } #endif - #if HAS_DRIVER(TMC2208) + #if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) static void tmc_get_ic_registers(TMC2208Stepper, const TMC_get_registers_enum) { SERIAL_CHAR('\t'); } #endif @@ -969,6 +980,15 @@ st.en_pwm_mode(restore_stealth); st.diag1_stall(false); } + + bool tmc_enable_stallguard(TMC2209Stepper &st) { + st.TCOOLTHRS(0xFFFFF); + return true; + } + void tmc_disable_stallguard(TMC2209Stepper &st, const bool restore_stealth) { + st.TCOOLTHRS(0); + } + bool tmc_enable_stallguard(TMC2660Stepper) { // TODO return false; diff --git a/Marlin/src/feature/tmc_util.h b/Marlin/src/feature/tmc_util.h index 1e73a02c20..eda702db79 100644 --- a/Marlin/src/feature/tmc_util.h +++ b/Marlin/src/feature/tmc_util.h @@ -92,7 +92,7 @@ class TMCStorage { uint8_t hybrid_thrs = 0; #endif #if USE_SENSORLESS - int8_t homing_thrs = 0; + int16_t homing_thrs = 0; #endif } stored; }; @@ -100,10 +100,10 @@ class TMCStorage { template class TMCMarlin : public TMC, public TMCStorage { public: - TMCMarlin(uint16_t cs_pin, float RS) : + TMCMarlin(const uint16_t cs_pin, const float RS) : TMC(cs_pin, RS) {} - TMCMarlin(uint16_t CS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK) : + TMCMarlin(const uint16_t CS, const float RS, const uint16_t pinMOSI, const uint16_t pinMISO, const uint16_t pinSCK) : TMC(CS, RS, pinMOSI, pinMISO, pinSCK) {} inline uint16_t rms_current() { return TMC::rms_current(); } @@ -111,7 +111,7 @@ class TMCMarlin : public TMC, public TMCStorage { this->val_mA = mA; TMC::rms_current(mA); } - inline void rms_current(uint16_t mA, float mult) { + inline void rms_current(const uint16_t mA, const float mult) { this->val_mA = mA; TMC::rms_current(mA, mult); } @@ -132,8 +132,9 @@ class TMCMarlin : public TMC, public TMCStorage { } #endif #if USE_SENSORLESS - inline int8_t sgt() { return TMC::sgt(); } - void sgt(const int8_t sgt_val) { + inline int16_t homing_threshold() { return TMC::sgt(); } + void homing_threshold(int16_t sgt_val) { + sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max); TMC::sgt(sgt_val); #if HAS_LCD_MENU this->stored.homing_thrs = sgt_val; @@ -148,25 +149,28 @@ class TMCMarlin : public TMC, public TMCStorage { inline void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); } #endif #if USE_SENSORLESS - inline void refresh_homing_thrs() { sgt(this->stored.homing_thrs); } + inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); } #endif #endif + + static constexpr int8_t sgt_min = -64, + sgt_max = 63; }; template class TMCMarlin : public TMC2208Stepper, public TMCStorage { public: - TMCMarlin(Stream * SerialPort, float RS, bool has_rx=true) : - TMC2208Stepper(SerialPort, RS, has_rx=true) + TMCMarlin(Stream * SerialPort, const float RS, const uint8_t) : + TMC2208Stepper(SerialPort, RS, /*has_rx=*/true) {} - TMCMarlin(uint16_t RX, uint16_t TX, float RS, bool has_rx=true) : - TMC2208Stepper(RX, TX, RS, has_rx=true) + TMCMarlin(const uint16_t RX, const uint16_t TX, const float RS, const uint8_t, const bool has_rx=true) : + TMC2208Stepper(RX, TX, RS, has_rx) {} uint16_t rms_current() { return TMC2208Stepper::rms_current(); } - inline void rms_current(uint16_t mA) { + inline void rms_current(const uint16_t mA) { this->val_mA = mA; TMC2208Stepper::rms_current(mA); } - inline void rms_current(uint16_t mA, float mult) { + inline void rms_current(const uint16_t mA, const float mult) { this->val_mA = mA; TMC2208Stepper::rms_current(mA, mult); } @@ -195,24 +199,87 @@ class TMCMarlin : public TMC220 #endif #endif }; + +template +class TMCMarlin : public TMC2209Stepper, public TMCStorage { + public: + TMCMarlin(Stream * SerialPort, const float RS, const uint8_t addr) : + TMC2209Stepper(SerialPort, RS, addr) + {} + TMCMarlin(const uint16_t RX, const uint16_t TX, const float RS, const uint8_t addr, const bool) : + TMC2209Stepper(RX, TX, RS, addr) + {} + uint8_t get_address() { return slave_address; } + uint16_t rms_current() { return TMC2209Stepper::rms_current(); } + inline void rms_current(const uint16_t mA) { + this->val_mA = mA; + TMC2209Stepper::rms_current(mA); + } + inline void rms_current(const uint16_t mA, const float mult) { + this->val_mA = mA; + TMC2209Stepper::rms_current(mA, mult); + } + + #if HAS_STEALTHCHOP + inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); } + inline bool get_stealthChop_status() { return !this->en_spreadCycle(); } + #endif + #if ENABLED(HYBRID_THRESHOLD) + uint32_t get_pwm_thrs() { + return _tmc_thrs(this->microsteps(), this->TPWMTHRS(), planner.settings.axis_steps_per_mm[AXIS_ID]); + } + void set_pwm_thrs(const uint32_t thrs) { + TMC2209Stepper::TPWMTHRS(_tmc_thrs(this->microsteps(), thrs, planner.settings.axis_steps_per_mm[AXIS_ID])); + #if HAS_LCD_MENU + this->stored.hybrid_thrs = thrs; + #endif + } + #endif + #if USE_SENSORLESS + inline int16_t homing_threshold() { return TMC2209Stepper::SGTHRS(); } + void homing_threshold(int16_t sgt_val) { + sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max); + TMC2209Stepper::SGTHRS(sgt_val); + #if HAS_LCD_MENU + this->stored.homing_thrs = sgt_val; + #endif + } + #endif + + #if HAS_LCD_MENU + inline void refresh_stepper_current() { rms_current(this->val_mA); } + + #if ENABLED(HYBRID_THRESHOLD) + inline void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); } + #endif + #if USE_SENSORLESS + inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); } + #endif + #endif + + static constexpr uint8_t sgt_min = 0, + sgt_max = 255; +}; + template class TMCMarlin : public TMC2660Stepper, public TMCStorage { public: - TMCMarlin(uint16_t cs_pin, float RS) : + TMCMarlin(const uint16_t cs_pin, const float RS) : TMC2660Stepper(cs_pin, RS) {} - TMCMarlin(uint16_t CS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK) : + TMCMarlin(const uint16_t CS, const float RS, const uint16_t pinMOSI, const uint16_t pinMISO, const uint16_t pinSCK) : TMC2660Stepper(CS, RS, pinMOSI, pinMISO, pinSCK) {} inline uint16_t rms_current() { return TMC2660Stepper::rms_current(); } - inline void rms_current(uint16_t mA) { + inline void rms_current(const uint16_t mA) { this->val_mA = mA; TMC2660Stepper::rms_current(mA); } #if USE_SENSORLESS - inline int8_t sgt() { return TMC2660Stepper::sgt(); } - void sgt(const int8_t sgt_val) { + inline int16_t homing_threshold() { return TMC2660Stepper::sgt(); } + void homing_threshold(int16_t sgt_val) { + sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max); TMC2660Stepper::sgt(sgt_val); #if HAS_LCD_MENU this->stored.homing_thrs = sgt_val; @@ -224,9 +291,12 @@ class TMCMarlin : public TMC266 inline void refresh_stepper_current() { rms_current(this->val_mA); } #if USE_SENSORLESS - inline void refresh_homing_thrs() { sgt(this->stored.homing_thrs); } + inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); } #endif #endif + + static constexpr int8_t sgt_min = -64, + sgt_max = 63; }; template @@ -262,7 +332,7 @@ void tmc_print_current(TMC &st) { void tmc_print_sgt(TMC &st) { st.printLabel(); SERIAL_ECHOPGM(" homing sensitivity: "); - SERIAL_PRINTLN(st.sgt(), DEC); + SERIAL_PRINTLN(st.homing_threshold(), DEC); } #endif @@ -293,6 +363,9 @@ void test_tmc_connection(const bool test_x, const bool test_y, const bool test_z bool tmc_enable_stallguard(TMC2130Stepper &st); void tmc_disable_stallguard(TMC2130Stepper &st, const bool restore_stealth); + bool tmc_enable_stallguard(TMC2209Stepper &st); + void tmc_disable_stallguard(TMC2209Stepper &st, const bool restore_stealth); + bool tmc_enable_stallguard(TMC2660Stepper); void tmc_disable_stallguard(TMC2660Stepper, const bool); #endif diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index f43cfa6a35..bcef33ec4a 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -966,7 +966,7 @@ G29_TYPE GcodeSuite::G29() { #ifdef Z_PROBE_END_SCRIPT if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Z Probe End Script: ", Z_PROBE_END_SCRIPT); planner.synchronize(); - enqueue_and_echo_commands_P(PSTR(Z_PROBE_END_SCRIPT)); + queue.inject_P(PSTR(Z_PROBE_END_SCRIPT)); #endif // Auto Bed Leveling is complete! Enable if possible. diff --git a/Marlin/src/gcode/bedlevel/mbl/G29.cpp b/Marlin/src/gcode/bedlevel/mbl/G29.cpp index 15fbf82128..6a073f577e 100644 --- a/Marlin/src/gcode/bedlevel/mbl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/mbl/G29.cpp @@ -85,7 +85,7 @@ void GcodeSuite::G29() { mbl.reset(); mbl_probe_index = 0; if (!ui.wait_for_bl_move) { - enqueue_and_echo_commands_P(PSTR("G28\nG29 S2")); + queue.inject_P(PSTR("G28\nG29 S2")); return; } state = MeshNext; @@ -134,7 +134,7 @@ void GcodeSuite::G29() { BUZZ(100, 659); BUZZ(100, 698); - gcode.home_all_axes(); + home_all_axes(); set_bed_leveling_enabled(true); #if ENABLED(MESH_G28_REST_ORIGIN) diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index c191eeae3b..3656dc0999 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -260,13 +260,9 @@ void GcodeSuite::G28(const bool always_home_all) { #else // NOT DELTA - const bool homeX = always_home_all || parser.seen('X'), - homeY = always_home_all || parser.seen('Y'), - homeZ = always_home_all || parser.seen('Z'), - home_all = (!homeX && !homeY && !homeZ) || (homeX && homeY && homeZ), - doX = home_all || homeX, - doY = home_all || homeY, - doZ = home_all || homeZ; + const bool homeX = parser.seen('X'), homeY = parser.seen('Y'), homeZ = parser.seen('Z'), + home_all = always_home_all || (homeX == homeY && homeX == homeZ), + doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ; set_destination_from_current(); diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp index 666ddc38ff..e0f3b2958b 100644 --- a/Marlin/src/gcode/calibrate/G34_M422.cpp +++ b/Marlin/src/gcode/calibrate/G34_M422.cpp @@ -121,14 +121,11 @@ void GcodeSuite::G34() { // Users of G34 might have a badly misaligned bed, so raise Z by the // length of the deployed pin (BLTOUCH stroke < 7mm) #define Z_BASIC_CLEARANCE Z_CLEARANCE_BETWEEN_PROBES + 7.0f - #else + #else #define Z_BASIC_CLEARANCE Z_CLEARANCE_BETWEEN_PROBES #endif - // 0.05 is a 5% incline. On a 300mm bed that would be a misalignment of about 1.5cm. - // This angle is the maximum misalignment catered for - #define MAX_ANGLE 0.05f - float z_probe = Z_BASIC_CLEARANCE + MAX_ANGLE * ( + float z_probe = Z_BASIC_CLEARANCE + (G34_MAX_GRADE) * 0.01f * ( #if ENABLED(Z_TRIPLE_STEPPER_DRIVERS) SQRT(MAX(HYPOT2(z_auto_align_xpos[0] - z_auto_align_ypos[0], z_auto_align_xpos[1] - z_auto_align_ypos[1]), HYPOT2(z_auto_align_xpos[1] - z_auto_align_ypos[1], z_auto_align_xpos[2] - z_auto_align_ypos[2]), @@ -139,7 +136,7 @@ void GcodeSuite::G34() { ); // Home before the alignment procedure - gcode.G28(false); + home_all_axes(); // Move the Z coordinate realm towards the positive - dirty trick current_position[Z_AXIS] -= z_probe * 0.5; @@ -154,14 +151,17 @@ void GcodeSuite::G34() { for (iteration = 0; iteration < z_auto_align_iterations; ++iteration) { if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> probing all positions."); - SERIAL_ECHOLNPAIR(" \nITERATION: ", int(iteration + 1)); + SERIAL_ECHOLNPAIR("\nITERATION: ", int(iteration + 1)); // Initialize minimum value float z_measured_min = 100000.0f; // Probe all positions (one per Z-Stepper) - for (uint8_t zstepper = 0; zstepper < Z_STEPPER_COUNT; ++zstepper) { + for (uint8_t izstepper = 0; izstepper < Z_STEPPER_COUNT; ++izstepper) { + // iteration odd/even --> downward / upward stepper sequence + const uint8_t zstepper = (iteration & 1) ? Z_STEPPER_COUNT - 1 - izstepper : izstepper; + // Safe clearance even on an incline - do_blocking_move_to_z(z_probe); + if (iteration == 0 || izstepper > 0) do_blocking_move_to_z(z_probe); // Probe a Z height for each stepper if (isnan(probe_pt(z_auto_align_xpos[zstepper], z_auto_align_ypos[zstepper], PROBE_PT_RAISE, 0, true))) { @@ -171,8 +171,8 @@ void GcodeSuite::G34() { } // This is not the trigger Z value. It is the position of the probe after raising it. - // It is higher than the trigger value by a constant value (not known here). This value - // is more useful for determining the desired next iteration Z position for probing. It is + // It is higher than the trigger value by a constant value (not known here). This value + // is more useful for determining the desired next iteration Z position for probing. It is // equally well suited for determining the misalignment, just like the trigger position would be. z_measured[zstepper] = current_position[Z_AXIS]; if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " measured position is ", z_measured[zstepper]); @@ -185,22 +185,23 @@ void GcodeSuite::G34() { // Adapt the next probe clearance height based on the new measurements. // Safe_height = lowest distance to bed (= highest measurement) plus highest measured misalignment. - SERIAL_EOL(); #if ENABLED(Z_TRIPLE_STEPPER_DRIVERS) - z_maxdiff = MAX(ABS(z_measured[0] - z_measured[1]), ABS(z_measured[1] - z_measured[2]), ABS(z_measured[2] - z_measured[0])); + z_maxdiff = MAX(ABS(z_measured[0] - z_measured[1]), ABS(z_measured[1] - z_measured[2]), ABS(z_measured[2] - z_measured[0])); z_probe = Z_BASIC_CLEARANCE + MAX(z_measured[0], z_measured[1], z_measured[2]) + z_maxdiff; - SERIAL_ECHOLNPAIR("DIFFERENCE Z1-Z2: ", ABS(z_measured[0] - z_measured[1]), - "DIFFERENCE Z2-Z3: ", ABS(z_measured[1] - z_measured[2]), - "DIFFERENCE Z3-Z1: ", ABS(z_measured[2] - z_measured[0])); #else z_maxdiff = ABS(z_measured[0] - z_measured[1]); z_probe = Z_BASIC_CLEARANCE + MAX(z_measured[0], z_measured[1]) + z_maxdiff; - SERIAL_ECHOLNPAIR("DIFFERENCE Z1-Z2: ", ABS(z_measured[0] - z_measured[1])); #endif - SERIAL_EOL(); - // Raise to the new next probing height right away - do_blocking_move_to_z(z_probe); + SERIAL_ECHOPAIR("\n" + "DIFFERENCE Z1-Z2=", ABS(z_measured[0] - z_measured[1]) + #if ENABLED(Z_TRIPLE_STEPPER_DRIVERS) + , " Z2-Z3=", ABS(z_measured[1] - z_measured[2]) + , " Z3-Z1=", ABS(z_measured[2] - z_measured[0]) + #endif + ); + SERIAL_EOL(); + SERIAL_EOL(); // The following correction actions are to be enabled for select Z-steppers only stepper.set_separate_multi_axis(true); @@ -221,7 +222,7 @@ void GcodeSuite::G34() { err_break = true; break; } - + // Remember the alignment for the next iteration last_z_align_move[zstepper] = z_align_abs; @@ -231,7 +232,7 @@ void GcodeSuite::G34() { if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " corrected by ", z_align_move); // Lock all steppers except one - set_all_z_lock(true); + set_all_z_lock(true); switch (zstepper) { case 0: stepper.set_z_lock(false); break; case 1: stepper.set_z2_lock(false); break; @@ -245,7 +246,7 @@ void GcodeSuite::G34() { } // for (zstepper) // Back to normal stepper operations - set_all_z_lock(false); + set_all_z_lock(false); stepper.set_separate_multi_axis(false); if (err_break) break; @@ -254,10 +255,10 @@ void GcodeSuite::G34() { } // for (iteration) - if (err_break) { SERIAL_ECHOLNPGM("Aborted due to error."); break; } + if (err_break) { SERIAL_ECHOLNPGM("G34 aborted."); break; } - SERIAL_ECHOLNPAIR("Performed iterations: ", int(iteration + (iteration != z_auto_align_iterations)), " of ", int(z_auto_align_iterations)); - SERIAL_ECHOLNPAIR_F("Achieved accuracy: ", z_maxdiff); + SERIAL_ECHOLNPAIR("Did ", int(iteration + (iteration != z_auto_align_iterations)), " iterations of ", int(z_auto_align_iterations)); + SERIAL_ECHOLNPAIR_F("Accuracy: ", z_maxdiff); SERIAL_EOL(); // Restore the active tool after homing @@ -284,8 +285,8 @@ void GcodeSuite::G34() { bltouch._stow(); #endif - // Home after the alignment procedure - gcode.G28(false); + // Home Z after the alignment procedure + process_subcommands_now_P(PSTR("G28 Z")); } while(0); diff --git a/Marlin/src/gcode/calibrate/M100.cpp b/Marlin/src/gcode/calibrate/M100.cpp index eed7800976..53eb4c0ace 100644 --- a/Marlin/src/gcode/calibrate/M100.cpp +++ b/Marlin/src/gcode/calibrate/M100.cpp @@ -51,7 +51,7 @@ * Also, there are two support functions that can be called from a developer's C code. * * uint16_t check_for_free_memory_corruption(PGM_P const free_memory_start); - * void M100_dump_routine(PGM_P const title, const char *start, const char *end); + * void M100_dump_routine(PGM_P const title, char *start, char *end); * * Initial version by Roxy-3D */ @@ -63,43 +63,34 @@ #if defined(__AVR__) || IS_32BIT_TEENSY extern char __bss_end; - char* end_bss = &__bss_end; - char* free_memory_start = end_bss; - - - char* free_memory_end = 0; - char* stacklimit = 0; - char* heaplimit = 0; + char *end_bss = &__bss_end, + *free_memory_start = end_bss, *free_memory_end = 0, + *stacklimit = 0, *heaplimit = 0; #define MEMORY_END_CORRECTION 0 #elif defined(TARGET_LPC1768) - extern char __bss_end__; - extern char __StackLimit; - extern char __HeapLimit; + extern char __bss_end__, __StackLimit, __HeapLimit; - char* end_bss = &__bss_end__; - char* stacklimit = &__StackLimit; - char* heaplimit = &__HeapLimit ; + char *end_bss = &__bss_end__, + *stacklimit = &__StackLimit, + *heaplimit = &__HeapLimit ; #define MEMORY_END_CORRECTION 0x200 - char* free_memory_start = heaplimit; - char* free_memory_end = stacklimit - MEMORY_END_CORRECTION; - + char *free_memory_start = heaplimit, + *free_memory_end = stacklimit - MEMORY_END_CORRECTION; #elif defined(__SAM3X8E__) - extern char _ebss; + extern char _ebss; - char* end_bss = &_ebss; - - char* free_memory_start = end_bss; - - char* free_memory_end = 0; - char* stacklimit = 0; - char* heaplimit = 0; + char *end_bss = &_ebss, + *free_memory_start = end_bss, + *free_memory_end = 0, + *stacklimit = 0, + *heaplimit = 0; #define MEMORY_END_CORRECTION 0x10000 // need to stay well below 0x20080000 or M100 F crashes @@ -141,7 +132,7 @@ inline int32_t count_test_bytes(const char * const start_free_memory) { * the block. If so, it may indicate memory corruption due to a bad pointer. * Unexpected bytes are flagged in the right column. */ - inline void dump_free_memory(const char *start_free_memory, const char *end_free_memory) { + inline void dump_free_memory(char *start_free_memory, char *end_free_memory) { // // Start and end the dump on a nice 16 byte boundary // (even though the values are not 16-byte aligned). @@ -162,7 +153,7 @@ inline int32_t count_test_bytes(const char * const start_free_memory) { SERIAL_CHAR('|'); // Point out non test bytes for (uint8_t i = 0; i < 16; i++) { char ccc = (char)start_free_memory[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken - if (&start_free_memory[i] >= (const char*)command_queue && &start_free_memory[i] < (const char*)(command_queue + sizeof(command_queue))) { // Print out ASCII in the command buffer area + if (&start_free_memory[i] >= (char*)queue.buffer && &start_free_memory[i] < (char*)queue.buffer + sizeof(queue.buffer)) { // Print out ASCII in the command buffer area if (!WITHIN(ccc, ' ', 0x7E)) ccc = ' '; } else { // If not in the command buffer area, flag bytes that don't match the test byte @@ -177,7 +168,7 @@ inline int32_t count_test_bytes(const char * const start_free_memory) { } } - void M100_dump_routine(PGM_P const title, const char *start, const char *end) { + void M100_dump_routine(PGM_P const title, char *start, char *end) { serialprintPGM(title); SERIAL_EOL(); // @@ -198,7 +189,7 @@ inline int check_for_free_memory_corruption(PGM_P const title) { SERIAL_ECHOPAIR("\nfmc() n=", n); SERIAL_ECHOPAIR("\nfree_memory_start=", hex_address(free_memory_start)); - SERIAL_ECHOLNPAIR(" end_free_memory=", hex_address(end_free_memory)); + SERIAL_ECHOLNPAIR(" end_free_memory=", hex_address(end_free_memory)); if (end_free_memory < start_free_memory) { SERIAL_ECHOPGM(" end_free_memory < Heap "); @@ -340,11 +331,11 @@ void GcodeSuite::M100() { char *sp = top_of_stack(); if (!free_memory_end) free_memory_end = sp - MEMORY_END_CORRECTION; SERIAL_ECHOPAIR("\nbss_end : ", hex_address(end_bss)); - if (heaplimit) SERIAL_ECHOPAIR("\n__heaplimit : ", hex_address(heaplimit )); + if (heaplimit) SERIAL_ECHOPAIR("\n__heaplimit : ", hex_address(heaplimit)); SERIAL_ECHOPAIR("\nfree_memory_start : ", hex_address(free_memory_start)); if (stacklimit) SERIAL_ECHOPAIR("\n__stacklimit : ", hex_address(stacklimit)); - SERIAL_ECHOPAIR("\nfree_memory_end : ", hex_address(free_memory_end )); - if (MEMORY_END_CORRECTION) SERIAL_ECHOPAIR("\nMEMORY_END_CORRECTION: ", MEMORY_END_CORRECTION ); + SERIAL_ECHOPAIR("\nfree_memory_end : ", hex_address(free_memory_end)); + if (MEMORY_END_CORRECTION) SERIAL_ECHOPAIR("\nMEMORY_END_CORRECTION: ", MEMORY_END_CORRECTION); SERIAL_ECHOLNPAIR("\nStack Pointer : ", hex_address(sp)); // Always init on the first invocation of M100 diff --git a/Marlin/src/gcode/config/M200-M205.cpp b/Marlin/src/gcode/config/M200-M205.cpp index 511ab6cdc6..45b6afc624 100644 --- a/Marlin/src/gcode/config/M200-M205.cpp +++ b/Marlin/src/gcode/config/M200-M205.cpp @@ -61,7 +61,7 @@ void GcodeSuite::M201() { LOOP_XYZE(i) { if (parser.seen(axis_codes[i])) { - const uint8_t a = (i == E_AXIS ? E_AXIS_N(target_extruder) : i); + const uint8_t a = (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i); planner.settings.max_acceleration_mm_per_s2[a] = parser.value_axis_units((AxisEnum)a); } } @@ -81,7 +81,7 @@ void GcodeSuite::M203() { LOOP_XYZE(i) if (parser.seen(axis_codes[i])) { - const uint8_t a = (i == E_AXIS ? E_AXIS_N(target_extruder) : i); + const uint8_t a = (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i); planner.settings.max_feedrate_mm_s[a] = parser.value_axis_units((AxisEnum)a); } } diff --git a/Marlin/src/gcode/config/M43.cpp b/Marlin/src/gcode/config/M43.cpp index c46e7005be..5e229cba5f 100644 --- a/Marlin/src/gcode/config/M43.cpp +++ b/Marlin/src/gcode/config/M43.cpp @@ -114,7 +114,7 @@ inline void servo_probe_test() { ", stow angle: ", servo_angles[probe_index][1] ); - bool deploy_state, stow_state; + bool deploy_state = false, stow_state; #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) @@ -141,7 +141,7 @@ inline void servo_probe_test() { // First, check for a probe that recognizes an advanced BLTouch sequence. // In addition to STOW and DEPLOY, it uses SW MODE (and RESET in the beginning) - // to see if this is one of the following: BLTOUCH Classic 1.2, 1.3, or + // to see if this is one of the following: BLTOUCH Classic 1.2, 1.3, or // BLTouch Smart 1.0, 2.0, 2.2, 3.0, 3.1. But only if the user has actually // configured a BLTouch as being present. If the user has not configured this, // the BLTouch will be detected in the last phase of these tests (see further on). @@ -218,17 +218,18 @@ inline void servo_probe_test() { if (deploy_state != READ(PROBE_TEST_PIN)) { // probe triggered for (probe_counter = 0; probe_counter < 15 && deploy_state != READ(PROBE_TEST_PIN); ++probe_counter) safe_delay(2); + SERIAL_ECHOPGM(". Pulse width"); if (probe_counter == 15) - SERIAL_ECHOLNPGM(". Pulse width: 30ms or more"); - else - SERIAL_ECHOLNPAIR(". Pulse width (+/- 4ms): ", probe_counter * 2); - + SERIAL_ECHOLNPGM(": 30ms or more"); + else + SERIAL_ECHOLNPAIR(" (+/- 4ms): ", probe_counter * 2); + if (probe_counter >= 4) { if (probe_counter == 15) { if (blt) SERIAL_ECHOPGM("= BLTouch V3.1"); else SERIAL_ECHOPGM("= Z Servo Probe"); } - else SERIAL_ECHOPGM("= BLTouch pre V3.1 or compatible probe"); + else SERIAL_ECHOPGM("= BLTouch pre V3.1 (or compatible)"); SERIAL_ECHOLNPGM(" detected."); } else SERIAL_ECHOLNPGM("FAIL: Noise detected - please re-run test"); @@ -238,7 +239,7 @@ inline void servo_probe_test() { } } - if (!probe_counter) SERIAL_ECHOLNPGM("FAIL: Trigger not detected"); + if (!probe_counter) SERIAL_ECHOLNPGM("FAIL: No trigger detected"); #endif // HAS_Z_SERVO_PROBE diff --git a/Marlin/src/gcode/config/M540.cpp b/Marlin/src/gcode/config/M540.cpp index 5fa3020ac7..f4496e021d 100644 --- a/Marlin/src/gcode/config/M540.cpp +++ b/Marlin/src/gcode/config/M540.cpp @@ -22,7 +22,7 @@ #include "../../inc/MarlinConfig.h" -#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) +#if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) #include "../gcode.h" #include "../../module/stepper.h" @@ -37,4 +37,4 @@ void GcodeSuite::M540() { } -#endif // ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED +#endif // SD_ABORT_ON_ENDSTOP_HIT diff --git a/Marlin/src/gcode/config/M92.cpp b/Marlin/src/gcode/config/M92.cpp index 6fe3b46c0c..10eea9aedb 100644 --- a/Marlin/src/gcode/config/M92.cpp +++ b/Marlin/src/gcode/config/M92.cpp @@ -40,6 +40,8 @@ void report_M92(const bool echo=true, const int8_t e=-1) { SERIAL_ECHOPAIR(" M92 T", (int)i); SERIAL_ECHOLNPAIR(" E", VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS_N(i)])); } + #else + UNUSED(e); #endif } diff --git a/Marlin/src/gcode/control/M605.cpp b/Marlin/src/gcode/control/M605.cpp index f1f64f0ce3..f44a4c7a64 100644 --- a/Marlin/src/gcode/control/M605.cpp +++ b/Marlin/src/gcode/control/M605.cpp @@ -132,7 +132,7 @@ DEBUG_ECHOPAIR("\nX2 Home X: ", x_home_pos(1), "\nX2_MIN_POS=", int(X2_MIN_POS), "\nX2_MAX_POS=", int(X2_MAX_POS)); DEBUG_ECHOPAIR("\nX2_HOME_DIR=", int(X2_HOME_DIR), "\nX2_HOME_POS=", int(X2_HOME_POS)); DEBUG_ECHOPAIR("\nDEFAULT_DUAL_X_CARRIAGE_MODE=", STRINGIFY(DEFAULT_DUAL_X_CARRIAGE_MODE)); - DEBUG_ECHOPAIR("\nTOOLCHANGE_ZRAISE=", float(TOOLCHANGE_ZRAISE)); + DEBUG_ECHOPAIR("\toolchange_settings.z_raise=", toolchange_settings.z_raise); DEBUG_ECHOPAIR("\nDEFAULT_DUPLICATION_X_OFFSET=", int(DEFAULT_DUPLICATION_X_OFFSET)); DEBUG_EOL(); @@ -158,11 +158,12 @@ * A value of 0 disables duplication. */ void GcodeSuite::M605() { + bool ena = false; if (parser.seen("EPS")) { planner.synchronize(); if (parser.seenval('P')) duplication_e_mask = parser.value_int(); // Set the mask directly - else if (parser.seenval('E')) duplication_e_mask = pow(2, e + 1) - 1; // Set the mask by E index - const bool ena = (2 == parser.intval('S', extruder_duplication_enabled ? 2 : 0)); + else if (parser.seenval('E')) duplication_e_mask = pow(2, parser.value_int() + 1) - 1; // Set the mask by E index + ena = (2 == parser.intval('S', extruder_duplication_enabled ? 2 : 0)); extruder_duplication_enabled = ena && (duplication_e_mask >= 3); } SERIAL_ECHO_START(); diff --git a/Marlin/src/gcode/control/M7-M9.cpp b/Marlin/src/gcode/control/M7-M9.cpp new file mode 100644 index 0000000000..37221ed7e6 --- /dev/null +++ b/Marlin/src/gcode/control/M7-M9.cpp @@ -0,0 +1,63 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(COOLANT_CONTROL) + +#include "../gcode.h" +#include "../../module/planner.h" + +#if ENABLED(COOLANT_MIST) + /** + * M7: Mist Coolant On + */ + void GcodeSuite::M7() { + planner.synchronize(); // Wait for move to arrive + WRITE(COOLANT_MIST_PIN, !(COOLANT_MIST_INVERT)); // Turn on Mist coolant + } +#endif + +#if ENABLED(COOLANT_FLOOD) + /** + * M8: Flood Coolant On + */ + void GcodeSuite::M8() { + planner.synchronize(); // Wait for move to arrive + WRITE(COOLANT_FLOOD_PIN, !(COOLANT_FLOOD_INVERT)); // Turn on Flood coolant + } +#endif + +/** + * M9: Coolant OFF + */ +void GcodeSuite::M9() { + planner.synchronize(); // Wait for move to arrive + #if ENABLED(COOLANT_MIST) + WRITE(COOLANT_MIST_PIN, COOLANT_MIST_INVERT); // Turn off Mist coolant + #endif + #if ENABLED(COOLANT_FLOOD) + WRITE(COOLANT_FLOOD_PIN, COOLANT_FLOOD_INVERT); // Turn off Flood coolant + #endif +} + +#endif // COOLANT_CONTROL diff --git a/Marlin/src/gcode/control/M999.cpp b/Marlin/src/gcode/control/M999.cpp index 1d2dfae733..6f8fe06f0f 100644 --- a/Marlin/src/gcode/control/M999.cpp +++ b/Marlin/src/gcode/control/M999.cpp @@ -42,6 +42,5 @@ void GcodeSuite::M999() { if (parser.boolval('S')) return; - // gcode_LastN = Stopped_gcode_LastN; - flush_and_request_resend(); + queue.flush_and_request_resend(); } diff --git a/Marlin/src/gcode/feature/L6470/M916-918.cpp b/Marlin/src/gcode/feature/L6470/M916-918.cpp index 7744bfe0e3..abaf8abeec 100644 --- a/Marlin/src/gcode/feature/L6470/M916-918.cpp +++ b/Marlin/src/gcode/feature/L6470/M916-918.cpp @@ -106,10 +106,10 @@ void GcodeSuite::M916() { // turn the motor(s) both directions sprintf_P(gcode_string, PSTR("G0 %s%4.3f F%4.3f"), temp_axis_string, position_min, final_feedrate); - gcode.process_subcommands_now_P(gcode_string); + process_subcommands_now(gcode_string); sprintf_P(gcode_string, PSTR("G0 %s%4.3f F%4.3f"), temp_axis_string, position_max, final_feedrate); - gcode.process_subcommands_now_P(gcode_string); + process_subcommands_now(gcode_string); // get the status after the motors have stopped planner.synchronize(); @@ -226,10 +226,10 @@ void GcodeSuite::M917() { DEBUG_ECHOLNPAIR(" OCD threshold : ", (ocd_th_val + 1) * 375); sprintf_P(gcode_string, PSTR("G0 %s%4.3f F%4.3f"), temp_axis_string, position_min, final_feedrate); - gcode.process_subcommands_now_P(gcode_string); + process_subcommands_now(gcode_string); sprintf_P(gcode_string, PSTR("G0 %s%4.3f F%4.3f"), temp_axis_string, position_max, final_feedrate); - gcode.process_subcommands_now_P(gcode_string); + process_subcommands_now(gcode_string); planner.synchronize(); @@ -263,7 +263,7 @@ void GcodeSuite::M917() { L6470.set_param(axis_index[j], L6470_KVAL_HOLD, kval_hold); } DEBUG_ECHOLNPGM("."); - gcode.reset_stepper_timeout(); // reset_stepper_timeout to keep steppers powered + reset_stepper_timeout(); // reset_stepper_timeout to keep steppers powered watchdog_reset(); // beat the dog safe_delay(5000); status_composite_temp = 0; @@ -518,10 +518,10 @@ void GcodeSuite::M918() { DEBUG_ECHOLNPAIR("...feedrate = ", current_feedrate); sprintf_P(gcode_string, PSTR("G0 %s%4.3f F%4.3f"), temp_axis_string, position_min, current_feedrate); - gcode.process_subcommands_now_P(gcode_string); + process_subcommands_now(gcode_string); sprintf_P(gcode_string, PSTR("G0 %s%4.3f F%4.3f"), temp_axis_string, position_max, current_feedrate); - gcode.process_subcommands_now_P(gcode_string); + process_subcommands_now(gcode_string); planner.synchronize(); diff --git a/Marlin/src/gcode/feature/digipot/M907-M910.cpp b/Marlin/src/gcode/feature/digipot/M907-M910.cpp index 107c77f41c..541c32d054 100644 --- a/Marlin/src/gcode/feature/digipot/M907-M910.cpp +++ b/Marlin/src/gcode/feature/digipot/M907-M910.cpp @@ -85,16 +85,10 @@ void GcodeSuite::M907() { */ void GcodeSuite::M908() { #if HAS_DIGIPOTSS - stepper.digitalPotWrite( - parser.intval('P'), - parser.intval('S') - ); + stepper.digitalPotWrite(parser.intval('P'), parser.intval('S')); #endif #if ENABLED(DAC_STEPPER_CURRENT) - dac_current_raw( - parser.byteval('P', -1), - parser.ushortval('S', 0) - ); + dac_current_raw(parser.byteval('P', -1), parser.ushortval('S', 0)); #endif } diff --git a/Marlin/src/gcode/feature/pause/M600.cpp b/Marlin/src/gcode/feature/pause/M600.cpp index 147cc9c573..fe34541700 100644 --- a/Marlin/src/gcode/feature/pause/M600.cpp +++ b/Marlin/src/gcode/feature/pause/M600.cpp @@ -98,7 +98,7 @@ void GcodeSuite::M600() { #if ENABLED(HOME_BEFORE_FILAMENT_CHANGE) // Don't allow filament change without homing first - if (axis_unhomed_error()) gcode.home_all_axes(); + if (axis_unhomed_error()) home_all_axes(); #endif #if EXTRUDERS > 1 diff --git a/Marlin/src/gcode/feature/trinamic/M911-M914.cpp b/Marlin/src/gcode/feature/trinamic/M911-M914.cpp index c74428d905..d3aa9a077d 100644 --- a/Marlin/src/gcode/feature/trinamic/M911-M914.cpp +++ b/Marlin/src/gcode/feature/trinamic/M911-M914.cpp @@ -32,7 +32,7 @@ #if ENABLED(MONITOR_DRIVER_STATUS) - #define M91x_USE(ST) (AXIS_DRIVER_TYPE(ST, TMC2130) || AXIS_DRIVER_TYPE(ST, TMC2160) || AXIS_DRIVER_TYPE(ST, TMC2208) || AXIS_DRIVER_TYPE(ST, TMC2660) || AXIS_DRIVER_TYPE(ST, TMC5130) || AXIS_DRIVER_TYPE(ST, TMC5160)) + #define M91x_USE(ST) (AXIS_DRIVER_TYPE(ST, TMC2130) || AXIS_DRIVER_TYPE(ST, TMC2160) || AXIS_DRIVER_TYPE(ST, TMC2208) || AXIS_DRIVER_TYPE(ST, TMC2209) || AXIS_DRIVER_TYPE(ST, TMC2660) || AXIS_DRIVER_TYPE(ST, TMC5130) || AXIS_DRIVER_TYPE(ST, TMC5160)) #define M91x_USE_E(N) (E_STEPPERS > N && M91x_USE(E##N)) #define M91x_SOME_X (M91x_USE(X) || M91x_USE(X2)) @@ -41,7 +41,7 @@ #define M91x_SOME_E (M91x_USE_E(0) || M91x_USE_E(1) || M91x_USE_E(2) || M91x_USE_E(3) || M91x_USE_E(4) || M91x_USE_E(5)) #if !M91x_SOME_X && !M91x_SOME_Y && !M91x_SOME_Z && !M91x_SOME_E - #error "MONITOR_DRIVER_STATUS requires at least one TMC2130, TMC2208, or TMC2660." + #error "MONITOR_DRIVER_STATUS requires at least one TMC2130, 2160, 2208, 2209, 2660, 5130, or 5160." #endif /** @@ -313,39 +313,39 @@ bool report = true; const uint8_t index = parser.byteval('I'); LOOP_XYZ(i) if (parser.seen(axis_codes[i])) { - const int8_t value = (int8_t)constrain(parser.value_int(), -64, 63); + const int16_t value = parser.value_int(); report = false; switch (i) { #if X_SENSORLESS case X_AXIS: #if AXIS_HAS_STALLGUARD(X) - if (index < 2) stepperX.sgt(value); + if (index < 2) stepperX.homing_threshold(value); #endif #if AXIS_HAS_STALLGUARD(X2) - if (!(index & 1)) stepperX2.sgt(value); + if (!(index & 1)) stepperX2.homing_threshold(value); #endif break; #endif #if Y_SENSORLESS case Y_AXIS: #if AXIS_HAS_STALLGUARD(Y) - if (index < 2) stepperY.sgt(value); + if (index < 2) stepperY.homing_threshold(value); #endif #if AXIS_HAS_STALLGUARD(Y2) - if (!(index & 1)) stepperY2.sgt(value); + if (!(index & 1)) stepperY2.homing_threshold(value); #endif break; #endif #if Z_SENSORLESS case Z_AXIS: #if AXIS_HAS_STALLGUARD(Z) - if (index < 2) stepperZ.sgt(value); + if (index < 2) stepperZ.homing_threshold(value); #endif #if AXIS_HAS_STALLGUARD(Z2) - if (index == 0 || index == 2) stepperZ2.sgt(value); + if (index == 0 || index == 2) stepperZ2.homing_threshold(value); #endif #if AXIS_HAS_STALLGUARD(Z3) - if (index == 0 || index == 3) stepperZ3.sgt(value); + if (index == 0 || index == 3) stepperZ3.homing_threshold(value); #endif break; #endif diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 734468ff8e..98091f78fd 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -120,7 +120,8 @@ void GcodeSuite::get_destination_from_command() { #if ENABLED(POWER_LOSS_RECOVERY) // Only update power loss recovery on moves with E - if (seen[E_AXIS] && (seen[X_AXIS] || seen[Y_AXIS]) && IS_SD_PRINTING()) recovery.save(); + if (recovery.enabled && IS_SD_PRINTING() && seen[E_AXIS] && (seen[X_AXIS] || seen[Y_AXIS])) + recovery.save(); #endif if (parser.linearval('F') > 0) @@ -180,17 +181,13 @@ void GcodeSuite::dwell(millis_t time) { // Placeholders for non-migrated codes // #if ENABLED(M100_FREE_MEMORY_WATCHER) - extern void M100_dump_routine(PGM_P const title, const char *start, const char *end); + extern void M100_dump_routine(PGM_P const title, char *start, char *end); #endif /** * Process the parsed command and dispatch it to its handler */ -void GcodeSuite::process_parsed_command( - #if USE_EXECUTE_COMMANDS_IMMEDIATE - const bool no_ok - #endif -) { +void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { KEEPALIVE_STATE(IN_HANDLER); // Handle a known G, M, or T @@ -326,9 +323,19 @@ void GcodeSuite::process_parsed_command( #endif #if ENABLED(SPINDLE_LASER_ENABLE) - case 3: M3_M4(false); break; // M3: turn spindle/laser on, set laser/spindle power/speed, set rotation direction CW - case 4: M3_M4(true ); break; // M4: turn spindle/laser on, set laser/spindle power/speed, set rotation direction CCW - case 5: M5(); break; // M5 - turn spindle/laser off + case 3: M3_M4(false); break; // M3: Turn ON Laser | Spindle (clockwise), set Power | Speed + case 4: M3_M4(true ); break; // M4: Turn ON Laser | Spindle (counter-clockwise), set Power | Speed + case 5: M5(); break; // M5: Turn OFF Laser | Spindle + #endif + + #if ENABLED(COOLANT_CONTROL) + #if ENABLED(COOLANT_MIST) + case 7: M7(); break; // M7: Mist coolant ON + #endif + #if ENABLED(COOLANT_FLOOD) + case 8: M8(); break; // M8: Flood coolant ON + #endif + case 9: M9(); break; // M9: Coolant OFF #endif #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) @@ -338,9 +345,9 @@ void GcodeSuite::process_parsed_command( case 17: M17(); break; // M17: Enable all stepper motors #if ENABLED(SDSUPPORT) - case 20: M20(); break; // M20: list SD card - case 21: M21(); break; // M21: init SD card - case 22: M22(); break; // M22: release SD card + case 20: M20(); break; // M20: List SD card + case 21: M21(); break; // M21: Init SD card + case 22: M22(); break; // M22: Release SD card case 23: M23(); break; // M23: Select file case 24: M24(); break; // M24: Start SD print case 25: M25(); break; // M25: Pause SD print @@ -658,7 +665,7 @@ void GcodeSuite::process_parsed_command( case 524: M524(); break; // M524: Abort the current SD print job #endif - #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + #if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) case 540: M540(); break; // M540: Set abort on endstop hit for SD printing #endif @@ -791,10 +798,7 @@ void GcodeSuite::process_parsed_command( KEEPALIVE_STATE(NOT_BUSY); - #if USE_EXECUTE_COMMANDS_IMMEDIATE - if (!no_ok) - #endif - ok_to_send(); + if (!no_ok) queue.ok_to_send(); } /** @@ -802,16 +806,16 @@ void GcodeSuite::process_parsed_command( * This is called from the main loop() */ void GcodeSuite::process_next_command() { - char * const current_command = command_queue[cmd_queue_index_r]; + char * const current_command = queue.buffer[queue.index_r]; - PORT_REDIRECT(command_queue_port[cmd_queue_index_r]); + PORT_REDIRECT(queue.port[queue.index_r]); if (DEBUGGING(ECHO)) { SERIAL_ECHO_START(); SERIAL_ECHOLN(current_command); #if ENABLED(M100_FREE_MEMORY_DUMPER) - SERIAL_ECHOPAIR("slot:", cmd_queue_index_r); - M100_dump_routine(PSTR(" Command Queue:"), (const char*)command_queue, (const char*)(command_queue) + sizeof(command_queue)); + SERIAL_ECHOPAIR("slot:", queue.index_r); + M100_dump_routine(PSTR(" Command Queue:"), queue.buffer, queue.buffer + sizeof(queue.buffer)); #endif } @@ -820,43 +824,39 @@ void GcodeSuite::process_next_command() { process_parsed_command(); } -#if USE_EXECUTE_COMMANDS_IMMEDIATE +/** + * Run a series of commands, bypassing the command queue to allow + * G-code "macros" to be called from within other G-code handlers. + */ - /** - * Run a series of commands, bypassing the command queue to allow - * G-code "macros" to be called from within other G-code handlers. - */ - - void GcodeSuite::process_subcommands_now_P(PGM_P pgcode) { - char * const saved_cmd = parser.command_ptr; // Save the parser state - for (;;) { - PGM_P const delim = strchr_P(pgcode, '\n'); // Get address of next newline - const size_t len = delim ? delim - pgcode : strlen_P(pgcode); // Get the command length - char cmd[len + 1]; // Allocate a stack buffer - strncpy_P(cmd, pgcode, len); // Copy the command to the stack - cmd[len] = '\0'; // End with a nul - parser.parse(cmd); // Parse the command - process_parsed_command(true); // Process it - if (!delim) break; // Last command? - pgcode = delim + 1; // Get the next command - } - parser.parse(saved_cmd); // Restore the parser state +void GcodeSuite::process_subcommands_now_P(PGM_P pgcode) { + char * const saved_cmd = parser.command_ptr; // Save the parser state + for (;;) { + PGM_P const delim = strchr_P(pgcode, '\n'); // Get address of next newline + const size_t len = delim ? delim - pgcode : strlen_P(pgcode); // Get the command length + char cmd[len + 1]; // Allocate a stack buffer + strncpy_P(cmd, pgcode, len); // Copy the command to the stack + cmd[len] = '\0'; // End with a nul + parser.parse(cmd); // Parse the command + process_parsed_command(true); // Process it + if (!delim) break; // Last command? + pgcode = delim + 1; // Get the next command } + parser.parse(saved_cmd); // Restore the parser state +} - void GcodeSuite::process_subcommands_now(char * gcode) { - char * const saved_cmd = parser.command_ptr; // Save the parser state - for (;;) { - char * const delim = strchr(gcode, '\n'); // Get address of next newline - if (delim) *delim = '\0'; // Replace with nul - parser.parse(gcode); // Parse the current command - process_parsed_command(true); // Process it - if (!delim) break; // Last command? - gcode = delim + 1; // Get the next command - } - parser.parse(saved_cmd); // Restore the parser state +void GcodeSuite::process_subcommands_now(char * gcode) { + char * const saved_cmd = parser.command_ptr; // Save the parser state + for (;;) { + char * const delim = strchr(gcode, '\n'); // Get address of next newline + if (delim) *delim = '\0'; // Replace with nul + parser.parse(gcode); // Parse the current command + process_parsed_command(true); // Process it + if (!delim) break; // Last command? + gcode = delim + 1; // Get the next command } - -#endif // USE_EXECUTE_COMMANDS_IMMEDIATE + parser.parse(saved_cmd); // Restore the parser state +} #if ENABLED(HOST_KEEPALIVE_FEATURE) diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 6037804693..d5656c7a43 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -30,11 +30,11 @@ * ----------------- * * Helpful G-code references: - * - http://linuxcnc.org/handbook/gcode/g-code.html - * - http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes + * - http://marlinfw.org/meta/gcode + * - https://reprap.org/wiki/G-code + * - http://linuxcnc.org/docs/html/gcode.html * * Help to document Marlin's G-codes online: - * - http://reprap.org/wiki/G-code * - https://github.com/MarlinFirmware/MarlinDocumentation * * ----------------- @@ -75,9 +75,12 @@ * * M0 - Unconditional stop - Wait for user to press a button on the LCD (Only if ULTRA_LCD is enabled) * M1 -> M0 - * M3 - Turn laser/spindle on, set spindle/laser speed/power, set rotation to clockwise - * M4 - Turn laser/spindle on, set spindle/laser speed/power, set rotation to counter-clockwise - * M5 - Turn laser/spindle off + * M3 - Turn ON Laser | Spindle (clockwise), set Power | Speed. (Requires SPINDLE_LASER_ENABLE) + * M4 - Turn ON Laser | Spindle (counter-clockwise), set Power | Speed. (Requires SPINDLE_LASER_ENABLE) + * M5 - Turn OFF Laser | Spindle. (Requires SPINDLE_LASER_ENABLE) + * M7 - Turn mist coolant ON. (Requires COOLANT_CONTROL) + * M8 - Turn flood coolant ON. (Requires COOLANT_CONTROL) + * M9 - Turn coolant OFF. (Requires COOLANT_CONTROL) * M12 - Set up closed loop control system. (Requires EXTERNAL_CLOSED_LOOP_CONTROLLER) * M17 - Enable/Power all stepper motors * M18 - Disable all stepper motors; same as M84 @@ -136,7 +139,7 @@ * M119 - Report endstops status. * M120 - Enable endstops detection. * M121 - Disable endstops detection. - * M122 - Debug stepper (Requires at least one _DRIVER_TYPE defined as TMC2130/TMC2208/TMC2660 or L6470) + * M122 - Debug stepper (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660 or L6470) * M125 - Save current position and move to filament change position. (Requires PARK_HEAD_ON_PAUSE) * M126 - Solenoid Air Valve Open. (Requires BARICUDA) * M127 - Solenoid Air Valve Closed. (Requires BARICUDA) @@ -213,9 +216,9 @@ * M502 - Revert to the default "factory settings". ** Does not write them to EEPROM! ** * M503 - Print the current settings (in memory): "M503 S". S0 specifies compact output. * M504 - Validate EEPROM contents. (Requires EEPROM_SETTINGS) - * M524 - Abort the current SD print job (started with M24) - * M540 - Enable/disable SD card abort on endstop hit: "M540 S". (Requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) - * M569 - Enable stealthChop on an axis. (Requires at least one _DRIVER_TYPE to be TMC2130 or TMC2208) + * M524 - Abort the current SD print job started with M24. (Requires SDSUPPORT) + * M540 - Enable/disable SD card abort on endstop hit: "M540 S". (Requires SD_ABORT_ON_ENDSTOP_HIT) + * M569 - Enable stealthChop on an axis. (Requires at least one _DRIVER_TYPE to be TMC2130/2160/2208/2209/5130/5160) * M600 - Pause for filament change: "M600 X Y Z E L". (Requires ADVANCED_PAUSE_FEATURE) * M603 - Configure filament change: "M603 T U L". (Requires ADVANCED_PAUSE_FEATURE) * M605 - Set Dual X-Carriage movement mode: "M605 S [X] [R]". (Requires DUAL_X_CARRIAGE) @@ -238,13 +241,13 @@ * M869 - Report position encoder module error. * M876 - Handle Prompt Response. (Requires HOST_PROMPT_SUPPORT and not EMERGENCY_PARSER) * M900 - Get or Set Linear Advance K-factor. (Requires LIN_ADVANCE) - * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. (Requires at least one _DRIVER_TYPE defined as TMC2130/TMC2208/TMC2660 or L6470) + * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660 or L6470) * M907 - Set digital trimpot motor current using axis codes. (Requires a board with digital trimpots) * M908 - Control digital trimpot directly. (Requires DAC_STEPPER_CURRENT or DIGIPOTSS_PIN) * M909 - Print digipot/DAC current value. (Requires DAC_STEPPER_CURRENT) * M910 - Commit digipot/DAC value to external EEPROM via I2C. (Requires DAC_STEPPER_CURRENT) - * M911 - Report stepper driver overtemperature pre-warn condition. (Requires at least one _DRIVER_TYPE defined as TMC2130/TMC2208/TMC2660) - * M912 - Clear stepper driver overtemperature pre-warn condition flag. (Requires at least one _DRIVER_TYPE defined as TMC2130/TMC2208/TMC2660) + * M911 - Report stepper driver overtemperature pre-warn condition. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660) + * M912 - Clear stepper driver overtemperature pre-warn condition flag. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660) * M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD) * M914 - Set StallGuard sensitivity. (Requires SENSORLESS_HOMING or SENSORLESS_PROBING) * M916 - L6470 tuning: Increase KVAL_HOLD until thermal warning. (Requires at least one _DRIVER_TYPE L6470) @@ -309,19 +312,14 @@ public: static int8_t get_target_e_stepper_from_command(); static void get_destination_from_command(); - static void process_parsed_command( - #if USE_EXECUTE_COMMANDS_IMMEDIATE - const bool no_ok = false - #endif - ); + static void process_parsed_command(const bool no_ok=false); static void process_next_command(); - #if USE_EXECUTE_COMMANDS_IMMEDIATE - static void process_subcommands_now_P(PGM_P pgcode); - static void process_subcommands_now(char * gcode); - #endif + // Execute G-code in-place, preserving current G-code parameters + static void process_subcommands_now_P(PGM_P pgcode); + static void process_subcommands_now(char * gcode); - FORCE_INLINE static void home_all_axes() { G28(true); } + static inline void home_all_axes() { process_subcommands_now_P(PSTR("G28")); } #if ENABLED(HOST_KEEPALIVE_FEATURE) /** @@ -460,6 +458,16 @@ private: static void M5(); #endif + #if ENABLED(COOLANT_CONTROL) + #if ENABLED(COOLANT_MIST) + static void M7(); + #endif + #if ENABLED(COOLANT_FLOOD) + static void M8(); + #endif + static void M9(); + #endif + #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) static void M12(); #endif @@ -769,7 +777,7 @@ private: static void M524(); #endif - #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + #if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) static void M540(); #endif diff --git a/Marlin/src/gcode/host/M110.cpp b/Marlin/src/gcode/host/M110.cpp index 108f414d2b..33e6e67900 100644 --- a/Marlin/src/gcode/host/M110.cpp +++ b/Marlin/src/gcode/host/M110.cpp @@ -21,11 +21,11 @@ */ #include "../gcode.h" -#include "../queue.h" // for gcode_LastN +#include "../queue.h" // for last_N /** * M110: Set Current Line Number */ void GcodeSuite::M110() { - if (parser.seenval('N')) gcode_LastN = parser.value_long(); + if (parser.seenval('N')) queue.last_N = parser.value_long(); } diff --git a/Marlin/src/gcode/motion/M290.cpp b/Marlin/src/gcode/motion/M290.cpp index 4dd1fc4475..012cefaa4f 100644 --- a/Marlin/src/gcode/motion/M290.cpp +++ b/Marlin/src/gcode/motion/M290.cpp @@ -59,6 +59,14 @@ /** * M290: Babystepping + * + * X - Distance to step X + * Y - Distance to step Y + * Z - Distance to step Z + * S - Distance to step Z (alias for Z) + * + * With BABYSTEP_ZPROBE_OFFSET: + * P0 - Don't adjust the Z probe offset. */ void GcodeSuite::M290() { #if ENABLED(BABYSTEP_XY) diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp index 2acf06a172..4d01560ea7 100644 --- a/Marlin/src/gcode/parser.cpp +++ b/Marlin/src/gcode/parser.cpp @@ -42,7 +42,7 @@ bool GCodeParser::volumetric_enabled; #endif #if ENABLED(TEMPERATURE_UNITS_SUPPORT) - TempUnit GCodeParser::input_temp_units; + TempUnit GCodeParser::input_temp_units = TEMPUNIT_C; #endif char *GCodeParser::command_ptr, diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index d8bd91c5f3..7dbe3259e1 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -25,6 +25,8 @@ */ #include "queue.h" +GCodeQueue queue; + #include "gcode.h" #include "../lcd/ultralcd.h" @@ -42,7 +44,7 @@ * sending commands to Marlin, and lines will be checked for sequentiality. * M110 N sets the current line number. */ -long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0; +long gcode_N, GCodeQueue::last_N, GCodeQueue::stopped_N = 0; /** * GCode Command Queue @@ -53,17 +55,17 @@ long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0; * the main loop. The gcode.process_next_command method parses the next * command and hands off execution to individual handler functions. */ -uint8_t commands_in_queue = 0, // Count of commands in the queue - cmd_queue_index_r = 0, // Ring buffer read position - cmd_queue_index_w = 0; // Ring buffer write position +uint8_t GCodeQueue::length = 0, // Count of commands in the queue + GCodeQueue::index_r = 0, // Ring buffer read position + GCodeQueue::index_w = 0; // Ring buffer write position -char command_queue[BUFSIZE][MAX_CMD_SIZE]; +char GCodeQueue::buffer[BUFSIZE][MAX_CMD_SIZE]; /* * The port that the command was received on */ #if NUM_SERIAL > 1 - int16_t command_queue_port[BUFSIZE]; + int16_t GCodeQueue::port[BUFSIZE]; #endif /** @@ -82,7 +84,7 @@ bool send_ok[BUFSIZE]; */ static PGM_P injected_commands_P = nullptr; -void queue_setup() { +GCodeQueue::GCodeQueue() { // Send "ok" after commands by default for (uint8_t i = 0; i < COUNT(send_ok); i++) send_ok[i] = true; } @@ -90,24 +92,24 @@ void queue_setup() { /** * Clear the Marlin command queue */ -void clear_command_queue() { - cmd_queue_index_r = cmd_queue_index_w = commands_in_queue = 0; +void GCodeQueue::clear() { + index_r = index_w = length = 0; } /** * Once a new command is in the ring buffer, call this to commit it */ -inline void _commit_command(bool say_ok +void GCodeQueue::_commit_command(bool say_ok #if NUM_SERIAL > 1 - , int16_t port = -1 + , int16_t p/*=-1*/ #endif ) { - send_ok[cmd_queue_index_w] = say_ok; + send_ok[index_w] = say_ok; #if NUM_SERIAL > 1 - command_queue_port[cmd_queue_index_w] = port; + port[index_w] = p; #endif - if (++cmd_queue_index_w >= BUFSIZE) cmd_queue_index_w = 0; - commands_in_queue++; + if (++index_w >= BUFSIZE) index_w = 0; + length++; } /** @@ -115,16 +117,16 @@ inline void _commit_command(bool say_ok * Return true if the command was successfully added. * Return false for a full buffer, or if the 'command' is a comment. */ -inline bool _enqueuecommand(const char* cmd, bool say_ok=false +bool GCodeQueue::_enqueue(const char* cmd, bool say_ok/*=false*/ #if NUM_SERIAL > 1 - , int16_t port = -1 + , int16_t pn/*=-1*/ #endif ) { - if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false; - strcpy(command_queue[cmd_queue_index_w], cmd); + if (*cmd == ';' || length >= BUFSIZE) return false; + strcpy(buffer[index_w], cmd); _commit_command(say_ok #if NUM_SERIAL > 1 - , port + , pn #endif ); return true; @@ -132,19 +134,17 @@ inline bool _enqueuecommand(const char* cmd, bool say_ok=false /** * Enqueue with Serial Echo + * Return true if the command was consumed */ -bool enqueue_and_echo_command(const char* cmd) { +bool GCodeQueue::enqueue_one(const char* cmd) { - //SERIAL_ECHOPGM("enqueue_and_echo_command(\""); + //SERIAL_ECHOPGM("enqueue_one(\""); //SERIAL_ECHO(cmd); //SERIAL_ECHOPGM("\") \n"); - if (*cmd == 0 || *cmd == '\n' || *cmd == '\r') { - //SERIAL_ECHOLNPGM("Null command found... Did not queue!"); - return true; - } + if (*cmd == 0 || *cmd == '\n' || *cmd == '\r') return true; - if (_enqueuecommand(cmd)) { + if (_enqueue(cmd)) { SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(MSG_ENQUEUEING, cmd, "\""); return true; @@ -153,52 +153,66 @@ bool enqueue_and_echo_command(const char* cmd) { } /** - * Inject the next "immediate" command, when possible, onto the front of the queue. - * Return true if any immediate commands remain to inject. + * Process the next "immediate" command. */ -static bool drain_injected_commands_P() { - if (injected_commands_P != nullptr) { - size_t i = 0; - char c, cmd[60]; - strncpy_P(cmd, injected_commands_P, sizeof(cmd) - 1); - cmd[sizeof(cmd) - 1] = '\0'; - while ((c = cmd[i]) && c != '\n') i++; // find the end of this gcode command - cmd[i] = '\0'; - if (enqueue_and_echo_command(cmd)) // success? - injected_commands_P = c ? injected_commands_P + i + 1 : nullptr; // next command or done - } - return (injected_commands_P != nullptr); // return whether any more remain +bool GCodeQueue::process_injected_command() { + if (injected_commands_P == nullptr) return false; + + char c; + size_t i = 0; + while ((c = pgm_read_byte(&injected_commands_P[i])) && c != '\n') i++; + if (!i) return false; + + char cmd[i + 1]; + memcpy_P(cmd, injected_commands_P, i); + cmd[i] = '\0'; + + injected_commands_P = c ? injected_commands_P + i + 1 : nullptr; + + parser.parse(cmd); + PORT_REDIRECT(SERIAL_PORT); + gcode.process_parsed_command(); + PORT_RESTORE(); + + return true; } /** - * Record one or many commands to run from program memory. + * Enqueue one or many commands to run from program memory. + * Do not inject a comment or use leading spaces! * Aborts the current queue, if any. - * Note: drain_injected_commands_P() must be called repeatedly to drain the commands afterwards + * Note: process_injected_command() will be called to drain any commands afterwards */ -void enqueue_and_echo_commands_P(PGM_P const pgcode) { +void GCodeQueue::inject_P(PGM_P const pgcode) { injected_commands_P = pgcode; - (void)drain_injected_commands_P(); // first command executed asap (when possible) } -#if HAS_QUEUE_NOW - /** - * Enqueue and return only when commands are actually enqueued. - * Never call this from a G-code handler! - */ - void enqueue_and_echo_command_now(const char* cmd) { - while (!enqueue_and_echo_command(cmd)) idle(); +/** + * Enqueue and return only when commands are actually enqueued. + * Never call this from a G-code handler! + */ +void GCodeQueue::enqueue_one_now(const char* cmd) { + while (!enqueue_one(cmd)) idle(); +} + +/** + * Enqueue from program memory and return only when commands are actually enqueued + * Never call this from a G-code handler! + */ +void GCodeQueue::enqueue_now_P(PGM_P const pgcode) { + size_t i = 0; + PGM_P p = pgcode; + for (;;) { + char c; + while ((c = p[i]) && c != '\n') i++; + char cmd[i + 1]; + memcpy_P(cmd, p, i); + cmd[i] = '\0'; + enqueue_one_now(cmd); + if (!c) break; + p += i + 1; } - #if HAS_LCD_QUEUE_NOW - /** - * Enqueue from program memory and return only when commands are actually enqueued - * Never call this from a G-code handler! - */ - void enqueue_and_echo_commands_now_P(PGM_P const pgcode) { - enqueue_and_echo_commands_P(pgcode); - while (drain_injected_commands_P()) idle(); - } - #endif -#endif +} /** * Send an "ok" message to the host, indicating @@ -209,16 +223,16 @@ void enqueue_and_echo_commands_P(PGM_P const pgcode) { * P Planner space remaining * B Block queue space remaining */ -void ok_to_send() { +void GCodeQueue::ok_to_send() { #if NUM_SERIAL > 1 - const int16_t port = command_queue_port[cmd_queue_index_r]; - if (port < 0) return; - PORT_REDIRECT(port); + const int16_t pn = port[index_r]; + if (pn < 0) return; + PORT_REDIRECT(pn); #endif - if (!send_ok[cmd_queue_index_r]) return; + if (!send_ok[index_r]) return; SERIAL_ECHOPGM(MSG_OK); #if ENABLED(ADVANCED_OK) - char* p = command_queue[cmd_queue_index_r]; + char* p = buffer[index_r]; if (*p == 'N') { SERIAL_ECHO(' '); SERIAL_ECHO(*p++); @@ -226,7 +240,7 @@ void ok_to_send() { SERIAL_ECHO(*p++); } SERIAL_ECHOPGM(" P"); SERIAL_ECHO(int(BLOCK_BUFFER_SIZE - planner.movesplanned() - 1)); - SERIAL_ECHOPGM(" B"); SERIAL_ECHO(BUFSIZE - commands_in_queue); + SERIAL_ECHOPGM(" B"); SERIAL_ECHO(BUFSIZE - length); #endif SERIAL_EOL(); } @@ -235,15 +249,15 @@ void ok_to_send() { * Send a "Resend: nnn" message to the host to * indicate that a command needs to be re-sent. */ -void flush_and_request_resend() { +void GCodeQueue::flush_and_request_resend() { #if NUM_SERIAL > 1 - const int16_t port = command_queue_port[cmd_queue_index_r]; - if (port < 0) return; - PORT_REDIRECT(port); + const int16_t p = port[index_r]; + if (p < 0) return; + PORT_REDIRECT(p); #endif SERIAL_FLUSH(); SERIAL_ECHOPGM(MSG_RESEND); - SERIAL_ECHOLN(gcode_LastN + 1); + SERIAL_ECHOLN(last_N + 1); ok_to_send(); } @@ -266,16 +280,6 @@ inline int read_serial(const uint8_t index) { } } -void gcode_line_error(PGM_P const err, const int8_t port) { - PORT_REDIRECT(port); - SERIAL_ERROR_START(); - serialprintPGM(err); - SERIAL_ECHOLN(gcode_LastN); - while (read_serial(port) != -1); // clear out the RX buffer - flush_and_request_resend(); - serial_count[port] = 0; -} - #if ENABLED(BINARY_FILE_TRANSFER) inline bool serial_data_available(const uint8_t index) { @@ -526,6 +530,16 @@ void gcode_line_error(PGM_P const err, const int8_t port) { #endif // BINARY_FILE_TRANSFER +void GCodeQueue::gcode_line_error(PGM_P const err, const int8_t port) { + PORT_REDIRECT(port); + SERIAL_ERROR_START(); + serialprintPGM(err); + SERIAL_ECHOLN(last_N); + while (read_serial(port) != -1); // clear out the RX buffer + flush_and_request_resend(); + serial_count[port] = 0; +} + FORCE_INLINE bool is_M29(const char * const cmd) { // matches "M29" & "M29 ", but not "M290", etc const char * const m29 = strstr_P(cmd, PSTR("M29")); return m29 && !NUMERIC(m29[3]); @@ -536,7 +550,7 @@ FORCE_INLINE bool is_M29(const char * const cmd) { // matches "M29" & "M29 ", b * Exit when the buffer is full or when no more characters are * left on the serial port. */ -inline void get_serial_commands() { +void GCodeQueue::get_serial_commands() { static char serial_line_buffer[NUM_SERIAL][MAX_CMD_SIZE]; static bool serial_comment_mode[NUM_SERIAL] = { false } #if ENABLED(PAREN_COMMENTS) @@ -561,7 +575,7 @@ inline void get_serial_commands() { #if NO_TIMEOUTS > 0 static millis_t last_command_time = 0; const millis_t ms = millis(); - if (commands_in_queue == 0 && !serial_data_available() && ELAPSED(ms, last_command_time + NO_TIMEOUTS)) { + if (length == 0 && !serial_data_available() && ELAPSED(ms, last_command_time + NO_TIMEOUTS)) { SERIAL_ECHOLNPGM(MSG_WAIT); last_command_time = ms; } @@ -570,7 +584,7 @@ inline void get_serial_commands() { /** * Loop while serial characters are incoming and the queue is not full */ - while (commands_in_queue < BUFSIZE && serial_data_available()) { + while (length < BUFSIZE && serial_data_available()) { for (uint8_t i = 0; i < NUM_SERIAL; ++i) { int c; if ((c = read_serial(i)) < 0) continue; @@ -610,7 +624,7 @@ inline void get_serial_commands() { gcode_N = strtol(npos + 1, nullptr, 10); - if (gcode_N != gcode_LastN + 1 && !M110) + if (gcode_N != last_N + 1 && !M110) return gcode_line_error(PSTR(MSG_ERR_LINE_NO), i); char *apos = strrchr(command, '*'); @@ -623,7 +637,7 @@ inline void get_serial_commands() { else return gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM), i); - gcode_LastN = gcode_N; + last_N = gcode_N; } #if ENABLED(SDSUPPORT) // Pronterface "M29" and "M29 " has no line number @@ -669,7 +683,7 @@ inline void get_serial_commands() { #endif // Add the command to the queue - _enqueuecommand(serial_line_buffer[i], true + _enqueue(serial_line_buffer[i], true #if NUM_SERIAL > 1 , i #endif @@ -711,7 +725,7 @@ inline void get_serial_commands() { * or until the end of the file is reached. The special character '#' * can also interrupt buffering. */ - inline void get_sdcard_commands() { + inline void GCodeQueue::get_sdcard_commands() { static bool stop_buffering = false, sd_comment_mode = false #if ENABLED(PAREN_COMMENTS) @@ -728,11 +742,11 @@ inline void get_serial_commands() { * due to checksums, however, no checksums are used in SD printing. */ - if (commands_in_queue == 0) stop_buffering = false; + if (length == 0) stop_buffering = false; uint16_t sd_count = 0; bool card_eof = card.eof(); - while (commands_in_queue < BUFSIZE && !card_eof && !stop_buffering) { + while (length < BUFSIZE && !card_eof && !stop_buffering) { const int16_t n = card.get(); char sd_char = (char)n; card_eof = card.eof(); @@ -755,7 +769,7 @@ inline void get_serial_commands() { #if ENABLED(PRINTER_EVENT_LEDS) printerEventLEDs.onPrintCompleted(); #if HAS_RESUME_CONTINUE - enqueue_and_echo_commands_P(PSTR("M0 S" + inject_P(PSTR("M0 S" #if HAS_LCD_MENU "1800" #else @@ -779,7 +793,7 @@ inline void get_serial_commands() { // Skip empty lines and comments if (!sd_count) { thermalManager.manage_heater(); continue; } - command_queue[cmd_queue_index_w][sd_count] = '\0'; // terminate string + buffer[index_w][sd_count] = '\0'; // terminate string sd_count = 0; // clear sd line buffer _commit_command(false); @@ -800,7 +814,7 @@ inline void get_serial_commands() { #if ENABLED(PAREN_COMMENTS) && ! sd_comment_paren_mode #endif - ) command_queue[cmd_queue_index_w][sd_count++] = sd_char; + ) buffer[index_w][sd_count++] = sd_char; } } } @@ -813,10 +827,7 @@ inline void get_serial_commands() { * - The active serial input (usually USB) * - The SD card file being actively printed */ -void get_available_commands() { - - // if any immediate commands remain, don't get other commands yet - if (drain_injected_commands_P()) return; +void GCodeQueue::get_available_commands() { get_serial_commands(); @@ -828,14 +839,18 @@ void get_available_commands() { /** * Get the next command in the queue, optionally log it to SD, then dispatch it */ -void advance_command_queue() { +void GCodeQueue::advance() { - if (!commands_in_queue) return; + // Process immediate commands + if (process_injected_command()) return; + + // Return if the G-code buffer is empty + if (!length) return; #if ENABLED(SDSUPPORT) if (card.flag.saving) { - char* command = command_queue[cmd_queue_index_r]; + char* command = buffer[index_r]; if (is_M29(command)) { // M29 closes the file card.closefile(); @@ -872,9 +887,9 @@ void advance_command_queue() { #endif // SDSUPPORT // The queue may be reset by a command handler or by code invoked by idle() within a handler - if (commands_in_queue) { - --commands_in_queue; - if (++cmd_queue_index_r >= BUFSIZE) cmd_queue_index_r = 0; + if (length) { + --length; + if (++index_r >= BUFSIZE) index_r = 0; } } diff --git a/Marlin/src/gcode/queue.h b/Marlin/src/gcode/queue.h index ac519bc77b..49c01f0431 100644 --- a/Marlin/src/gcode/queue.h +++ b/Marlin/src/gcode/queue.h @@ -28,98 +28,125 @@ #include "../inc/MarlinConfig.h" -/** - * GCode line number handling. Hosts may include line numbers when sending - * commands to Marlin, and lines will be checked for sequentiality. - * M110 N sets the current line number. - */ -extern long gcode_LastN, Stopped_gcode_LastN; +class GCodeQueue { +public: + /** + * GCode line number handling. Hosts may include line numbers when sending + * commands to Marlin, and lines will be checked for sequentiality. + * M110 N sets the current line number. + */ + static long last_N, stopped_N; -/** - * GCode Command Queue - * A simple ring buffer of BUFSIZE command strings. - * - * Commands are copied into this buffer by the command injectors - * (immediate, serial, sd card) and they are processed sequentially by - * the main loop. The gcode.process_next_command method parses the next - * command and hands off execution to individual handler functions. - */ -extern uint8_t commands_in_queue, // Count of commands in the queue - cmd_queue_index_r; // Ring buffer read position + static inline void stop() { stopped_N = last_N; } -extern char command_queue[BUFSIZE][MAX_CMD_SIZE]; + /** + * GCode Command Queue + * A simple ring buffer of BUFSIZE command strings. + * + * Commands are copied into this buffer by the command injectors + * (immediate, serial, sd card) and they are processed sequentially by + * the main loop. The gcode.process_next_command method parses the next + * command and hands off execution to individual handler functions. + */ + static uint8_t length, // Count of commands in the queue + index_r; // Ring buffer read position -/* - * The port that the command was received on - */ -#if NUM_SERIAL > 1 - extern int16_t command_queue_port[BUFSIZE]; -#endif + static char buffer[BUFSIZE][MAX_CMD_SIZE]; -/** - * Initialization of queue for setup() - */ -void queue_setup(); + /* + * The port that the command was received on + */ + #if NUM_SERIAL > 1 + static int16_t port[BUFSIZE]; + #endif -/** - * Clear the Marlin command queue - */ -void clear_command_queue(); + GCodeQueue(); -/** - * Clear the serial line and request a resend of - * the next expected line number. - */ -void flush_and_request_resend(); + /** + * Clear the Marlin command queue + */ + static void clear(); -/** - * Send an "ok" message to the host, indicating - * that a command was successfully processed. - * - * If ADVANCED_OK is enabled also include: - * N Line number of the command, if any - * P Planner space remaining - * B Block queue space remaining - */ -void ok_to_send(); + /** + * Enqueue one or many commands to run from program memory. + * Aborts the current queue, if any. + * Note: process_injected_command() will process them. + */ + static void inject_P(PGM_P const pgcode); -/** - * Record one or many commands to run from program memory. - * Aborts the current queue, if any. - * Note: drain_injected_commands_P() must be called repeatedly to drain the commands afterwards - */ -void enqueue_and_echo_commands_P(PGM_P const pgcode); - -/** - * Enqueue with Serial Echo - */ -bool enqueue_and_echo_command(const char* cmd); - -#define HAS_LCD_QUEUE_NOW (ENABLED(MALYAN_LCD) || (HAS_LCD_MENU && ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE))) -#define HAS_QUEUE_NOW (ENABLED(SDSUPPORT) || HAS_LCD_QUEUE_NOW) - -#if HAS_QUEUE_NOW /** * Enqueue and return only when commands are actually enqueued */ - void enqueue_and_echo_command_now(const char* cmd); - #if HAS_LCD_QUEUE_NOW - /** - * Enqueue from program memory and return only when commands are actually enqueued - */ - void enqueue_and_echo_commands_now_P(PGM_P const cmd); + static void enqueue_one_now(const char* cmd); + + /** + * Enqueue from program memory and return only when commands are actually enqueued + */ + static void enqueue_now_P(PGM_P const cmd); + + /** + * Get the next command in the queue, optionally log it to SD, then dispatch it + */ + static void advance(); + + /** + * Add to the circular command queue the next command from: + * - The command-injection queue (injected_commands_P) + * - The active serial input (usually USB) + * - The SD card file being actively printed + */ + static void get_available_commands(); + + /** + * Send an "ok" message to the host, indicating + * that a command was successfully processed. + * + * If ADVANCED_OK is enabled also include: + * N Line number of the command, if any + * P Planner space remaining + * B Block queue space remaining + */ + static void ok_to_send(); + + /** + * Clear the serial line and request a resend of + * the next expected line number. + */ + static void flush_and_request_resend(); + +private: + + static uint8_t index_w; // Ring buffer write position + + static void get_serial_commands(); + + #if ENABLED(SDSUPPORT) + static void get_sdcard_commands(); #endif -#endif -/** - * Add to the circular command queue the next command from: - * - The command-injection queue (injected_commands_P) - * - The active serial input (usually USB) - * - The SD card file being actively printed - */ -void get_available_commands(); + static void _commit_command(bool say_ok + #if NUM_SERIAL > 1 + , int16_t p=-1 + #endif + ); -/** - * Get the next command in the queue, optionally log it to SD, then dispatch it - */ -void advance_command_queue(); + static bool _enqueue(const char* cmd, bool say_ok=false + #if NUM_SERIAL > 1 + , int16_t p=-1 + #endif + ); + + // Process the next "immediate" command + static bool process_injected_command(); + + /** + * Enqueue with Serial Echo + * Return true on success + */ + static bool enqueue_one(const char* cmd); + + static void gcode_line_error(PGM_P const err, const int8_t port); + +}; + +extern GCodeQueue queue; diff --git a/Marlin/src/gcode/sdcard/M28_M29.cpp b/Marlin/src/gcode/sdcard/M28_M29.cpp index 815a43ae0c..ae31eec165 100644 --- a/Marlin/src/gcode/sdcard/M28_M29.cpp +++ b/Marlin/src/gcode/sdcard/M28_M29.cpp @@ -53,7 +53,7 @@ void GcodeSuite::M28() { SERIAL_ECHOLN(p); card.openFile(p, false); #if NUM_SERIAL > 1 - card.transfer_port_index = command_queue_port[cmd_queue_index_r]; + card.transfer_port_index = queue.port[queue.index_r]; #endif } else diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index a1b922bed6..dc36febad3 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -46,7 +46,7 @@ #define ADC_KEY_NUM 8 #define ULTIPANEL - // this helps to implement ADC_KEYPAD menus + // This helps to implement ADC_KEYPAD menus #define REVERSE_MENU_DIRECTION #define ENCODER_PULSES_PER_STEP 1 #define ENCODER_STEPS_PER_MENU_ITEM 1 @@ -97,8 +97,6 @@ #define U8GLIB_SSD1306 #define ULTIPANEL - #define REVERSE_ENCODER_DIRECTION - #define REVERSE_MENU_DIRECTION #elif ENABLED(RA_CONTROL_PANEL) @@ -141,15 +139,18 @@ #define DEFAULT_LCD_CONTRAST 150 #define LCD_CONTRAST_MAX 255 -#elif ANY(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1) +#elif ANY(FYSETC_MINI_12864_X_X, FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1) #define FYSETC_MINI_12864 #define DOGLCD #define ULTIPANEL #define LCD_CONTRAST_MIN 0 #define LCD_CONTRAST_MAX 255 - #define DEFAULT_LCD_CONTRAST 255 + #define DEFAULT_LCD_CONTRAST 220 #define LED_COLORS_REDUCE_GREEN + #if POWER_SUPPLY > 0 && EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1) + #define LED_BACKLIGHT_TIMEOUT 10000 + #endif // Require LED backlighting enabled #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) @@ -178,7 +179,6 @@ #if ENABLED(ULTI_CONTROLLER) #define U8GLIB_SSD1309 - #define REVERSE_ENCODER_DIRECTION #define LCD_RESET_PIN LCD_PINS_D6 // This controller need a reset pin #define LCD_CONTRAST_MIN 0 #define LCD_CONTRAST_MAX 254 @@ -335,7 +335,7 @@ #endif // Extensible UI serial touch screens. (See src/lcd/extensible_ui) -#if ENABLED(MALYAN_LCD) +#if EITHER(DGUS_LCD, MALYAN_LCD) #define EXTENSIBLE_UI #endif @@ -405,9 +405,6 @@ #define E_MANUAL EXTRUDERS #elif ENABLED(PRUSA_MMU2) #define E_STEPPERS 1 - #ifndef TOOLCHANGE_ZRAISE - #define TOOLCHANGE_ZRAISE 0 - #endif #endif // No inactive extruders with MK2_MULTIPLEXER or SWITCHING_NOZZLE @@ -502,24 +499,30 @@ /** * Set flags for enabled probes */ -#define HAS_BED_PROBE (HAS_Z_SERVO_PROBE || ANY(FIX_MOUNTED_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, SOLENOID_PROBE, SENSORLESS_PROBING, RACK_AND_PINION_PROBE)) +#define HAS_BED_PROBE (HAS_Z_SERVO_PROBE || ANY(FIX_MOUNTED_PROBE, TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, SOLENOID_PROBE, SENSORLESS_PROBING, RACK_AND_PINION_PROBE)) #define PROBE_SELECTED (HAS_BED_PROBE || EITHER(PROBE_MANUALLY, MESH_BED_LEVELING)) #if HAS_BED_PROBE #define USES_Z_MIN_PROBE_ENDSTOP DISABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + #define HOMING_Z_WITH_PROBE (Z_HOME_DIR < 0 && !USES_Z_MIN_PROBE_ENDSTOP) #ifndef Z_PROBE_LOW_POINT #define Z_PROBE_LOW_POINT -5 #endif #if ENABLED(Z_PROBE_ALLEN_KEY) #define PROBE_TRIGGERED_WHEN_STOWED_TEST // Extra test for Allen Key Probe #endif + #ifdef MULTIPLE_PROBING + #if EXTRA_PROBING + #define TOTAL_PROBING (MULTIPLE_PROBING + EXTRA_PROBING) + #else + #define TOTAL_PROBING MULTIPLE_PROBING + #endif + #endif #else // Clear probe pin settings when no probe is selected #undef Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN #endif -#define HOMING_Z_WITH_PROBE (HAS_BED_PROBE && Z_HOME_DIR < 0 && ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)) - #ifdef GRID_MAX_POINTS_X #define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y)) #endif diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index a1f762193b..d5d0e89994 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -493,7 +493,7 @@ * Preserve this ordering when adding new drivers. */ -#define TRINAMICS (HAS_TRINAMIC || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE) || HAS_DRIVER(TMC5130_STANDALONE) || HAS_DRIVER(TMC5160_STANDALONE) || HAS_DRIVER(TMC2160_STANDALONE)) +#define TRINAMICS (HAS_TRINAMIC || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC2209_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE) || HAS_DRIVER(TMC5130_STANDALONE) || HAS_DRIVER(TMC5160_STANDALONE) || HAS_DRIVER(TMC2160_STANDALONE)) #ifndef MINIMUM_STEPPER_DIR_DELAY #if HAS_DRIVER(TB6560) @@ -905,8 +905,8 @@ #if HAS_TRINAMIC #define HAS_TMCX1X0 (HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2160) || HAS_DRIVER(TMC5130) || HAS_DRIVER(TMC5160)) #define TMC_HAS_SPI (HAS_TMCX1X0 || HAS_DRIVER(TMC2660)) - #define HAS_STALLGUARD (HAS_TMCX1X0 || HAS_DRIVER(TMC2660)) - #define HAS_STEALTHCHOP (HAS_TMCX1X0 || HAS_DRIVER(TMC2208)) + #define HAS_STALLGUARD (HAS_TMCX1X0 || HAS_DRIVER(TMC2209) || HAS_DRIVER(TMC2660)) + #define HAS_STEALTHCHOP (HAS_TMCX1X0 || HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)) #define STEALTHCHOP_ENABLED ANY(STEALTHCHOP_XY, STEALTHCHOP_Z, STEALTHCHOP_E) #define USE_SENSORLESS EITHER(SENSORLESS_HOMING, SENSORLESS_PROBING) @@ -1700,8 +1700,6 @@ // If platform requires early initialization of watchdog to properly boot #define EARLY_WATCHDOG (ENABLED(USE_WATCHDOG) && defined(ARDUINO_ARCH_SAM)) -#define USE_EXECUTE_COMMANDS_IMMEDIATE (ANY(G29_RETRY_AND_RECOVER, GCODE_MACROS, POWER_LOSS_RECOVERY) || HAS_DRIVER(L6470)) - #if ENABLED(Z_TRIPLE_STEPPER_DRIVERS) #define Z_STEPPER_COUNT 3 #elif ENABLED(Z_DUAL_STEPPER_DRIVERS) diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 5bea38d9eb..9fb9847658 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -48,6 +48,7 @@ #if !defined(CONFIGURATION_ADV_H_VERSION) || HEXIFY(CONFIGURATION_ADV_H_VERSION) < HEXIFY(REQUIRED_CONFIGURATION_ADV_H_VERSION) #error "You are using an old Configuration_adv.h file, update it before building Marlin." #endif +#undef HEXIFY /** * Warnings for old configurations @@ -274,6 +275,8 @@ #error "HAVE_TMC26X is now [AXIS]_DRIVER_TYPE TMC26X. Please update your Configuration.h." #elif defined(HAVE_TMC2130) #error "HAVE_TMC2130 is now [AXIS]_DRIVER_TYPE TMC2130. Please update your Configuration.h." +#elif defined(HAVE_TMC2208) + #error "HAVE_TMC2208 is now [AXIS]_DRIVER_TYPE TMC2208. Please update your Configuration.h." #elif defined(HAVE_L6470DRIVER) #error "HAVE_L6470DRIVER is now [AXIS]_DRIVER_TYPE L6470. Please update your Configuration.h." #elif defined(X_IS_TMC) || defined(X2_IS_TMC) || defined(Y_IS_TMC) || defined(Y2_IS_TMC) || defined(Z_IS_TMC) || defined(Z2_IS_TMC) || defined(Z3_IS_TMC) \ @@ -355,6 +358,10 @@ #error "Z_MIN_PROBE_ENDSTOP is no longer required. Please remove it from Configuration.h." #elif defined(DUAL_NOZZLE_DUPLICATION_MODE) #error "DUAL_NOZZLE_DUPLICATION_MODE is now MULTI_NOZZLE_DUPLICATION. Please update your configuration." +#elif defined(MENU_ITEM_CASE_LIGHT) + #error "MENU_ITEM_CASE_LIGHT is now CASE_LIGHT_MENU. Please update your configuration." +#elif defined(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + #error "ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED is now SD_ABORT_ON_ENDSTOP_HIT. Please update your Configuration_adv.h." #endif #define BOARD_MKS_13 -47 @@ -370,6 +377,10 @@ #elif MB(FORMBOT_TREX2) #error "FORMBOT_TREX2 has been renamed BOARD_FORMBOT_TREX2PLUS. Please update your configuration." #endif +#undef BOARD_MKS_13 +#undef BOARD_TRIGORILLA +#undef BOARD_RURAMPS4D +#undef BOARD_FORMBOT_TREX2 /** * Marlin release, version and default string @@ -694,7 +705,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif #ifndef TOOLCHANGE_ZRAISE - #error "TOOLCHANGE_ZRAISE required for EXTRUDERS > 1. Please update your Configuration." + #error "TOOLCHANGE_ZRAISE required for EXTRUDERS > 1. Please update your Configuration_adv.h." #endif #elif ENABLED(MK2_MULTIPLEXER) @@ -976,11 +987,12 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS + ENABLED(FIX_MOUNTED_PROBE) \ + (HAS_Z_SERVO_PROBE && DISABLED(BLTOUCH)) \ + ENABLED(BLTOUCH) \ + + ENABLED(TOUCH_MI_PROBE) \ + ENABLED(SOLENOID_PROBE) \ + ENABLED(Z_PROBE_ALLEN_KEY) \ + ENABLED(Z_PROBE_SLED) \ + ENABLED(RACK_AND_PINION_PROBE) - #error "Please enable only one probe option: PROBE_MANUALLY, FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or Z Servo." + #error "Please enable only one probe option: PROBE_MANUALLY, FIX_MOUNTED_PROBE, BLTOUCH, TOUCH_MI_PROBE, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or Z Servo." #endif #if HAS_BED_PROBE @@ -1037,14 +1049,33 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "RACK_AND_PINION_PROBE requires Z_PROBE_DEPLOY_X and Z_PROBE_RETRACT_X." #endif + /** + * Touch-MI probe requirements + */ + #if ENABLED(TOUCH_MI_PROBE) + #if DISABLED(Z_SAFE_HOMING) + #error "TOUCH_MI_PROBE requires Z_SAFE_HOMING." + #elif !defined(TOUCH_MI_RETRACT_Z) + #error "TOUCH_MI_PROBE requires TOUCH_MI_RETRACT_Z." + #elif defined(Z_AFTER_PROBING) + #error "TOUCH_MI_PROBE requires Z_AFTER_PROBING to be disabled." + #elif Z_HOMING_HEIGHT < 10 + #error "TOUCH_MI_PROBE requires Z_HOMING_HEIGHT >= 10." + #elif Z_MIN_PROBE_ENDSTOP_INVERTING + #error "TOUCH_MI_PROBE requires Z_MIN_PROBE_ENDSTOP_INVERTING to be set to false." + #elif DISABLED(BABYSTEP_ZPROBE_OFFSET) + #error "TOUCH_MI_PROBE requires BABYSTEPPING with BABYSTEP_ZPROBE_OFFSET." + #endif + #endif + /** * Require pin options and pins to be defined */ #if ENABLED(SENSORLESS_PROBING) - #if ENABLED(DELTA) && (!AXIS_DRIVER_TYPE_X(TMC2130) || !AXIS_DRIVER_TYPE_Y(TMC2130) || !AXIS_DRIVER_TYPE_Z(TMC2130)) - #error "SENSORLESS_PROBING requires TMC2130 drivers on X, Y, and Z." - #elif !AXIS_DRIVER_TYPE_Z(TMC2130) - #error "SENSORLESS_PROBING requires a TMC2130 driver on Z." + #if ENABLED(DELTA) && !(AXIS_HAS_STALLGUARD(X) && AXIS_HAS_STALLGUARD(Y) && AXIS_HAS_STALLGUARD(Z)) + #error "SENSORLESS_PROBING requires TMC2130/2160/2209/5130/5160 drivers on X, Y, and Z." + #elif !AXIS_HAS_STALLGUARD(Z) + #error "SENSORLESS_PROBING requires a TMC2130/2160/2209/5130/5160 driver on Z." #endif #elif ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) #if DISABLED(USE_ZMIN_PLUG) @@ -1073,8 +1104,14 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "Probes need Z_AFTER_PROBING >= 0." #endif - #if MULTIPLE_PROBING && MULTIPLE_PROBING < 2 - #error "MULTIPLE_PROBING must be >= 2." + #if MULTIPLE_PROBING || EXTRA_PROBING + #if !MULTIPLE_PROBING + #error "EXTRA_PROBING requires MULTIPLE_PROBING." + #elif MULTIPLE_PROBING < 2 + #error "MULTIPLE_PROBING must be 2 or more." + #elif MULTIPLE_PROBING <= EXTRA_PROBING + #error "EXTRA_PROBING must be less than MULTIPLE_PROBING." + #endif #endif #if Z_PROBE_LOW_POINT > 0 @@ -1369,9 +1406,9 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "TEMP_SENSOR_4 1000 requires HOTEND4_PULLUP_RESISTOR_OHMS, HOTEND4_RESISTANCE_25C_OHMS and HOTEND4_BETA in Configuration_adv.h." #elif ENABLED(HEATER_5_USER_THERMISTOR) && !(defined(HOTEND5_PULLUP_RESISTOR_OHMS) && defined(HOTEND5_RESISTANCE_25C_OHMS) && defined(HOTEND5_BETA)) #error "TEMP_SENSOR_5 1000 requires HOTEND5_PULLUP_RESISTOR_OHMS, HOTEND5_RESISTANCE_25C_OHMS and HOTEND5_BETA in Configuration_adv.h." -#elif ENABLED(BED_USER_THERMISTOR) && !(defined(BED_PULLUP_RESISTOR_OHMS) && defined(BED_RESISTANCE_25C_OHMS) && defined(BED_BETA)) +#elif ENABLED(HEATER_BED_USER_THERMISTOR) && !(defined(BED_PULLUP_RESISTOR_OHMS) && defined(BED_RESISTANCE_25C_OHMS) && defined(BED_BETA)) #error "TEMP_SENSOR_BED 1000 requires BED_PULLUP_RESISTOR_OHMS, BED_RESISTANCE_25C_OHMS and BED_BETA in Configuration_adv.h." -#elif ENABLED(CHAMBER_USER_THERMISTOR) && !(defined(CHAMBER_PULLUP_RESISTOR_OHMS) && defined(CHAMBER_RESISTANCE_25C_OHMS) && defined(CHAMBER_BETA)) +#elif ENABLED(HEATER_CHAMBER_USER_THERMISTOR) && !(defined(CHAMBER_PULLUP_RESISTOR_OHMS) && defined(CHAMBER_RESISTANCE_25C_OHMS) && defined(CHAMBER_BETA)) #error "TEMP_SENSOR_CHAMBER 1000 requires CHAMBER_PULLUP_RESISTOR_OHMS, CHAMBER_RESISTANCE_25C_OHMS and CHAMBER_BETA in Configuration_adv.h." #endif @@ -1491,6 +1528,13 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "LED_CONTROL_MENU requires BLINKM, RGB_LED, RGBW_LED, PCA9533, PCA9632, or NEOPIXEL_LED." #endif +/** + * LED Backlight Timeout + */ +#if defined(LED_BACKLIGHT_TIMEOUT) && !(EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1) && POWER_SUPPLY > 0) + #error "LED_BACKLIGHT_TIMEOUT requires a Fysetc Mini Panel and a Power Switch." +#endif + /** * Basic multi hotend duplication mode */ @@ -1739,6 +1783,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "NEOPIXEL_LED requires NEOPIXEL_PIN and NEOPIXEL_PIXELS." #endif #endif +#undef _RGB_TEST /** * Auto Fan check for PWM pins @@ -1804,6 +1849,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS + ENABLED(G3D_PANEL) \ + (ENABLED(MINIPANEL) && DISABLED(MKS_MINI_12864)) \ + ENABLED(MKS_MINI_12864) \ + + ENABLED(FYSETC_MINI_12864_X_X) \ + ENABLED(FYSETC_MINI_12864_1_2) \ + ENABLED(FYSETC_MINI_12864_2_0) \ + ENABLED(FYSETC_MINI_12864_2_1) \ @@ -1838,73 +1884,106 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS /** * Check existing CS pins against enabled TMC SPI drivers. */ -#define INVALID_TMC2130(ST) (AXIS_DRIVER_TYPE(ST, TMC2130) && !PIN_EXISTS(ST##_CS)) -#if INVALID_TMC2130(X) - #error "TMC2130 on X requires X_CS_PIN." -#elif INVALID_TMC2130(X2) - #error "TMC2130 on X2 requires X2_CS_PIN." -#elif INVALID_TMC2130(Y) - #error "TMC2130 on Y requires Y_CS_PIN." -#elif INVALID_TMC2130(Y2) - #error "TMC2130 on Y2 requires Y2_CS_PIN." -#elif INVALID_TMC2130(Z) - #error "TMC2130 on Z requires Z_CS_PIN." -#elif INVALID_TMC2130(Z2) - #error "TMC2130 on Z2 requires Z2_CS_PIN." -#elif INVALID_TMC2130(Z3) - #error "TMC2130 on Z3 requires Z3_CS_PIN." -#elif INVALID_TMC2130(E0) - #error "TMC2130 on E0 requires E0_CS_PIN." -#elif INVALID_TMC2130(E1) - #error "TMC2130 on E1 requires E1_CS_PIN." -#elif INVALID_TMC2130(E2) - #error "TMC2130 on E2 requires E2_CS_PIN." -#elif INVALID_TMC2130(E3) - #error "TMC2130 on E3 requires E3_CS_PIN." -#elif INVALID_TMC2130(E4) - #error "TMC2130 on E4 requires E4_CS_PIN." -#elif INVALID_TMC2130(E5) - #error "TMC2130 on E5 requires E5_CS_PIN." +#define INVALID_TMC_SPI(ST) (AXIS_HAS_SPI && !PIN_EXISTS(ST##_CS)) +#if INVALID_TMC_SPI(X) + #error "An SPI driven TMC driver on X requires X_CS_PIN." +#elif INVALID_TMC_SPI(X2) + #error "An SPI driven TMC driver on X2 requires X2_CS_PIN." +#elif INVALID_TMC_SPI(Y) + #error "An SPI driven TMC driver on Y requires Y_CS_PIN." +#elif INVALID_TMC_SPI(Y2) + #error "An SPI driven TMC driver on Y2 requires Y2_CS_PIN." +#elif INVALID_TMC_SPI(Z) + #error "An SPI driven TMC driver on Z requires Z_CS_PIN." +#elif INVALID_TMC_SPI(Z2) + #error "An SPI driven TMC driver on Z2 requires Z2_CS_PIN." +#elif INVALID_TMC_SPI(Z3) + #error "An SPI driven TMC driver on Z3 requires Z3_CS_PIN." +#elif INVALID_TMC_SPI(E0) + #error "An SPI driven TMC driver on E0 requires E0_CS_PIN." +#elif INVALID_TMC_SPI(E1) + #error "An SPI driven TMC driver on E1 requires E1_CS_PIN." +#elif INVALID_TMC_SPI(E2) + #error "An SPI driven TMC driver on E2 requires E2_CS_PIN." +#elif INVALID_TMC_SPI(E3) + #error "An SPI driven TMC driver on E3 requires E3_CS_PIN." +#elif INVALID_TMC_SPI(E4) + #error "An SPI driven TMC driver on E4 requires E4_CS_PIN." +#elif INVALID_TMC_SPI(E5) + #error "An SPI driven TMC driver on E5 requires E5_CS_PIN." #endif -#undef INVALID_TMC2130 +#undef INVALID_TMC_SPI /** * Check existing RX/TX pins against enable TMC UART drivers. */ -#define INVALID_TMC2208(ST) (AXIS_DRIVER_TYPE(ST, TMC2208) && !(defined(ST##_HARDWARE_SERIAL) || (PIN_EXISTS(ST##_SERIAL_RX, ST##_SERIAL_TX)))) -#if INVALID_TMC2208(X) - #error "TMC2208 on X requires X_HARDWARE_SERIAL or X_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(X2) - #error "TMC2208 on X2 requires X2_HARDWARE_SERIAL or X2_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(Y) - #error "TMC2208 on Y requires Y_HARDWARE_SERIAL or Y_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(Y2) - #error "TMC2208 on Y2 requires Y2_HARDWARE_SERIAL or Y2_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(Z) - #error "TMC2208 on Z requires Z_HARDWARE_SERIAL or Z_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(Z2) - #error "TMC2208 on Z2 requires Z2_HARDWARE_SERIAL or Z2_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(Z3) - #error "TMC2208 on Z3 requires Z3_HARDWARE_SERIAL or Z3_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(E0) - #error "TMC2208 on E0 requires E0_HARDWARE_SERIAL or E0_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(E1) - #error "TMC2208 on E1 requires E1_HARDWARE_SERIAL or E1_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(E2) - #error "TMC2208 on E2 requires E2_HARDWARE_SERIAL or E2_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(E3) - #error "TMC2208 on E3 requires E3_HARDWARE_SERIAL or E3_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(E4) - #error "TMC2208 on E4 requires E4_HARDWARE_SERIAL or E4_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC2208(E5) - #error "TMC2208 on E5 requires E5_HARDWARE_SERIAL or E5_SERIAL_(RX|TX)_PIN." +#define INVALID_TMC_UART(ST) (AXIS_HAS_UART(ST) && !(defined(ST##_HARDWARE_SERIAL) || (PIN_EXISTS(ST##_SERIAL_RX, ST##_SERIAL_TX)))) +#if INVALID_TMC_UART(X) + #error "TMC2208 or TMC2209 on X requires X_HARDWARE_SERIAL or X_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(X2) + #error "TMC2208 or TMC2209 on X2 requires X2_HARDWARE_SERIAL or X2_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(Y) + #error "TMC2208 or TMC2209 on Y requires Y_HARDWARE_SERIAL or Y_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(Y2) + #error "TMC2208 or TMC2209 on Y2 requires Y2_HARDWARE_SERIAL or Y2_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(Z) + #error "TMC2208 or TMC2209 on Z requires Z_HARDWARE_SERIAL or Z_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(Z2) + #error "TMC2208 or TMC2209 on Z2 requires Z2_HARDWARE_SERIAL or Z2_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(Z3) + #error "TMC2208 or TMC2209 on Z3 requires Z3_HARDWARE_SERIAL or Z3_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(E0) + #error "TMC2208 or TMC2209 on E0 requires E0_HARDWARE_SERIAL or E0_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(E1) + #error "TMC2208 or TMC2209 on E1 requires E1_HARDWARE_SERIAL or E1_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(E2) + #error "TMC2208 or TMC2209 on E2 requires E2_HARDWARE_SERIAL or E2_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(E3) + #error "TMC2208 or TMC2209 on E3 requires E3_HARDWARE_SERIAL or E3_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(E4) + #error "TMC2208 or TMC2209 on E4 requires E4_HARDWARE_SERIAL or E4_SERIAL_(RX|TX)_PIN." +#elif INVALID_TMC_UART(E5) + #error "TMC2208 or TMC2209 on E5 requires E5_HARDWARE_SERIAL or E5_SERIAL_(RX|TX)_PIN." #endif -#undef INVALID_TMC2208 +#undef INVALID_TMC_UART /** - * TMC2208 software UART and ENDSTOP_INTERRUPTS both use pin change interrupts (PCI) + * TMC2209 slave address values */ -#if HAS_DRIVER(TMC2208) && ENABLED(ENDSTOP_INTERRUPTS_FEATURE) && !( \ +#define INVALID_TMC_ADDRESS(ST) static_assert(0 <= ST##_SLAVE_ADDRESS && ST##_SLAVE_ADDRESS <= 3, "TMC2209 slave address must be 0, 1, 2 or 3") +#if AXIS_DRIVER_TYPE_X(TMC2209) + INVALID_TMC_ADDRESS(X); +#elif AXIS_DRIVER_TYPE_X2(TMC2209) + INVALID_TMC_ADDRESS(X2); +#elif AXIS_DRIVER_TYPE_Y(TMC2209) + INVALID_TMC_ADDRESS(Y); +#elif AXIS_DRIVER_TYPE_Y2(TMC2209) + INVALID_TMC_ADDRESS(Y2); +#elif AXIS_DRIVER_TYPE_Z(TMC2209) + INVALID_TMC_ADDRESS(Z); +#elif AXIS_DRIVER_TYPE_Z2(TMC2209) + INVALID_TMC_ADDRESS(Z2); +#elif AXIS_DRIVER_TYPE_Z3(TMC2209) + INVALID_TMC_ADDRESS(Z3); +#elif AXIS_DRIVER_TYPE_E0(TMC2209) + INVALID_TMC_ADDRESS(E0); +#elif AXIS_DRIVER_TYPE_E1(TMC2209) + INVALID_TMC_ADDRESS(E1); +#elif AXIS_DRIVER_TYPE_E2(TMC2209) + INVALID_TMC_ADDRESS(E2); +#elif AXIS_DRIVER_TYPE_E3(TMC2209) + INVALID_TMC_ADDRESS(E3); +#elif AXIS_DRIVER_TYPE_E4(TMC2209) + INVALID_TMC_ADDRESS(E4); +#elif AXIS_DRIVER_TYPE_E5(TMC2209) + INVALID_TMC_ADDRESS(E5); +#endif +#undef INVALID_TMC_ADDRESS + +/** + * TMC2208/2209 software UART and ENDSTOP_INTERRUPTS both use pin change interrupts (PCI) + */ +#if (HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)) && ENABLED(ENDSTOP_INTERRUPTS_FEATURE) && !( \ defined(X_HARDWARE_SERIAL ) \ || defined(X2_HARDWARE_SERIAL) \ || defined(Y_HARDWARE_SERIAL ) \ @@ -1922,9 +2001,9 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif /** - * TMC2208 software UART is only supported on AVR + * TMC2208/2209 software UART is only supported on AVR and LPC */ -#if HAS_DRIVER(TMC2208) && !defined(__AVR__) && !defined(TARGET_LPC1768) && !( \ +#if (HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)) && !defined(__AVR__) && !defined(TARGET_LPC1768) && !( \ defined(X_HARDWARE_SERIAL ) \ || defined(X2_HARDWARE_SERIAL) \ || defined(Y_HARDWARE_SERIAL ) \ @@ -1945,32 +2024,45 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS // is necessary in order to reset the stallGuard indication between the initial movement of all three // towers to +Z and the individual homing of each tower. This restriction can be removed once a means of // clearing the stallGuard activated status is found. + + // Stall detection DIAG = HIGH : TMC2209 + // Stall detection DIAG = LOW : TMC2130/TMC2160/TMC2660/TMC5130/TMC5160 + #define X_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(X,TMC2209) + #define Y_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(Y,TMC2209) + #define Z_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(Z,TMC2209) + #if ENABLED(DELTA) && !BOTH(STEALTHCHOP_XY, STEALTHCHOP_Z) #error "SENSORLESS_HOMING on DELTA currently requires STEALTHCHOP_XY and STEALTHCHOP_Z." - #elif X_SENSORLESS && X_HOME_DIR == -1 && (!X_MIN_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_XMIN)) + #elif X_SENSORLESS && X_HOME_DIR == -1 && (X_MIN_ENDSTOP_INVERTING != X_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_XMIN)) #error "SENSORLESS_HOMING requires X_MIN_ENDSTOP_INVERTING and ENDSTOPPULLUP_XMIN when homing to X_MIN." - #elif X_SENSORLESS && X_HOME_DIR == 1 && (!X_MAX_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_XMAX)) + #elif X_SENSORLESS && X_HOME_DIR == 1 && (X_MAX_ENDSTOP_INVERTING != X_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_XMAX)) #error "SENSORLESS_HOMING requires X_MAX_ENDSTOP_INVERTING and ENDSTOPPULLUP_XMAX when homing to X_MAX." - #elif Y_SENSORLESS && Y_HOME_DIR == -1 && (!Y_MIN_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_YMIN)) + #elif Y_SENSORLESS && Y_HOME_DIR == -1 && (Y_MIN_ENDSTOP_INVERTING != Y_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_YMIN)) #error "SENSORLESS_HOMING requires Y_MIN_ENDSTOP_INVERTING and ENDSTOPPULLUP_YMIN when homing to Y_MIN." - #elif Y_SENSORLESS && Y_HOME_DIR == 1 && (!Y_MAX_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_YMAX)) + #elif Y_SENSORLESS && Y_HOME_DIR == 1 && (Y_MAX_ENDSTOP_INVERTING != Y_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_YMAX)) #error "SENSORLESS_HOMING requires Y_MAX_ENDSTOP_INVERTING and ENDSTOPPULLUP_YMAX when homing to Y_MAX." - #elif Z_SENSORLESS && Z_HOME_DIR == -1 && (!Z_MIN_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_ZMIN)) + #elif Z_SENSORLESS && Z_HOME_DIR == -1 && (Z_MIN_ENDSTOP_INVERTING != Z_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_ZMIN)) #error "SENSORLESS_HOMING requires Z_MIN_ENDSTOP_INVERTING and ENDSTOPPULLUP_ZMIN when homing to Z_MIN." - #elif Z_SENSORLESS && Z_HOME_DIR == 1 && (!Z_MAX_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_ZMAX)) + #elif Z_SENSORLESS && Z_HOME_DIR == 1 && (Z_MAX_ENDSTOP_INVERTING != Z_ENDSTOP_INVERTING || DISABLED(ENDSTOPPULLUP_ZMAX)) #error "SENSORLESS_HOMING requires Z_MAX_ENDSTOP_INVERTING and ENDSTOPPULLUP_ZMAX when homing to Z_MAX." #elif ENDSTOP_NOISE_THRESHOLD #error "SENSORLESS_HOMING is incompatible with ENDSTOP_NOISE_THRESHOLD." + #elif !(X_SENSORLESS || Y_SENSORLESS || Z_SENSORLESS) + #error "SENSORLESS_HOMING requires a TMC stepper driver with StallGuard on X, Y, or Z axes." #endif + + #undef X_ENDSTOP_INVERTING + #undef Y_ENDSTOP_INVERTING + #undef Z_ENDSTOP_INVERTING #endif -// Sensorless homing/probing requirements -#if ENABLED(SENSORLESS_HOMING) && !(X_SENSORLESS || Y_SENSORLESS || Z_SENSORLESS) - #error "SENSORLESS_HOMING requires a TMC stepper driver with StallGuard on X, Y, or Z axes." -#elif BOTH(SENSORLESS_PROBING, DELTA) && !(X_SENSORLESS && Y_SENSORLESS && Z_SENSORLESS) - #error "SENSORLESS_PROBING for DELTA requires TMC stepper drivers with StallGuard on X, Y, and Z axes." -#elif ENABLED(SENSORLESS_PROBING) && !Z_SENSORLESS - #error "SENSORLESS_PROBING requires a TMC stepper driver with StallGuard on Z." +// Sensorless probing requirements +#if ENABLED(SENSORLESS_PROBING) + #if ENABLED(DELTA) && !(X_SENSORLESS && Y_SENSORLESS && Z_SENSORLESS) + #error "SENSORLESS_PROBING for DELTA requires TMC stepper drivers with StallGuard on X, Y, and Z axes." + #elif !Z_SENSORLESS + #error "SENSORLESS_PROBING requires a TMC stepper driver with StallGuard on Z." + #endif #endif // Sensorless homing is required for both combined steppers in an H-bot @@ -1986,11 +2078,11 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #if ENABLED(HYBRID_THRESHOLD) && !STEALTHCHOP_ENABLED #error "Enable STEALTHCHOP_(XY|Z|E) to use HYBRID_THRESHOLD." #elif ENABLED(SENSORLESS_HOMING) && !HAS_STALLGUARD - #error "SENSORLESS_HOMING requires TMC2130 or TMC2160 or TMC5160 stepper drivers." + #error "SENSORLESS_HOMING requires TMC2130, TMC2160, TMC2209, TMC2660, or TMC5160 stepper drivers." #elif ENABLED(SENSORLESS_PROBING) && !HAS_STALLGUARD - #error "SENSORLESS_PROBING requires TMC2130 stepper drivers." + #error "SENSORLESS_PROBING requires TMC2130, TMC2160, TMC2209, TMC2660, or TMC5160 stepper drivers." #elif STEALTHCHOP_ENABLED && !HAS_STEALTHCHOP - #error "STEALTHCHOP requires TMC2130 or TMC2160 or TMC2208 or TMC5160 stepper drivers." + #error "STEALTHCHOP requires TMC2130, TMC2160, TMC2208, TMC2209, or TMC5160 stepper drivers." #endif #if ENABLED(DELTA) && (ENABLED(STEALTHCHOP_XY) != ENABLED(STEALTHCHOP_Z)) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index f646d454c1..78769326ff 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -39,7 +39,7 @@ /** * Marlin release version identifier */ - #define SHORT_BUILD_VERSION "2.0.x_TR16" + #define SHORT_BUILD_VERSION "2.0.x_TR17" /** * Verbose version identifier which should contain a reference to the location @@ -52,7 +52,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ - #define STRING_DISTRIBUTION_DATE "2019-05-26" + #define STRING_DISTRIBUTION_DATE "2019-06-23" /** * Required minimum Configuration.h and Configuration_adv.h file versions. diff --git a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp index 4d205be300..03a3f97628 100644 --- a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp @@ -33,6 +33,7 @@ #include "ultralcd_HD44780.h" #include "../ultralcd.h" +#include "../../libs/numtostr.h" #include "../../sd/cardreader.h" #include "../../module/temperature.h" diff --git a/Marlin/src/lcd/HD44780/ultralcd_HD44780.h b/Marlin/src/lcd/HD44780/ultralcd_HD44780.h index 5ca36cb226..c742f59e31 100644 --- a/Marlin/src/lcd/HD44780/ultralcd_HD44780.h +++ b/Marlin/src/lcd/HD44780/ultralcd_HD44780.h @@ -90,7 +90,6 @@ //https://github.com/mikeshub/SailfishLCD //uses the code directly from Sailfish - #include #include #define LCD_CLASS LiquidCrystalSerial diff --git a/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h b/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h index f0d795b840..2f2340ca41 100644 --- a/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h +++ b/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h @@ -28,19 +28,22 @@ #ifdef __SAM3X8E__ uint8_t u8g_com_HAL_DUE_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); #define U8G_COM_HAL_SW_SPI_FN u8g_com_HAL_DUE_sw_spi_fn - uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); #define U8G_COM_HAL_HW_SPI_FN u8g_com_HAL_DUE_shared_hw_spi_fn - uint8_t u8g_com_HAL_DUE_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); #define U8G_COM_ST7920_HAL_SW_SPI u8g_com_HAL_DUE_ST7920_sw_spi_fn - #else - uint8_t u8g_com_HAL_AVR_sw_sp_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); - #define U8G_COM_HAL_SW_SPI_FN u8g_com_HAL_AVR_sw_sp_fn - + #elif defined(__STM32F1__) + uint8_t u8g_com_HAL_STM32F1_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_HAL_SW_SPI_FN u8g_com_HAL_STM32F1_sw_spi_fn + uint8_t u8g_com_arduino_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_HAL_HW_SPI_FN u8g_com_arduino_hw_spi_fn + uint8_t u8g_com_arduino_st7920_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_ST7920_HAL_SW_SPI u8g_com_arduino_st7920_spi_fn + #else + uint8_t u8g_com_HAL_AVR_sw_sp_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_HAL_SW_SPI_FN u8g_com_HAL_AVR_sw_sp_fn // AVR ? uint8_t u8g_com_arduino_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); #define U8G_COM_HAL_HW_SPI_FN u8g_com_arduino_hw_spi_fn - uint8_t u8g_com_arduino_st7920_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); #define U8G_COM_ST7920_HAL_SW_SPI u8g_com_arduino_st7920_spi_fn #endif @@ -51,7 +54,7 @@ uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); #define U8G_COM_SSD_I2C_HAL u8g_com_arduino_ssd_i2c_fn - #ifdef ARDUINO_ARCH_STM32F1 + #if defined(ARDUINO_ARCH_STM32F1) && PIN_EXISTS(FSMC_CS) uint8_t u8g_com_stm32duino_fsmc_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); #define U8G_COM_HAL_FSMC_FN u8g_com_stm32duino_fsmc_fn #else diff --git a/Marlin/src/lcd/dogm/dogm_Statusscreen.h b/Marlin/src/lcd/dogm/dogm_Statusscreen.h index 438d57ac7f..8e31841fc4 100644 --- a/Marlin/src/lcd/dogm/dogm_Statusscreen.h +++ b/Marlin/src/lcd/dogm/dogm_Statusscreen.h @@ -659,6 +659,63 @@ #endif // !STATUS_BED_WIDTH && !STATUS_COMBINE_HEATERS && HAS_HEATED_BED && HOTENDS < 4 +#if HAS_HEATED_CHAMBER + + #define STATUS_CHAMBER_WIDTH 16 + + #ifdef STATUS_CHAMBER_ANIM + + const unsigned char status_chamber_bmp[] PROGMEM = { + B11111111,B11111111, + B10000000,B00000001, + B10000000,B00000001, + B10000000,B00000001, + B10000000,B00000001, + B10000000,B00000001, + B10000000,B00000001, + B10000000,B00000001, + B10000000,B00000001, + B10000000,B00000001, + B11111111,B11111111, + B11111111,B11111111 + }; + + const unsigned char status_chamber_on_bmp[] PROGMEM = { + B11111111,B11111111, + B10000000,B00000001, + B10000100,B00100001, + B10000010,B00010001, + B10000010,B00010001, + B10000100,B00100001, + B10001000,B01000001, + B10001000,B01000001, + B10000100,B00100001, + B10000000,B00000001, + B11111111,B11111111, + B11111111,B11111111 + }; + + #else + + const unsigned char status_chamber_bmp[] PROGMEM = { + B11111111,B11111111, + B10000000,B00000001, + B10000100,B00100001, + B10000010,B00010001, + B10000010,B00010001, + B10000100,B00100001, + B10001000,B01000001, + B10001000,B01000001, + B10000100,B00100001, + B10000000,B00000001, + B11111111,B11111111, + B11111111,B11111111 + }; + + #endif + +#endif // HAS_HEATED_CHAMBER + // Can also be overridden in Configuration.h // If you can afford it, try the 3-frame fan animation! // Don't compile in the fan animation with no fan @@ -1302,6 +1359,50 @@ #endif +// +// Chamber Bitmap Properties +// +#ifndef STATUS_CHAMBER_WIDTH + #define STATUS_CHAMBER_WIDTH 0 +#endif +#ifndef STATUS_CHAMBER_BYTEWIDTH + #define STATUS_CHAMBER_BYTEWIDTH BW(STATUS_CHAMBER_WIDTH) +#endif +#if STATUS_CHAMBER_WIDTH && !STATUS_HEATERS_WIDTH + + #ifndef STATUS_CHAMBER_X + #define STATUS_CHAMBER_X (128 - (STATUS_FAN_BYTEWIDTH + STATUS_CHAMBER_BYTEWIDTH) * 8) + #endif + + #ifndef STATUS_CHAMBER_HEIGHT + #ifdef STATUS_CHAMBER_ANIM + #define STATUS_CHAMBER_HEIGHT(S) ((S) ? sizeof(status_chamber_on_bmp) / (STATUS_CHAMBER_BYTEWIDTH) : sizeof(status_chamber_bmp) / (STATUS_CHAMBER_BYTEWIDTH)) + #else + #define STATUS_CHAMBER_HEIGHT(S) (sizeof(status_chamber_bmp) / (STATUS_CHAMBER_BYTEWIDTH)) + #endif + #endif + + #ifndef STATUS_CHAMBER_Y + #define STATUS_CHAMBER_Y(S) (20 - STATUS_CHAMBER_HEIGHT(S)) + #endif + + #ifndef STATUS_CHAMBER_TEXT_X + #define STATUS_CHAMBER_TEXT_X (STATUS_CHAMBER_X + 7) + #endif + + static_assert( + sizeof(status_chamber_bmp) == (STATUS_CHAMBER_BYTEWIDTH) * (STATUS_CHAMBER_HEIGHT(0)), + "Status chamber bitmap (status_chamber_bmp) dimensions don't match data." + ); + #ifdef STATUS_CHAMBER_ANIM + static_assert( + sizeof(status_chamber_on_bmp) == (STATUS_CHAMBER_BYTEWIDTH) * (STATUS_CHAMBER_HEIGHT(1)), + "Status chamber bitmap (status_chamber_on_bmp) dimensions don't match data." + ); + #endif + +#endif + // // Bed Bitmap Properties // @@ -1314,7 +1415,7 @@ #if STATUS_BED_WIDTH && !STATUS_HEATERS_WIDTH #ifndef STATUS_BED_X - #define STATUS_BED_X (128 - (STATUS_FAN_BYTEWIDTH + STATUS_BED_BYTEWIDTH) * 8) + #define STATUS_BED_X (128 - (STATUS_CHAMBER_BYTEWIDTH + STATUS_FAN_BYTEWIDTH + STATUS_BED_BYTEWIDTH) * 8) #endif #ifndef STATUS_BED_HEIGHT diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp index a917bc2e84..15b551b48b 100644 --- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp +++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp @@ -33,6 +33,7 @@ #include "ultralcd_DOGM.h" #include "../ultralcd.h" #include "../lcdprint.h" +#include "../../libs/numtostr.h" #include "../../module/motion.h" #include "../../module/temperature.h" @@ -74,6 +75,7 @@ FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, cons #define DO_DRAW_FAN (HAS_FAN0 && STATUS_FAN_WIDTH && STATUS_FAN_FRAMES) #define ANIM_HOTEND (HOTENDS && ENABLED(STATUS_HOTEND_ANIM)) #define ANIM_BED (DO_DRAW_BED && ENABLED(STATUS_BED_ANIM)) +#define ANIM_CHAMBER (HAS_HEATED_CHAMBER && ENABLED(STATUS_CHAMBER_ANIM)) #if ANIM_HOTEND || ANIM_BED uint8_t heat_bits; @@ -88,6 +90,11 @@ FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, cons #else #define BED_ALT() false #endif +#if ANIM_CHAMBER + #define CHAMBER_ALT() TEST(heat_bits, 6) +#else + #define CHAMBER_ALT() false +#endif #define MAX_HOTEND_DRAW MIN(HOTENDS, ((LCD_PIXEL_WIDTH - (STATUS_LOGO_BYTEWIDTH + STATUS_FAN_BYTEWIDTH) * 8) / (STATUS_HEATERS_XSPACE))) #define STATUS_HEATERS_BOT (STATUS_HEATERS_Y + STATUS_HEATERS_HEIGHT - 1) @@ -126,6 +133,27 @@ FORCE_INLINE void _draw_heater_status(const int8_t heater, const bool blink) { target = IFBED(thermalManager.degTargetBed(), thermalManager.degTargetHotend(heater)); #endif + #if HAS_HEATED_CHAMBER + FORCE_INLINE void _draw_chamber_status(const bool blink) { + const float temp = thermalManager.degChamber(), + target = thermalManager.degTargetChamber(); + #if !HEATER_IDLE_HANDLER + UNUSED(blink); + #endif + if (PAGE_UNDER(7)) { + #if HEATER_IDLE_HANDLER + const bool is_idle = false, // thermalManager.chamber_idle.timed_out, + dodraw = (blink || !is_idle); + #else + constexpr bool dodraw = true; + #endif + if (dodraw) _draw_centered_temp(target + 0.5, STATUS_CHAMBER_TEXT_X, 7); + } + if (PAGE_CONTAINS(28 - INFO_FONT_ASCENT, 28 - 1)) + _draw_centered_temp(temp + 0.5f, STATUS_CHAMBER_TEXT_X, 28); + } + #endif + #if DISABLED(STATUS_HOTEND_ANIM) #define STATIC_HOTEND true #define HOTEND_DOT isHeat @@ -271,7 +299,7 @@ void MarlinUI::draw_status_screen() { // At the first page, generate new display values if (first_page) { - #if ANIM_HOTEND || ANIM_BED + #if ANIM_HOTEND || ANIM_BED || ANIM_CHAMBER uint8_t new_bits = 0; #if ANIM_HOTEND HOTEND_LOOP() if (thermalManager.isHeatingHotend(e) ^ SHOW_ON_STATE) SBI(new_bits, e); @@ -279,6 +307,9 @@ void MarlinUI::draw_status_screen() { #if ANIM_BED if (thermalManager.isHeatingBed() ^ SHOW_ON_STATE) SBI(new_bits, 7); #endif + #if ANIM_CHAMBER + if (thermalManager.isHeatingChamber() ^ SHOW_ON_STATE) SBI(new_bits, 6); + #endif heat_bits = new_bits; #endif strcpy(xstring, ftostr4sign(LOGICAL_X_POSITION(current_position[X_AXIS]))); @@ -326,6 +357,20 @@ void MarlinUI::draw_status_screen() { u8g.drawBitmapP(STATUS_BED_X, bedy, STATUS_BED_BYTEWIDTH, bedh, BED_BITMAP(BED_ALT())); #endif + #if DO_DRAW_CHAMBER + #if ANIM_HAMBER + #define CHAMBER_BITMAP(S) ((S) ? status_chamber_on_bmp : status_chamber_bmp) + #else + #define CHAMBER_BITMAP(S) status_chamber_bmp + #endif + if (PAGE_CONTAINS(STATUS_CHAMBER_Y, STATUS_CHAMBER_Y + STATUS_CHAMBER_HEIGHT - 1)) + u8g.drawBitmapP( + STATUS_CHAMBER_X, STATUS_CHAMBER_Y, + STATUS_CHAMBER_BYTEWIDTH, STATUS_CHAMBER_HEIGHT, + CHAMBER_BITMAP(CHAMBER_ALT()) + ); + #endif + #if DO_DRAW_FAN #if STATUS_FAN_FRAMES > 2 static bool old_blink; @@ -366,6 +411,10 @@ void MarlinUI::draw_status_screen() { _draw_heater_status(-1, blink); #endif + #if HAS_HEATED_CHAMBER + _draw_chamber_status(blink); + #endif + // Fan, if a bitmap was provided #if DO_DRAW_FAN if (PAGE_CONTAINS(STATUS_FAN_TEXT_Y - INFO_FONT_ASCENT, STATUS_FAN_TEXT_Y - 1)) { diff --git a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp index 8f295ab0fe..9e0850efb5 100644 --- a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp +++ b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp @@ -57,7 +57,7 @@ #include "../../inc/MarlinConfig.h" -#if HAS_GRAPHICAL_LCD +#if HAS_GRAPHICAL_LCD && PIN_EXISTS(FSMC_CS) #include "U8glib.h" #include "HAL_LCD_com_defines.h" diff --git a/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp index ff8bc33787..a2fb3f4711 100644 --- a/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp +++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp @@ -48,6 +48,7 @@ #include "../lcdprint.h" #include "../fontutils.h" +#include "../../libs/numtostr.h" #include "../ultralcd.h" #include "../../sd/cardreader.h" @@ -418,7 +419,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop onpage = PAGE_CONTAINS(baseline - (EDIT_FONT_ASCENT - 1), baseline); } if (onpage) { - lcd_moveto((lcd_chr_fit - (vallen + 1)) * one_chr_width, baseline); // Right-justified, leaving padded by spaces + lcd_moveto(((lcd_chr_fit - 1) - (vallen + 1)) * one_chr_width, baseline); // Right-justified, leaving padded by spaces lcd_put_wchar(' '); // overwrite char if value gets shorter lcd_put_u8str(value); } diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp new file mode 100644 index 0000000000..3601c95072 --- /dev/null +++ b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp @@ -0,0 +1,1090 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 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 . + * + */ + +/* DGUS implementation written by coldtobi in 2019 for Marlin */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD) + +#include "DGUSDisplay.h" +#include "DGUSVPVariable.h" +#include "DGUSDisplayDefinition.h" + +#include "../../ui_api.h" + +#include "../../../../Marlin.h" +#include "../../../../module/temperature.h" +#include "../../../../module/motion.h" +#include "../../../../gcode/queue.h" +#include "../../../../module/planner.h" +#include "../../../../sd/cardreader.h" +#include "../../../../libs/duration_t.h" +#include "../../../../module/printcounter.h" + +// Preamble... 2 Bytes, usually 0x5A 0xA5, but configurable +constexpr uint8_t DGUS_HEADER1 = 0x5A; +constexpr uint8_t DGUS_HEADER2 = 0xA5; + +constexpr uint8_t DGUS_CMD_WRITEVAR = 0x82; +constexpr uint8_t DGUS_CMD_READVAR = 0x83; + +#if ENABLED(DEBUG_DGUSLCD) + bool dguslcd_local_debug; // = false; +#endif + +uint16_t DGUSScreenVariableHandler::ConfirmVP; + +#if ENABLED(SDSUPPORT) + int16_t DGUSScreenVariableHandler::top_file = 0; + int16_t DGUSScreenVariableHandler::file_to_print = 0; + static ExtUI::FileList filelist; +#endif + +void (*DGUSScreenVariableHandler::confirm_action_cb)() = nullptr; + +//DGUSScreenVariableHandler ScreenHandler; + +DGUSLCD_Screens DGUSScreenVariableHandler::current_screen; +DGUSLCD_Screens DGUSScreenVariableHandler::past_screens[NUM_PAST_SCREENS]; +uint8_t DGUSScreenVariableHandler::update_ptr; +uint16_t DGUSScreenVariableHandler::skipVP; +bool DGUSScreenVariableHandler::ScreenComplete; + +//DGUSDisplay dgusdisplay; + +rx_datagram_state_t DGUSDisplay::rx_datagram_state = DGUS_IDLE; +uint8_t DGUSDisplay::rx_datagram_len = 0; +bool DGUSDisplay::Initialized = false; +bool DGUSDisplay::no_reentrance = false; + +#if DGUS_RX_BUFFER_SIZE > 256 + typedef uint16_t r_ring_buffer_pos_t; +#else + typedef uint8_t r_ring_buffer_pos_t; +#endif + +#if DGUS_TX_BUFFER_SIZE > 256 + typedef uint16_t t_ring_buffer_pos_t; +#else + typedef uint8_t t_ring_buffer_pos_t; +#endif + +class DGUSSerial { +public: + DGUSSerial(); + ~DGUSSerial(); + + r_ring_buffer_pos_t available(); + t_ring_buffer_pos_t GetTxBufferFree(); + void write(const uint8_t c); + + int read(); + + // ISR for Rx + void store_rxd_char(); + // ISR for Tx (UDRE vector) + void tx_udr_empty_irq(void); + + inline volatile bool is_rx_overrun() { + return dgus_rx_overrun; + } + + inline void reset_rx_overun() { + dgus_rx_overrun = false; + } + +private: + r_ring_buffer_pos_t atomic_read_rx_head(); + void atomic_set_rx_tail(r_ring_buffer_pos_t value); + r_ring_buffer_pos_t atomic_read_rx_tail(); + + volatile bool dgus_rx_overrun = false; + + struct ring_buffer_r { + volatile r_ring_buffer_pos_t head, tail; + unsigned char buffer[DGUS_RX_BUFFER_SIZE]; + } rx_buffer = { 0, 0, { 0 } }; + + struct ring_buffer_t { + volatile t_ring_buffer_pos_t head, tail; + unsigned char buffer[DGUS_TX_BUFFER_SIZE]; + } tx_buffer = { 0, 0, { 0 } }; + + #if DGUS_RX_BUFFER_SIZE > 256 + volatile bool rx_tail_value_not_stable = false; + volatile uint16_t rx_tail_value_backup = 0; + #endif + +}; + +static DGUSSerial dgusserial; + +// endianness swap +uint16_t swap16(const uint16_t value) { return (value & 0xffU) << 8U | (value >> 8U); } + +bool populate_VPVar(const uint16_t VP, DGUS_VP_Variable * const ramcopy) { + // DEBUG_ECHOPAIR("populate_VPVar ", VP); + const DGUS_VP_Variable *pvp = DGUSLCD_FindVPVar(VP); + // DEBUG_ECHOLNPAIR(" pvp ", (uint16_t )pvp); + if (!pvp) return false; + memcpy_P(ramcopy, pvp, sizeof(DGUS_VP_Variable)); + return true; +} + +void DGUSScreenVariableHandler::sendinfoscreen(const char* line1, const char* line2, const char* line3, const char* line4, bool l1inflash, bool l2inflash, bool l3inflash, bool l4inflash) { + DGUS_VP_Variable ramcopy; + if (populate_VPVar(VP_MSGSTR1, &ramcopy)) { + ramcopy.memadr = (void*) line1; + l1inflash ? DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay(ramcopy); + } + if (populate_VPVar(VP_MSGSTR2, &ramcopy)) { + ramcopy.memadr = (void*) line2; + l2inflash ? DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay(ramcopy); + } + if (populate_VPVar(VP_MSGSTR3, &ramcopy)) { + ramcopy.memadr = (void*) line3; + l3inflash ? DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay(ramcopy); + } + if (populate_VPVar(VP_MSGSTR4, &ramcopy)) { + ramcopy.memadr = (void*) line4; + l4inflash ? DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(ramcopy) : DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay(ramcopy); + } +} + +void DGUSScreenVariableHandler::HandleUserConfirmationPopUp(uint16_t VP, const char* line1, const char* line2, const char* line3, const char* line4, bool l1, bool l2, bool l3, bool l4) { + if (current_screen == DGUSLCD_SCREEN_CONFIRM) { + // Already showing a pop up, so we need to cancel that first. + PopToOldScreen(); + } + + ConfirmVP = VP; + sendinfoscreen(line1, line2, line3, line4, l1, l2, l3, l4); + ScreenHandler.GotoScreen(DGUSLCD_SCREEN_CONFIRM); +} + +void DGUSScreenVariableHandler::setstatusmessage(const char *msg) { + DGUS_VP_Variable ramcopy; + if (populate_VPVar(VP_M117, &ramcopy)) { + ramcopy.memadr = (void*) msg; + DGUSLCD_SendStringToDisplay(ramcopy); + } +} + +void DGUSScreenVariableHandler::setstatusmessagePGM(PGM_P const msg) { + DGUS_VP_Variable ramcopy; + if (populate_VPVar(VP_M117, &ramcopy)) { + ramcopy.memadr = (void*) msg; + DGUSLCD_SendStringToDisplayPGM(ramcopy); + } +} + +// Send an 8 bit or 16 bit value to the display. +void DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay(DGUS_VP_Variable &var) { + if (var.memadr) { + //DEBUG_ECHOPAIR(" DGUS_LCD_SendWordValueToDisplay ", var.VP); + //DEBUG_ECHOLNPAIR(" data ", *(uint16_t *)var.memadr); + uint8_t *tmp = (uint8_t *) var.memadr; + uint16_t data_to_send = (tmp[0] << 8); + if (var.size >= 1) data_to_send |= tmp[1]; + dgusdisplay.WriteVariable(var.VP, data_to_send); + } +} + +// Send an uint8_t between 0 and 255 to the display, but scale to a percentage (0..100) +void DGUSScreenVariableHandler::DGUSLCD_SendPercentageToDisplay(DGUS_VP_Variable &var) { + if (var.memadr) { + //DEBUG_ECHOPAIR(" DGUS_LCD_SendWordValueToDisplay ", var.VP); + //DEBUG_ECHOLNPAIR(" data ", *(uint16_t *)var.memadr); + uint16_t tmp = *(uint8_t *) var.memadr +1 ; // +1 -> avoid rounding issues for the display. + tmp = map(tmp, 0, 255, 0, 100); + uint16_t data_to_send = swap16(tmp); + dgusdisplay.WriteVariable(var.VP, data_to_send); + } +} + +// Send the current print time to the display. +// It is using a hex display for that: It expects BSD coded data in the format xxyyzz +void DGUSScreenVariableHandler::DGUSLCD_SendPrintTimeToDisplay(DGUS_VP_Variable &var) { + duration_t elapsed = print_job_timer.duration(); + + uint8_t days = elapsed.day(), + hours = elapsed.hour() % 24, + minutes = elapsed.minute() % 60, + seconds = elapsed.second() % 60; + + char buf[14], *p = buf; // that two extra bytes saves us some flash... + + if (days) { *p++ = days / 10 + '0'; *p++ = days % 10 + '0'; *p++ = 'd'; } + *p++ = hours / 10 + '0'; *p++ = hours % 10 + '0'; *p++ = 'h'; + *p++ = minutes / 10 + '0'; *p++ = minutes % 10 + '0'; *p++ = 'm'; + *p++ = seconds / 10 + '0'; *p++ = seconds % 10 + '0'; *p++ = 's'; + *p = '\0'; + + dgusdisplay.WriteVariable(VP_PrintTime, buf, var.size, true); +} + + + +// Send an uint8_t between 0 and 100 to a variable scale to 0..255 +void DGUSScreenVariableHandler::DGUSLCD_PercentageToUint8(DGUS_VP_Variable &var, void *val_ptr) { + if (var.memadr) { + uint16_t value = swap16(*(uint16_t*)val_ptr); + *(uint8_t*)var.memadr = map(constrain(value, 0, 100), 0, 100, 0, 255); + } +} + +// Sends a (RAM located) string to the DGUS Display +// (Note: The DGUS Display does not clear after the \0, you have to +// overwrite the remainings with spaces.// var.size has the display buffer size! +void DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay(DGUS_VP_Variable &var) { + char *tmp = (char*) var.memadr; + dgusdisplay.WriteVariable(var.VP, tmp, var.size, true); +} + +// Sends a (flash located) string to the DGUS Display +// (Note: The DGUS Display does not clear after the \0, you have to +// overwrite the remainings with spaces.// var.size has the display buffer size! +void DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(DGUS_VP_Variable &var) { + char *tmp = (char*) var.memadr; + dgusdisplay.WriteVariablePGM(var.VP, tmp, var.size, true); +} + +#if ENABLED(SDSUPPORT) + + void DGUSScreenVariableHandler::ScreenChangeHookIfSD(DGUS_VP_Variable &var, void *val_ptr) { + // default action executed when there is a SD card, but not printing + if (ExtUI::isMediaInserted() && !ExtUI::isPrintingFromMedia()) { + ScreenChangeHook(var, val_ptr); + dgusdisplay.RequestScreen(current_screen); + return; + } + + // if we are printing, we jump to two screens after the requested one. + // This should host e.g a print pause / print abort / print resume dialog. + // This concept allows to recycle this hook for other file + if (ExtUI::isPrintingFromMedia() && !card.flag.abort_sd_printing) { + GotoScreen(DGUSLCD_SCREEN_SDPRINTMANIPULATION); + return; + } + + // Don't let the user in the dark why there is no reaction. + if (!ExtUI::isMediaInserted()) { + setstatusmessagePGM(PSTR("No SD Card")); + return; + } + if (card.flag.abort_sd_printing) { + setstatusmessagePGM(PSTR("Aborting...")); + return; + } + } + + void DGUSScreenVariableHandler::DGUSLCD_SD_ScrollFilelist(DGUS_VP_Variable& var, void *val_ptr) { + auto old_top = top_file; + int16_t scroll = (int16_t)swap16(*(uint16_t*)val_ptr); + if (scroll == 0) { + if (!filelist.isAtRootDir()) { + filelist.upDir(); + top_file = 0; + ForceCompleteUpdate(); + } + } + else { + top_file += scroll; + DEBUG_ECHOPAIR("new topfile calculated:", top_file); + if (top_file < 0) { + top_file = 0; + DEBUG_ECHOLN("Top of filelist reached"); + } + else { + int16_t max_top = filelist.count() - DGUS_SD_FILESPERSCREEN; + NOLESS(max_top, 0); + NOMORE(top_file, max_top); + } + DEBUG_ECHOPAIR("new topfile adjusted:", top_file); + } + + if (old_top != top_file) ForceCompleteUpdate(); + } + + void DGUSScreenVariableHandler::DGUSLCD_SD_FileSelected(DGUS_VP_Variable &var, void *val_ptr) { + uint16_t touched_nr = (int16_t)swap16(*(uint16_t*)val_ptr) + top_file; + if (touched_nr > filelist.count()) return; + if (!filelist.seek(touched_nr)) return; + if (filelist.isDir()) { + filelist.changeDir(filelist.filename()); + top_file = 0; + ForceCompleteUpdate(); + return; + } + + // Setup Confirmation screen + file_to_print = touched_nr; + HandleUserConfirmationPopUp(VP_SD_FileSelectConfirm, nullptr, PSTR("Print file"), filelist.filename(), PSTR("from SD Card?"), true, true, false, true); + } + + void DGUSScreenVariableHandler::DGUSLCD_SD_StartPrint(DGUS_VP_Variable &var, void *val_ptr) { + if(!filelist.seek(file_to_print)) return; + ExtUI::printFile(filelist.filename()); + ScreenHandler.GotoScreen(DGUSLCD_SCREEN_STATUS); + } + + void DGUSScreenVariableHandler::DGUSLCD_SD_ResumePauseAbort(DGUS_VP_Variable &var, void *val_ptr) { + if (!ExtUI::isPrintingFromMedia()) return; // avoid race condition when user stays in this menu and printer finishes. + switch (swap16(*(uint16_t*)val_ptr)) { + case 0: // Resume + if (ExtUI::isPrintingFromMediaPaused()) ExtUI::resumePrint(); + break; + case 1: // Pause + if (!ExtUI::isPrintingFromMediaPaused()) ExtUI::pausePrint(); + break; + case 2: // Abort + ScreenHandler.HandleUserConfirmationPopUp(VP_SD_AbortPrintConfirmed, nullptr, PSTR("Abort printing"), filelist.filename(), PSTR("?"), true, true, false, true); + break; + } + } + + void DGUSScreenVariableHandler::DGUSLCD_SD_ReallyAbort(DGUS_VP_Variable &var, void *val_ptr) { + ExtUI::stopPrint(); + GotoScreen(DGUSLCD_SCREEN_MAIN); + } + + void DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename(DGUS_VP_Variable& var) { + uint16_t target_line = (var.VP - VP_SD_FileName0) / VP_SD_FileName_LEN; + if (target_line > DGUS_SD_FILESPERSCREEN) return; + char tmpfilename[VP_SD_FileName_LEN + 1] = ""; + var.memadr = (void*)tmpfilename; + if (filelist.seek(top_file + target_line)) + snprintf_P(tmpfilename, VP_SD_FileName_LEN, PSTR("%s%c"), filelist.filename(), filelist.isDir() ? '/' : 0); + DGUSLCD_SendStringToDisplay(var); + } + + + void DGUSScreenVariableHandler::SDCardInserted() { + top_file = 0; + auto cs = ScreenHandler.getCurrentScreen(); + if (cs == DGUSLCD_SCREEN_MAIN || cs == DGUSLCD_SCREEN_STATUS) + ScreenHandler.GotoScreen(DGUSLCD_SCREEN_SDFILELIST); + } + + void DGUSScreenVariableHandler::SDCardRemoved() { + if (current_screen == DGUSLCD_SCREEN_SDFILELIST + || (current_screen == DGUSLCD_SCREEN_CONFIRM && (ConfirmVP == VP_SD_AbortPrintConfirmed || ConfirmVP == VP_SD_FileSelectConfirm)) + || current_screen == DGUSLCD_SCREEN_SDPRINTMANIPULATION + ) ScreenHandler.GotoScreen(DGUSLCD_SCREEN_MAIN); + } + + void DGUSScreenVariableHandler::SDCardError() { + DGUSScreenVariableHandler::SDCardRemoved(); + ScreenHandler.sendinfoscreen(PSTR("NOTICE"), nullptr, PSTR("SD card error"), nullptr, true, true, true, true); + ScreenHandler.SetupConfirmAction(nullptr); + ScreenHandler.GotoScreen(DGUSLCD_SCREEN_POPUP); + } + +#endif // SDSUPPORT + +void DGUSScreenVariableHandler::ScreenConfirmedOK(DGUS_VP_Variable &var, void *val_ptr) { + DGUS_VP_Variable ramcopy; + if (!populate_VPVar(ConfirmVP, &ramcopy)) return; + if (ramcopy.set_by_display_handler) ramcopy.set_by_display_handler(ramcopy, val_ptr); +} + +const uint16_t* DGUSLCD_FindScreenVPMapList(uint8_t screen) { + const uint16_t *ret; + const struct VPMapping *map = VPMap; + while (ret = (uint16_t*) pgm_read_word(&(map->VPList))) { + if (pgm_read_byte(&(map->screen)) == screen) return ret; + map++; + } + return nullptr; +} + +const DGUS_VP_Variable* DGUSLCD_FindVPVar(const uint16_t vp) { + const DGUS_VP_Variable *ret = ListOfVP; + do { + const uint16_t vpcheck = pgm_read_word(&(ret->VP)); + if (vpcheck == 0) break; + if (vpcheck == vp) return ret; + ++ret; + } while (1); + + DEBUG_ECHOLNPAIR("FindVPVar NOT FOUND ", vp); + return nullptr; +} + +void DGUSScreenVariableHandler::ScreenChangeHookIfIdle(DGUS_VP_Variable &var, void *val_ptr) { + if (!ExtUI::isPrinting()) { + ScreenChangeHook(var, val_ptr); + dgusdisplay.RequestScreen(current_screen); + } +} + +void DGUSScreenVariableHandler::ScreenChangeHook(DGUS_VP_Variable &var, void *val_ptr) { + uint8_t *tmp = (uint8_t*)val_ptr; + + // The keycode in target is coded as , so 0x0100A means + // from screen 1 (main) to 10 (temperature). DGUSLCD_SCREEN_POPUP is special, + // meaning "return to previous screen" + DGUSLCD_Screens target = (DGUSLCD_Screens)tmp[1]; + + if (target == DGUSLCD_SCREEN_POPUP) { + // special handling for popup is to return to previous menu + if (current_screen == DGUSLCD_SCREEN_POPUP && confirm_action_cb) confirm_action_cb(); + PopToOldScreen(); + return; + } + + UpdateNewScreen(target); + + #ifdef DEBUG_DGUSLCD + if (!DGUSLCD_FindScreenVPMapList(target)) DEBUG_ECHOLNPAIR("WARNING: No screen Mapping found for ", x); + #endif +} + +void DGUSScreenVariableHandler::HandleAllHeatersOff(DGUS_VP_Variable &var, void *val_ptr) { + thermalManager.disable_all_heaters(); + ScreenHandler.ForceCompleteUpdate(); // hint to send all data. +} + +void DGUSScreenVariableHandler::HandleTemperatureChanged(DGUS_VP_Variable &var, void *val_ptr) { + uint16_t newvalue = swap16(*(uint16_t*)val_ptr); + uint16_t acceptedvalue; + + switch (var.VP) { + default: return; + #if HOTENDS >= 1 + case VP_T_E1_Set: + thermalManager.setTargetHotend(newvalue, 0); + acceptedvalue = thermalManager.temp_hotend[0].target; + break; + #endif + #if HOTENDS >= 2 + case VP_T_E2_Set: + thermalManager.setTargetHotend(newvalue, 1); + acceptedvalue = thermalManager.temp_hotend[1].target; + break; + #endif + #if HAS_HEATED_BED + case VP_T_Bed_Set: + thermalManager.setTargetBed(newvalue); + acceptedvalue = thermalManager.temp_bed.target; + break; + #endif + } + + // reply to display the new value to update the view if the new value was rejected by the Thermal Manager. + if (newvalue != acceptedvalue && var.send_to_display_handler) var.send_to_display_handler(var); + ScreenHandler.skipVP = var.VP; // don't overwrite value the next update time as the display might autoincrement in parallel +} + +void DGUSScreenVariableHandler::HandleFlowRateChanged(DGUS_VP_Variable &var, void *val_ptr) { + uint16_t newvalue = swap16(*(uint16_t*)val_ptr); + uint8_t target_extruder; + switch (var.VP) { + default: return; + #if (HOTENDS >= 1) + case VP_Flowrate_E1: target_extruder = 0; break; + #endif + #if (HOTENDS >= 2) + case VP_Flowrate_E2: target_extruder = 1; break; + #endif + } + + planner.flow_percentage[target_extruder] = newvalue; + planner.refresh_e_factor(target_extruder); + ScreenHandler.skipVP = var.VP; // don't overwrite value the next update time as the display might autoincrement in parallel +} + +void DGUSScreenVariableHandler::HandleManualExtrude(DGUS_VP_Variable &var, void *val_ptr) { + DEBUG_ECHOLNPGM("HandleManualMove"); + + int16_t movevalue = swap16(*(uint16_t*)val_ptr); + float target = movevalue * 0.01f; + ExtUI::extruder_t target_extruder; + + switch (var.VP) { + #if HOTENDS >=1 + case VP_MOVE_E1: target_extruder = ExtUI::extruder_t::E0; break; + #endif + #if HOTENDS >=2 + case VP_MOVE_E2: target_extruder = ExtUI::extruder_t::E1; break + #endif + default: return; + } + + target += ExtUI::getAxisPosition_mm(target_extruder); + ExtUI::setAxisPosition_mm(target, target_extruder); + skipVP = var.VP; +} + +void DGUSScreenVariableHandler::HandleManualMove(DGUS_VP_Variable &var, void *val_ptr) { + DEBUG_ECHOLNPGM("HandleManualMove"); + + int16_t movevalue = swap16(*(uint16_t*)val_ptr); + char axiscode; + unsigned int speed = 1500; //FIXME: get default feedrate for manual moves, dont hardcode. + + switch (var.VP) { + case VP_MOVE_X: + axiscode = 'X'; + if (!ExtUI::canMove(ExtUI::axis_t::X)) goto cannotmove; + break; + + case VP_MOVE_Y: + axiscode = 'Y'; + if (!ExtUI::canMove(ExtUI::axis_t::Y)) goto cannotmove; + break; + + case VP_MOVE_Z: + axiscode = 'Z'; + speed = 300; // default to 5mm/s + if (!ExtUI::canMove(ExtUI::axis_t::Z)) goto cannotmove; + break; + + case VP_HOME_ALL: // only used for homing + axiscode = '\0'; + movevalue = 0; // ignore value sent from display, this VP is _ONLY_ for homing. + break; + + default: return; + } + + if (!movevalue) { + // homing + DEBUG_ECHOPAIR(" homing ", axiscode); + char buf[6] = "G28 X"; + buf[4] = axiscode; + //DEBUG_ECHOPAIR(" ", buf); + while (!enqueue_and_echo_command(buf)) idle(); + //DEBUG_ECHOLN(" ✓"); + ScreenHandler.ForceCompleteUpdate(); + return; + } + else { + //movement + DEBUG_ECHOPAIR(" move ", axiscode); + bool old_relative_mode = relative_mode; + if (!relative_mode) { + //DEBUG_ECHO(" G91"); + while (!enqueue_and_echo_command("G91")) idle(); + //DEBUG_ECHOPGM(" ✓ "); + } + char buf[32]; // G1 X9999.99 F12345 + unsigned int backup_speed = MMS_TO_MMM(feedrate_mm_s); + char sign[]="\0"; + int16_t value = movevalue / 100; + if (movevalue < 0) { value = -value; sign[0] = '-'; } + int16_t fraction = ABS(movevalue) % 100; + snprintf_P(buf, 32, PSTR("G0 %c%s%d.%02d F%d"), axiscode, sign, value, fraction, speed); + //DEBUG_ECHOPAIR(" ", buf); + while (!enqueue_and_echo_command(buf)) idle(); + //DEBUG_ECHOLN(" ✓ "); + if (backup_speed != speed) { + snprintf_P(buf, 32, PSTR("G0 F%d"), backup_speed); + while (!enqueue_and_echo_command(buf)) idle(); + //DEBUG_ECHOPAIR(" ", buf); + } + //while (!enqueue_and_echo_command(buf)) idle(); + //DEBUG_ECHOLN(" ✓ "); + if (!old_relative_mode) { + //DEBUG_ECHO("G90"); + while (!enqueue_and_echo_command("G90")) idle(); + //DEBUG_ECHO(" ✓ "); + } + } + + ScreenHandler.ForceCompleteUpdate(); + DEBUG_ECHOLNPGM("manmv done."); + return; + + cannotmove: + DEBUG_ECHOLNPAIR(" cannot move ", axiscode); + return; +} + +void DGUSScreenVariableHandler::UpdateNewScreen(DGUSLCD_Screens newscreen, bool popup) { + DEBUG_ECHOLNPAIR("SetNewScreen: ", newscreen); + + if (!popup) { + memmove(&past_screens[1], &past_screens[0], sizeof(past_screens) - 1); + past_screens[0] = current_screen; + } + + current_screen = newscreen; + skipVP = 0; + ForceCompleteUpdate(); +} + +void DGUSScreenVariableHandler::PopToOldScreen() { + DEBUG_ECHOLNPAIR("PopToOldScreen s=", past_screens[0]); + GotoScreen(past_screens[0], true); + memmove(&past_screens[0], &past_screens[1], sizeof(past_screens) - 1); + past_screens[sizeof(past_screens) - 1] = DGUSLCD_SCREEN_MAIN; +} + +void DGUSScreenVariableHandler::UpdateScreenVPData() { + DEBUG_ECHOPAIR(" UpdateScreenVPData Screen: ", current_screen); + + const uint16_t *VPList = DGUSLCD_FindScreenVPMapList(current_screen); + if (!VPList) { + DEBUG_ECHOLNPAIR(" NO SCREEN FOR: ", current_screen); + ScreenComplete = true; + return; // nothing to do, likely a bug or boring screen. + } + + // Round-Robbin updating of all VPs. + VPList += update_ptr; + + bool sent_one = false; + do { + uint16_t VP = pgm_read_word(VPList); + DEBUG_ECHOPAIR(" VP: ", VP); + if (!VP) { + update_ptr = 0; + DEBUG_ECHOLNPGM(" UpdateScreenVPData done"); + ScreenComplete = true; + return; // Screen completed. + } + + if (VP == skipVP) { + skipVP = 0; + continue; + } + + DGUS_VP_Variable rcpy; + if (populate_VPVar(VP, &rcpy)) { + uint8_t expected_tx = 6 + rcpy.size; // expected overhead is 6 bytes + payload. + // Send the VP to the display, but try to avoid overruning the Tx Buffer. + // But send at least one VP, to avoid getting stalled. + if (rcpy.send_to_display_handler && (!sent_one || expected_tx <= dgusdisplay.GetFreeTxBuffer())) { + //DEBUG_ECHOPAIR(" calling handler for ", rcpy.VP); + sent_one = true; + rcpy.send_to_display_handler(rcpy); + } + else { + //auto x=dgusdisplay.GetFreeTxBuffer(); + //DEBUG_ECHOLNPAIR(" tx almost full: ", x); + //DEBUG_ECHOPAIR(" update_ptr ", update_ptr); + ScreenComplete = false; + return; // please call again! + } + } + + } while (++update_ptr, ++VPList, true); +} + +void DGUSDisplay::loop() { + // protection against recursion… ProcessRx() might call indirectly idle() when trying to injecting gcode commands if the queue is full. + if (!no_reentrance) { + no_reentrance = true; + ProcessRx(); + no_reentrance = false; + } +} + +void DGUSDisplay::InitDisplay() { + RequestScreen( + #if ENABLED(SHOW_BOOTSCREEN) + DGUSLCD_SCREEN_BOOT + #else + DGUSLCD_SCREEN_MAIN + #endif + ); +} + +void DGUSDisplay::WriteVariable(uint16_t adr, const void* values, uint8_t valueslen, bool isstr) { + const char* myvalues = static_cast(values); + bool strend = myvalues ? false : true; + WriteHeader(adr, DGUS_CMD_WRITEVAR, valueslen); + while (valueslen--) { + char x; + if (!strend) x = *myvalues++; + if ((isstr && !x) || strend) { + strend = true; + x = ' '; + } + dgusserial.write(x); + } +} + +void DGUSDisplay::WriteVariablePGM(uint16_t adr, const void* values, uint8_t valueslen, bool isstr) { + const char* myvalues = static_cast(values); + bool strend = myvalues ? false : true; + WriteHeader(adr, DGUS_CMD_WRITEVAR, valueslen); + while (valueslen--) { + char x; + if (!strend) x = pgm_read_byte(myvalues++); + if ((isstr && !x) || strend) { + strend = true; + x = ' '; + } + dgusserial.write(x); + } +} + +void DGUSScreenVariableHandler::GotoScreen(DGUSLCD_Screens screen, bool ispopup) { + dgusdisplay.RequestScreen(screen); + UpdateNewScreen(screen, ispopup); +} + +bool DGUSScreenVariableHandler::loop() { + dgusdisplay.loop(); + + const millis_t ms = millis(); + static millis_t next_event_ms = 0; + + if (!IsScreenComplete() || ELAPSED(ms, next_event_ms)) { + next_event_ms = ms + DGUS_UPDATE_INTERVAL_MS; + UpdateScreenVPData(); + } + + #if ENABLED(SHOW_BOOTSCREEN) + static bool booted = false; + if (!booted && ELAPSED(ms, BOOTSCREEN_TIMEOUT)) { + booted = true; + GotoScreen(DGUSLCD_SCREEN_MAIN); + } + #endif + return IsScreenComplete(); +} + +void DGUSDisplay::RequestScreen(DGUSLCD_Screens screen) { + DEBUG_ECHOLNPAIR("GotoScreen ", screen); + const unsigned char gotoscreen[] = { 0x5A, 0x01, (unsigned char) (screen >> 8U), (unsigned char) (screen & 0xFFU) }; + WriteVariable(0x84, gotoscreen, sizeof(gotoscreen)); +} + +void DGUSDisplay::ProcessRx() { + + if (!dgusserial.available() && dgusserial.is_rx_overrun()) { + // if we've got an overrun, but reset the flag only when we've emptied the buffer + // We want to extract as many as valid datagrams possible... + DEBUG_ECHOPGM("OVFL"); + rx_datagram_state = DGUS_IDLE; + dgusserial.reset_rx_overun(); + } + + uint8_t receivedbyte; + while (dgusserial.available()) { + switch (rx_datagram_state) { + + case DGUS_IDLE: // Waiting for the first header byte + receivedbyte = dgusserial.read(); + //DEBUG_ECHOPAIR("< ",x); + if (DGUS_HEADER1 == receivedbyte) rx_datagram_state = DGUS_HEADER1_SEEN; + break; + + case DGUS_HEADER1_SEEN: // Waiting for the second header byte + receivedbyte = dgusserial.read(); + //DEBUG_ECHOPAIR(" ",x); + rx_datagram_state = (DGUS_HEADER2 == receivedbyte) ? DGUS_HEADER2_SEEN : DGUS_IDLE; + break; + + case DGUS_HEADER2_SEEN: // Waiting for the length byte + rx_datagram_len = dgusserial.read(); + DEBUG_ECHOPAIR(" (", rx_datagram_len); + DEBUG_ECHOPGM(") "); + + // Telegram min len is 3 (command and one word of payload) + rx_datagram_state = WITHIN(rx_datagram_len, 3, DGUS_RX_BUFFER_SIZE) ? DGUS_WAIT_TELEGRAM : DGUS_IDLE; + break; + + case DGUS_WAIT_TELEGRAM: // wait for complete datagram to arrive. + if (dgusserial.available() < rx_datagram_len) return; + + Initialized = true; // We've talked to it, so we defined it as initialized. + uint8_t command = dgusserial.read(); + + DEBUG_ECHOPAIR("# ", command); + + uint8_t readlen = rx_datagram_len - 1; // command is part of len. + unsigned char tmp[rx_datagram_len - 1]; + unsigned char *ptmp = tmp; + while (readlen--) { + receivedbyte = dgusserial.read(); + DEBUG_ECHOPAIR(" ", receivedbyte); + *ptmp++ = receivedbyte; + } + DEBUG_ECHOPGM(" # "); + // mostly we'll get this: 5A A5 03 82 4F 4B -- ACK on 0x82, so discard it. + if (command == DGUS_CMD_WRITEVAR && 'O' == tmp[0] && 'K' == tmp[1]) { + DEBUG_ECHOLNPGM(">"); + rx_datagram_state = DGUS_IDLE; + break; + } + + /* AutoUpload, (and answer to) Command 0x83 : + | tmp[0 1 2 3 4 ... ] + | Example 5A A5 06 83 20 01 01 78 01 …… + | / / | | \ / | \ \ + | Header | | | | \_____\_ DATA (Words!) + | DatagramLen / VPAdr | + | Command DataLen (in Words) */ + if (command == DGUS_CMD_READVAR) { + const uint16_t vp = tmp[0] << 8 | tmp[1]; + const uint8_t dlen = tmp[2] << 1; // Convert to Bytes. (Display works with words) + //DEBUG_ECHOPAIR(" vp=", vp); DEBUG_ECHOPAIR(" dlen=", dlen); + DGUS_VP_Variable ramcopy; + if (populate_VPVar(vp, &ramcopy)) { + if (!(dlen == ramcopy.size || (dlen == 2 && ramcopy.size == 1))) + DEBUG_ECHOLNPGM("SIZE MISMATCH"); + else if (ramcopy.set_by_display_handler) { + ramcopy.set_by_display_handler(ramcopy, &tmp[3]); + } + else + DEBUG_ECHOLNPGM(" VPVar found, no handler."); + } + else + DEBUG_ECHOLNPAIR(" VPVar not found:", vp); + + rx_datagram_state = DGUS_IDLE; + break; + } + + // discard what we do not understand. + rx_datagram_state = DGUS_IDLE; + } + } +} + +size_t DGUSDisplay::GetFreeTxBuffer() { return dgusserial.GetTxBufferFree(); } + +void DGUSDisplay::WriteHeader(uint16_t adr, uint8_t cmd, uint8_t payloadlen) { + dgusserial.write(DGUS_HEADER1); + dgusserial.write(DGUS_HEADER2); + dgusserial.write(payloadlen + 3); + dgusserial.write(cmd); + dgusserial.write(adr >> 8); + dgusserial.write(adr & 0xFF); +} + +void DGUSDisplay::WritePGM(const char str[], uint8_t len) { + while (len--) dgusserial.write(pgm_read_byte(str++)); +} + +// Serial implementation stolen from MarlinSerial.cpp -- but functinality reduced to our use case +// (no XON/XOFF, no Emergency Parser, no error statistics, no support to send from interrupts ...) + +// Define all UART registers +#define _TNAME(X,Y,Z) X##Y##Z +#define TNAME(X,Y,Z) _TNAME(X,Y,Z) +#define DGUS_SERIAL_RX_VECT TNAME(USART,DGUS_SER_PORT,_RX_vect) +#define DGUS_SERIAL_UDRE_VECT TNAME(USART,DGUS_SER_PORT,_UDRE_vect) +#define DGUS_UCSRxA TNAME(UCSR,DGUS_SER_PORT,A) +#define DGUS_UCSRxB TNAME(UCSR,DGUS_SER_PORT,B) +#define DGUS_UCSRxC TNAME(UCSR,DGUS_SER_PORT,C) +#define DGUS_UBRRxH TNAME(UBRR,DGUS_SER_PORT,H) +#define DGUS_UBRRxL TNAME(UBRR,DGUS_SER_PORT,L) +#define DGUS_UDRx TNAME(UDR,DGUS_SER_PORT,) + +#define U2Xx TNAME(U2X,DGUS_SER_PORT,) +#define RXENx TNAME(RXEN,DGUS_SER_PORT,) +#define TXENx TNAME(TXEN,DGUS_SER_PORT,) +#define TXCx TNAME(TXC,DGUS_SER_PORT,) +#define RXCIEx TNAME(RXCIE,DGUS_SER_PORT,) +#define UDRIEx TNAME(UDRIE,DGUS_SER_PORT,) +#define UDREx TNAME(UDRE,DGUS_SER_PORT,) + +// A SW memory barrier, to ensure GCC does not overoptimize loops +#define sw_barrier() asm volatile("": : :"memory"); + +DGUSSerial::DGUSSerial() { + // Initialize UART + DGUS_UCSRxA = 1 << U2Xx; + const uint16_t baud_setting = (F_CPU / 4 / DGUS_BAUDRATE - 1) / 2; + DGUS_UBRRxH = baud_setting >> 8; + DGUS_UBRRxL = baud_setting; + DGUS_UCSRxC = 0x06; + DGUS_UCSRxB = 1 << RXCIEx | 1 << TXENx | 1 << RXENx; // Enable TX,RX and the RX interrupts. +} + +DGUSSerial::~DGUSSerial() { DGUS_UCSRxB = 0; } + +// "Atomically" read the RX head index value without disabling interrupts: +// This MUST be called with RX interrupts enabled, and CAN'T be called +// from the RX ISR itself! +FORCE_INLINE r_ring_buffer_pos_t DGUSSerial::atomic_read_rx_head() { + #if RX_BUFFER_SIZE > 256 + // Keep reading until 2 consecutive reads return the same value, + // meaning there was no update in-between caused by an interrupt. + // This works because serial RX interrupts happen at a slower rate + // than successive reads of a variable, so 2 consecutive reads with + // the same value means no interrupt updated it. + r_ring_buffer_pos_t vold, vnew = rx_buffer.head; + sw_barrier(); + do { + vold = vnew; + vnew = rx_buffer.head; + sw_barrier(); + } while (vold != vnew); + return vnew; + #else + // With an 8bit index, reads are always atomic. No need for special handling + return rx_buffer.head; + #endif +} + +// Set RX tail index, taking into account the RX ISR could interrupt +// the write to this variable in the middle - So a backup strategy +// is used to ensure reads of the correct values. +// -Must NOT be called from the RX ISR - +FORCE_INLINE void DGUSSerial::atomic_set_rx_tail(r_ring_buffer_pos_t value) { + #if RX_BUFFER_SIZE > 256 + // Store the new value in the backup + rx_tail_value_backup = value; + sw_barrier(); + // Flag we are about to change the true value + rx_tail_value_not_stable = true; + sw_barrier(); + // Store the new value + rx_buffer.tail = value; + sw_barrier(); + // Signal the new value is completely stored into the value + rx_tail_value_not_stable = false; + sw_barrier(); + #else + rx_buffer.tail = value; + #endif +} + +// Get the RX tail index, taking into account the read could be +// interrupting in the middle of the update of that index value +// -Called from the RX ISR - +FORCE_INLINE r_ring_buffer_pos_t DGUSSerial::atomic_read_rx_tail() { + #if RX_BUFFER_SIZE > 256 + // If the true index is being modified, return the backup value + if (rx_tail_value_not_stable) return rx_tail_value_backup; + #endif + // The true index is stable, return it + return rx_buffer.tail; +} + +// (called with RX interrupts disabled) +FORCE_INLINE void DGUSSerial::store_rxd_char() { + // Get the tail - Nothing can alter its value while this ISR is executing, but there's + // a chance that this ISR interrupted the main process while it was updating the index. + // The backup mechanism ensures the correct value is always returned. + const r_ring_buffer_pos_t t = atomic_read_rx_tail(); + + // Get the head pointer - This ISR is the only one that modifies its value, so it's safe to read here + r_ring_buffer_pos_t h = rx_buffer.head; + + // Get the next element + r_ring_buffer_pos_t i = (r_ring_buffer_pos_t) (h + 1) & (r_ring_buffer_pos_t) (DGUS_RX_BUFFER_SIZE - 1); + + // Read the character from the USART + uint8_t c = DGUS_UDRx; + + // If the character is to be stored at the index just before the tail + // (such that the head would advance to the current tail), the RX FIFO is + // full, so don't write the character or advance the head. + if (i != t) { + rx_buffer.buffer[h] = c; + h = i; + } + else + dgus_rx_overrun = true; + + // Store the new head value - The main loop will retry until the value is stable + rx_buffer.head = h; +} + +// (called with TX irqs disabled) +FORCE_INLINE void DGUSSerial::tx_udr_empty_irq(void) { + // Read positions + uint8_t t = tx_buffer.tail; + const uint8_t h = tx_buffer.head; + // If nothing to transmit, just disable TX interrupts. This could + // happen as the result of the non atomicity of the disabling of RX + // interrupts that could end reenabling TX interrupts as a side effect. + if (h == t) { + CBI(DGUS_UCSRxB, UDRIEx); // (Non-atomic, could be reenabled by the main program, but eventually this will succeed) + return; + } + + // There is something to TX, Send the next byte + const uint8_t c = tx_buffer.buffer[t]; + t = (t + 1) & (DGUS_TX_BUFFER_SIZE - 1); + DGUS_UDRx = c; + tx_buffer.tail = t; + + // Clear the TXC bit (by writing a one to its bit location). + // Ensures flush() won't return until the bytes are actually written/ + SBI(DGUS_UCSRxA, TXCx); + + // Disable interrupts if there is nothing to transmit following this byte + if (h == t) CBI(DGUS_UCSRxB, UDRIEx); +} + +r_ring_buffer_pos_t DGUSSerial::available(void) { + const r_ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail; + return (r_ring_buffer_pos_t) (DGUS_RX_BUFFER_SIZE + h - t) & (DGUS_RX_BUFFER_SIZE - 1); +} + +int DGUSSerial::read() { + const r_ring_buffer_pos_t h = atomic_read_rx_head(); + + // Read the tail. Main thread owns it, so it is safe to directly read it + r_ring_buffer_pos_t t = rx_buffer.tail; + + // If nothing to read, return now + if (h == t) return -1; + + // Get the next char + const int v = rx_buffer.buffer[t]; + t = (r_ring_buffer_pos_t) (t + 1) & (DGUS_RX_BUFFER_SIZE - 1); + + // Advance tail - Making sure the RX ISR will always get an stable value, even + // if it interrupts the writing of the value of that variable in the middle. + atomic_set_rx_tail(t); + return v; +} + +void DGUSSerial::write(const uint8_t c) { + // are we currently tranmitting? If not, we can just place the byte in UDR. + if (!TEST(DGUS_UCSRxB, UDRIEx) && TEST(DGUS_UCSRxA, UDREx)) { + DGUS_UDRx = c; + SBI(DGUS_UCSRxA, TXCx); + return; + } + + const uint8_t i = (tx_buffer.head + 1) & (DGUS_TX_BUFFER_SIZE - 1); + while (i == tx_buffer.tail) sw_barrier(); + + // Store new char. head is always safe to move + tx_buffer.buffer[tx_buffer.head] = c; + tx_buffer.head = i; + SBI(DGUS_UCSRxB, UDRIEx); // Enable Interrupts to finish off. +} + +t_ring_buffer_pos_t DGUSSerial::GetTxBufferFree() { + const t_ring_buffer_pos_t t = tx_buffer.tail, // next byte to send. + h = tx_buffer.head; // next pos for queue. + int ret = t - h - 1; + if (ret < 0) ret += DGUS_TX_BUFFER_SIZE + 1; + return ret; +} + +ISR(DGUS_SERIAL_UDRE_VECT) { dgusserial.tx_udr_empty_irq(); } +ISR(DGUS_SERIAL_RX_VECT) { dgusserial.store_rxd_char(); } + +#endif // DGUS_LCD diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.h b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.h new file mode 100644 index 0000000000..4488a58f4e --- /dev/null +++ b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.h @@ -0,0 +1,236 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/* DGUS implementation written by coldtobi in 2019 for Marlin */ + +#include "../../../../inc/MarlinConfigPre.h" + +#include "../../../../Marlin.h" +#include "DGUSVPVariable.h" + +enum DGUSLCD_Screens : uint8_t; + +#define DEBUG_OUT ENABLED(DEBUG_DGUSLCD) +#include "../../../../core/debug_out.h" + +typedef enum : uint8_t { + DGUS_IDLE, //< waiting for DGUS_HEADER1. + DGUS_HEADER1_SEEN, //< DGUS_HEADER1 received + DGUS_HEADER2_SEEN, //< DGUS_HEADER2 received + DGUS_WAIT_TELEGRAM, //< LEN received, Waiting for to receive all bytes. +} rx_datagram_state_t; + +// Low-Level access to the display. +class DGUSDisplay { +public: + + DGUSDisplay() = default; + + static void InitDisplay(); + + // Variable access. + static void WriteVariable(uint16_t adr, const void* values, uint8_t valueslen, bool isstr=false); + static void WriteVariablePGM(uint16_t adr, const void* values, uint8_t valueslen, bool isstr=false); + template + static void WriteVariable(uint16_t adr, T value) { + WriteVariable(adr, static_cast(&value), sizeof(T)); + } + + // Until now I did not need to actively read from the display. That's why there is no ReadVariable + // (I extensively use the auto upload of the display) + + // Force display into another screen. + // (And trigger update of containing VPs) + // (to implement a pop up message, which may not be nested) + static void RequestScreen(DGUSLCD_Screens screen); + + // Periodic tasks, eg. Rx-Queue handling. + static void loop(); + +public: + // Helper for users of this class to estimate if an interaction would be blocking. + static size_t GetFreeTxBuffer(); + + // Checks two things: Can we confirm the presence of the display and has we initiliazed it. + // (both boils down that the display answered to our chatting) + static inline bool isInitialized() { return Initialized; } + +private: + static void WriteHeader(uint16_t adr, uint8_t cmd, uint8_t payloadlen); + static void WritePGM(const char str[], uint8_t len); + static void ProcessRx(); + + static rx_datagram_state_t rx_datagram_state; + static uint8_t rx_datagram_len; + static bool Initialized, no_reentrance; +}; + +extern DGUSDisplay dgusdisplay; + +// compile-time x^y +constexpr float cpow(const float x, const int y) { return y == 0 ? 1.0 : x * cpow(x, y - 1); } + +class DGUSScreenVariableHandler { +public: + DGUSScreenVariableHandler() = default; + + static bool loop(); + + /// Send all 4 strings that are displayed on the infoscreen, confirmation screen and kill screen + /// The bools specifing whether the strings are in RAM or FLASH. + static void sendinfoscreen(const char* line1, const char* line2, const char* line3, const char* line4, bool l1inflash, bool l2inflash, bool l3inflash, bool liinflash); + + static void HandleUserConfirmationPopUp(uint16_t ConfirmVP, const char* line1, const char* line2, const char* line3, const char* line4, bool l1inflash, bool l2inflash, bool l3inflash, bool liinflash); + + /// "M117" Message -- msg is a RAM ptr. + static void setstatusmessage(const char* msg); + /// The same for messages from Flash + static void setstatusmessagePGM(PGM_P const msg); + // Callback for VP "Display wants to change screen on idle printer" + static void ScreenChangeHookIfIdle(DGUS_VP_Variable &var, void *val_ptr); + // Callback for VP "Screen has been changed" + static void ScreenChangeHook(DGUS_VP_Variable &var, void *val_ptr); + // Callback for VP "All Heaters Off" + static void HandleAllHeatersOff(DGUS_VP_Variable &var, void *val_ptr); + // Hook for "Change this temperature" + static void HandleTemperatureChanged(DGUS_VP_Variable &var, void *val_ptr); + // Hook for "Change Flowrate" + static void HandleFlowRateChanged(DGUS_VP_Variable &var, void *val_ptr); + // Hook for manual move. + static void HandleManualMove(DGUS_VP_Variable &var, void *val_ptr); + // Hook for manual extrude. + static void HandleManualExtrude(DGUS_VP_Variable &var, void *val_ptr); + + #if ENABLED(SDSUPPORT) + // Callback for VP "Display wants to change screen when there is a SD card" + static void ScreenChangeHookIfSD(DGUS_VP_Variable &var, void *val_ptr); + /// Scroll buttons on the file listing screen. + static void DGUSLCD_SD_ScrollFilelist(DGUS_VP_Variable &var, void *val_ptr); + /// File touched. + static void DGUSLCD_SD_FileSelected(DGUS_VP_Variable &var, void *val_ptr); + /// start print after confirmation received. + static void DGUSLCD_SD_StartPrint(DGUS_VP_Variable &var, void *val_ptr); + /// User hit the pause, resume or abort button. + static void DGUSLCD_SD_ResumePauseAbort(DGUS_VP_Variable &var, void *val_ptr); + /// User confirmed the abort action + static void DGUSLCD_SD_ReallyAbort(DGUS_VP_Variable &var, void *val_ptr); + /// Send a single filename to the display. + static void DGUSLCD_SD_SendFilename(DGUS_VP_Variable &var); + /// Marlin informed us that a new SD has been inserted. + static void SDCardInserted(); + /// Marlin informed us that the SD Card has been removed(). + static void SDCardRemoved(); + /// Marlin informed us about a bad SD Card. + static void SDCardError(); + #endif + + // OK Button the Confirm screen. + static void ScreenConfirmedOK(DGUS_VP_Variable &var, void *val_ptr); + + // Update data after went to new screen (by display or by GotoScreen) + // remember: store the last-displayed screen, so it can get returned to. + // (e.g for pop up messages) + static void UpdateNewScreen(DGUSLCD_Screens newscreen, bool popup=false); + + // Recall the remembered screen. + static void PopToOldScreen(); + + // Make the display show the screen and update all VPs in it. + static void GotoScreen(DGUSLCD_Screens screen, bool ispopup = false); + + static void UpdateScreenVPData(); + + // Helpers to convert and transfer data to the display. + static void DGUSLCD_SendWordValueToDisplay(DGUS_VP_Variable &var); + static void DGUSLCD_SendStringToDisplay(DGUS_VP_Variable &var); + static void DGUSLCD_SendStringToDisplayPGM(DGUS_VP_Variable &var); + static void DGUSLCD_SendPercentageToDisplay(DGUS_VP_Variable &var); + static void DGUSLCD_SendPrintTimeToDisplay(DGUS_VP_Variable &var); + + /// Send a value from 0..100 to a variable with a range from 0..255 + static void DGUSLCD_PercentageToUint8(DGUS_VP_Variable &var, void *val_ptr); + + template + static void DGUSLCD_SetValueDirectly(DGUS_VP_Variable &var, void *val_ptr) { + if (!var.memadr) return; + union { unsigned char tmp[sizeof(T)]; T t; } x; + unsigned char *ptr = (unsigned char*)val_ptr; + for (uint8_t i = 0; i < sizeof(T); i++) x.tmp[i] = ptr[sizeof(T) - i - 1]; + *(T*)var.memadr = x.t; + } + + /// Send a float value to the display. + /// Display will get a 4-byte integer scaled to the number of digits: + /// Tell the display the number of digits and it cheats by displaying a dot between... + template + static void DGUSLCD_SendFloatAsLongValueToDisplay(DGUS_VP_Variable &var) { + if (var.memadr) { + float f = *(float *)var.memadr; + f *= cpow(10, decimals); + union { long l; char lb[4]; } endian; + + char tmp[4]; + endian.l = f; + tmp[0] = endian.lb[3]; + tmp[1] = endian.lb[2]; + tmp[2] = endian.lb[1]; + tmp[3] = endian.lb[0]; + dgusdisplay.WriteVariable(var.VP, tmp, 4); + } + } + + /// Force an update of all VP on the current screen. + static inline void ForceCompleteUpdate() { update_ptr = 0; ScreenComplete = false; } + /// Has all VPs sent to the screen + static inline bool IsScreenComplete() { return ScreenComplete; } + + static inline DGUSLCD_Screens getCurrentScreen() { return current_screen; } + + static inline void SetupConfirmAction( void (*f)()) { confirm_action_cb = f; } + +private: + static DGUSLCD_Screens current_screen; ///< currently on screen + static constexpr uint8_t NUM_PAST_SCREENS = 4; + static DGUSLCD_Screens past_screens[NUM_PAST_SCREENS]; ///< LIFO with past screens for the "back" button. + + static uint8_t update_ptr; ///< Last sent entry in the VPList for the actual screen. + static uint16_t skipVP; ///< When updating the screen data, skip this one, because the user is interacting with it. + static bool ScreenComplete; ///< All VPs sent to screen? + + static uint16_t ConfirmVP; ///< context for confirm screen (VP that will be emulated-sent on "OK"). + + #if ENABLED(SDSUPPORT) + static int16_t top_file; ///< file on top of file chooser + static int16_t file_to_print; ///< touched file to be confirmed + #endif + + static void (*confirm_action_cb)(); +}; + +extern DGUSScreenVariableHandler ScreenHandler; + +/// Find the flash address of a DGUS_VP_Variable for the VP. +extern const DGUS_VP_Variable* DGUSLCD_FindVPVar(const uint16_t vp); + +/// Helper to populate a DGUS_VP_Variable for a given VP. Return false if not found. +extern bool populate_VPVar(const uint16_t VP, DGUS_VP_Variable * const ramcopy); diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.cpp b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.cpp new file mode 100644 index 0000000000..fdc8db67a9 --- /dev/null +++ b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.cpp @@ -0,0 +1,231 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 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 . + * + */ + +/* DGUS implementation written by coldtobi in 2019 for Marlin */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD) + +#include "DGUSDisplayDefinition.h" +#include "DGUSDisplay.h" + +#include "../../../../module/temperature.h" +#include "../../../../module/motion.h" + +#include "../../../ultralcd.h" + +const uint16_t VPList_Boot[] PROGMEM = { + VP_MARLIN_VERSION, + 0x0000 +}; + +const uint16_t VPList_Main[] PROGMEM = { + /* VP_M117, for completeness, but it cannot be auto-uploaded. */ + 0x0000 +}; + +const uint16_t VPList_Temp[] PROGMEM = { + #if HOTENDS >= 1 + VP_T_E1_Is, VP_T_E1_Set, + #endif + #if HOTENDS >= 2 + VP_T_E2_I, VP_T_E2_S, + #endif + #if HAS_HEATED_BED + VP_T_Bed_Is, VP_T_Bed_Set, + #endif + 0x0000 +}; + +const uint16_t VPList_Status[] PROGMEM = { + /* VP_M117, for completeness, but it cannot be auto-uploaded */ + #if HOTENDS >= 1 + VP_T_E1_Is, VP_T_E1_Set, + #endif + #if HOTENDS >= 2 + VP_T_E2_I, VP_T_E2_S, + #endif + #if HAS_HEATED_BED + VP_T_Bed_Is, VP_T_Bed_Set, + #endif + #if FAN_COUNT > 0 + VP_Fan_Percentage, + #endif + VP_XPos, VP_YPos, VP_ZPos, + VP_Fan_Percentage, + VP_Feedrate_Percentage, + VP_PrintProgress_Percentage, + 0x0000 +}; + +const uint16_t VPList_Status2[] PROGMEM = { + /* VP_M117, for completeness, but it cannot be auto-uploaded */ + #if HOTENDS >= 1 + VP_Flowrate_E1, + #endif + #if HOTENDS >= 2 + VP_Flowrate_E2, + #endif + VP_PrintProgress_Percentage, + VP_PrintTime, + 0x0000 +}; + +const uint16_t VPList_ManualMove[] PROGMEM = { + VP_XPos, VP_YPos, VP_ZPos, + 0x0000 +}; + +const uint16_t VPList_ManualExtrude[] PROGMEM = { + VP_EPos, + 0x0000 +}; + +const uint16_t VPList_FanAndFeedrate[] PROGMEM = { + VP_Feedrate_Percentage, VP_Fan_Percentage, + 0x0000 +}; + +const uint16_t VPList_SD_FlowRates[] PROGMEM = { + VP_Flowrate_E1, VP_Flowrate_E2, + 0x0000 +}; + +const uint16_t VPList_SDFileList[] PROGMEM = { + VP_SD_FileName0, VP_SD_FileName1, VP_SD_FileName2, VP_SD_FileName3, VP_SD_FileName4, + 0x0000 +}; + +const uint16_t VPList_SD_PrintManipulation[] PROGMEM = { + VP_PrintProgress_Percentage, VP_PrintTime, + 0x0000 +}; + +const struct VPMapping VPMap[] PROGMEM = { + { DGUSLCD_SCREEN_BOOT, VPList_Boot }, + { DGUSLCD_SCREEN_MAIN, VPList_Main }, + { DGUSLCD_SCREEN_TEMPERATURE, VPList_Temp }, + { DGUSLCD_SCREEN_STATUS, VPList_Status }, + { DGUSLCD_SCREEN_STATUS2, VPList_Status2 }, + { DGUSLCD_SCREEN_MANUALMOVE, VPList_ManualMove }, + { DGUSLCD_SCREEN_MANUALEXTRUDE, VPList_ManualExtrude }, + { DGUSLCD_SCREEN_FANANDFEEDRATE, VPList_FanAndFeedrate }, + { DGUSLCD_SCREEN_FLOWRATES, VPList_SD_FlowRates }, + { DGUSLCD_SCREEN_SDPRINTMANIPULATION, VPList_SD_PrintManipulation }, + { DGUSLCD_SCREEN_SDFILELIST, VPList_SDFileList }, + { 0 , nullptr } // List is terminated with an nullptr as table entry. +}; + +const char MarlinVersion[] PROGMEM = SHORT_BUILD_VERSION; + +// Helper to define a DGUS_VP_Variable for common use cases. +#define VPHELPER(VPADR, VPADRVAR, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=sizeof(VPADRVAR), \ + .set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR } + +// Helper to define a DGUS_VP_Variable when the sizeo of the var cannot be determined automaticalyl (eg. a string) +#define VPHELPER_STR(VPADR, VPADRVAR, STRLEN, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=STRLEN, \ + .set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR } + +const struct DGUS_VP_Variable ListOfVP[] PROGMEM = { + // Helper to detect touch events + VPHELPER(VP_SCREENCHANGE, nullptr, DGUSScreenVariableHandler::ScreenChangeHook, nullptr), + VPHELPER(VP_SCREENCHANGE_ASK, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfIdle, nullptr), + VPHELPER(VP_SCREENCHANGE_WHENSD, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfSD, nullptr), + VPHELPER(VP_CONFIRMED, nullptr, DGUSScreenVariableHandler::ScreenConfirmedOK, nullptr), + + VPHELPER(VP_TEMP_ALL_OFF, nullptr, &DGUSScreenVariableHandler::HandleAllHeatersOff, nullptr), + + VPHELPER(VP_MOVE_X, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Y, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), + VPHELPER(VP_MOVE_Z, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), + VPHELPER(VP_HOME_ALL, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr), + + { .VP = VP_MARLIN_VERSION, .memadr = (void*)MarlinVersion, .size = VP_MARLIN_VERSION_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, + // M117 LCD String (We don't need the string in memory but "just" push it to the display on demand, hence the nullptr + { .VP = VP_M117, .memadr = nullptr, .size = VP_M117_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay }, + + // Temperature Data + #if HOTENDS >= 1 + VPHELPER(VP_T_E1_Is, &thermalManager.temp_hotend[0].current, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>), + VPHELPER(VP_T_E1_Set, &thermalManager.temp_hotend[0].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_Flowrate_E1, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_EPos, &destination[3], nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_MOVE_E1, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr), + #endif + #if HOTENDS >= 2 + VPHELPER(VP_T_E2_I, &thermalManager.temp_hotend[1].current, nullptr, DGUSLCD_SendFloatAsLongValueToDisplay<0>), + VPHELPER(VP_T_E2_S, &thermalManager.temp_hotend[1].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_Flowrate_E2, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), + VPHELPER(VP_MOVE_E2, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr), + #endif + #if HOTENDS >= 3 + #error More than 2 Hotends currently not implemented on the Display UI design. + #endif + #if HAS_HEATED_BED + VPHELPER(VP_T_Bed_Is, &thermalManager.temp_bed.current, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>), + VPHELPER(VP_T_Bed_Set, &thermalManager.temp_bed.target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay), + #endif + + // Fan Data. + #if FAN_COUNT > 0 + VPHELPER(VP_Fan_Percentage, &thermalManager.fan_speed[0], DGUSScreenVariableHandler::DGUSLCD_PercentageToUint8, &DGUSScreenVariableHandler::DGUSLCD_SendPercentageToDisplay), + #endif + + // Feedrate. + VPHELPER(VP_Feedrate_Percentage, &feedrate_percentage, DGUSScreenVariableHandler::DGUSLCD_SetValueDirectly, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ), + + // Position Data. + VPHELPER(VP_XPos, ¤t_position[0], nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_YPos, ¤t_position[1], nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), + VPHELPER(VP_ZPos, ¤t_position[2], nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>), + + // Print Progress. + VPHELPER(VP_PrintProgress_Percentage, &MarlinUI::progress_bar_percent, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ), + + // Print Time + VPHELPER_STR(VP_PrintTime, nullptr, VP_PrintTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintTimeToDisplay ), + + // SDCard File listing. + #if ENABLED(SDSUPPORT) + VPHELPER(VP_SD_ScrollEvent, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ScrollFilelist, nullptr), + VPHELPER(VP_SD_FileSelected, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_FileSelected, nullptr), + VPHELPER(VP_SD_FileSelectConfirm, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_StartPrint, nullptr), + VPHELPER_STR(VP_SD_FileName0, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName1, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName2, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName3, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), + VPHELPER_STR(VP_SD_FileName4, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ), + VPHELPER(VP_SD_ResumePauseAbort, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ResumePauseAbort, nullptr), + VPHELPER(VP_SD_AbortPrintConfirmed, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ReallyAbort, nullptr), + #endif + + // Messages for the User, shared by the popup and the kill screen. They cant be autouploaded as we do not buffer content. + { .VP = VP_MSGSTR1, .memadr = nullptr, .size = VP_MSGSTR1_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR2, .memadr = nullptr, .size = VP_MSGSTR2_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR3, .memadr = nullptr, .size = VP_MSGSTR3_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, + { .VP = VP_MSGSTR4, .memadr = nullptr, .size = VP_MSGSTR4_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM }, + + VPHELPER(0, 0, 0, 0) // must be last entry. +}; + +#endif // DGUS_LCD diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.h b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.h new file mode 100644 index 0000000000..877f6ee86c --- /dev/null +++ b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.h @@ -0,0 +1,192 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/* DGUS implementation written by coldtobi in 2019 for Marlin */ + +#include "DGUSVPVariable.h" + +// This file defines the interaction between Marlin and the display firmware. + +// information on which screen which VP is displayed +// As this is a sparse table, two arrays are needed: +// one to list the VPs of one screen and one to map screens to the lists. +// (Strictly this would not be necessary, but allows to only send data the display needs and reducing load on Marlin) +struct VPMapping { + const uint8_t screen; + const uint16_t *VPList; // The list is null-terminated. +}; + +extern const struct VPMapping VPMap[]; + +enum DGUSLCD_Screens : uint8_t { + DGUSLCD_SCREEN_BOOT = 0, + DGUSLCD_SCREEN_MAIN = 10, + DGUSLCD_SCREEN_TEMPERATURE = 20, + DGUSLCD_SCREEN_STATUS = 30, + DGUSLCD_SCREEN_STATUS2 = 32, + DGUSLCD_SCREEN_MANUALMOVE = 40, + DGUSLCD_SCREEN_MANUALEXTRUDE=42, + DGUSLCD_SCREEN_FANANDFEEDRATE = 44, + DGUSLCD_SCREEN_FLOWRATES = 46, + DGUSLCD_SCREEN_SDFILELIST = 50, + DGUSLCD_SCREEN_SDPRINTMANIPULATION = 52, + DGUSLCD_SCREEN_CONFIRM = 240, + DGUSLCD_SCREEN_KILL = 250, ///< Kill Screen. Must always be 250 (to be able to display "Error wrong LCD Version") + DGUSLCD_SCREEN_POPUP = 252, ///< special target, popup screen will also return this code to say "return to previous screen" + DGUSLDC_SCREEN_UNUSED = 255 +}; + +// Display Memory layout used (T5UID) +// Except system variables this is arbitrary, just to organize stuff.... + +// 0x0000 .. 0x0FFF -- System variables and reserved by the display +// 0x1000 .. 0x1FFF -- Variables to never change location, regardless of UI Version +// 0x2000 .. 0x2FFF -- Controls (VPs that will trigger some action) +// 0x3000 .. 0x4FFF -- Marlin Data to be displayed +// 0x5000 .. -- SPs (if we want to modify display elements, e.g change color or like) -- currently unused + +// As there is plenty of space (at least most displays have >8k RAM), we do not pack them too tight, +// so that we can keep variables nicely together in the address space. + +// UI Version always on 0x1000...0x1002 so that the firmware can check this and bail out. +constexpr uint16_t VP_UI_VERSION_MAJOR = 0x1000; // Major -- incremented when incompatible +constexpr uint16_t VP_UI_VERSION_MINOR = 0x1001; // Minor -- incremented on new features, but compatible +constexpr uint16_t VP_UI_VERSION_PATCH = 0x1002; // Patch -- fixed which do not change functionality. +constexpr uint16_t VP_UI_FLAVOUR = 0x1010; // lets reserve 16 bytes here to determine if UI is suitable for this Marlin. tbd. + +// Storage space for the Killscreen messages. 0x1100 - 0x1200 . Reused for the popup. +constexpr uint16_t VP_MSGSTR1 = 0x1100; +constexpr uint8_t VP_MSGSTR1_LEN = 0x20; // might be more place for it... +constexpr uint16_t VP_MSGSTR2 = 0x1140; +constexpr uint8_t VP_MSGSTR2_LEN = 0x20; +constexpr uint16_t VP_MSGSTR3 = 0x1180; +constexpr uint8_t VP_MSGSTR3_LEN = 0x20; +constexpr uint16_t VP_MSGSTR4 = 0x11C0; +constexpr uint8_t VP_MSGSTR4_LEN = 0x20; + +// Screenchange request for screens that only make sense when printer is idle. +// e.g movement is only allowed if printer is not printing. +// Marlin must confirm by setting the screen manually. +constexpr uint16_t VP_SCREENCHANGE_ASK = 0x2000; +constexpr uint16_t VP_SCREENCHANGE = 0x2001; // Key-Return button to new menu pressed. Data contains target screen in low byte and info in high byte. +constexpr uint16_t VP_TEMP_ALL_OFF = 0x2002; // Turn all heaters off. Value arbitrary ;)= +constexpr uint16_t VP_SCREENCHANGE_WHENSD = 0x2003; // "Print" Button touched -- go only there if there is an SD Card. + +constexpr uint16_t VP_CONFIRMED = 0x2010; // OK on confirm screen. + +// Buttons on the SD-Card File listing. +constexpr uint16_t VP_SD_ScrollEvent = 0x2020; // Data: 0 for "up a directory", numbers are the amount to scroll, e.g -1 one up, 1 one down +constexpr uint16_t VP_SD_FileSelected = 0x2022; // Number of file field selected. +constexpr uint16_t VP_SD_FileSelectConfirm = 0x2024; // (This is a virtual VP and emulated by the Confirm Screen when a file has been confirmed) + +constexpr uint16_t VP_SD_ResumePauseAbort = 0x2026; // Resume(Data=0), Pause(Data=1), Abort(Data=2) SD Card prints +constexpr uint16_t VP_SD_AbortPrintConfirmed = 0x2028; // Abort print confirmation (virtual, will be injected by the confirm dialog) + +// Controls for movement (we can't use the incremental / decremental feature of the display at this feature works only with 16 bit values +// (which would limit us to 655.35mm, which is likely not a problem for common setups, but i don't want to rule out hangprinters support) +// A word about the coding: The VP will be per axis and the return code will be an signed 16 bit value in 0.01 mm resolution, telling us +// the relative travel amount t he user wants to do. So eg. if the display sends us VP=2100 with value 100, the user wants us to move X by +1 mm. +constexpr uint16_t VP_MOVE_X = 0x2100; +constexpr uint16_t VP_MOVE_Y = 0x2102; +constexpr uint16_t VP_MOVE_Z = 0x2104; +constexpr uint16_t VP_MOVE_E1 = 0x2110; +constexpr uint16_t VP_MOVE_E2 = 0x2112; +//constexpr uint16_t VP_MOVE_E3 = 0x2114; +//constexpr uint16_t VP_MOVE_E4 = 0x2116; +//constexpr uint16_t VP_MOVE_E5 = 0x2118; +//constexpr uint16_t VP_MOVE_E6 = 0x211A; +constexpr uint16_t VP_HOME_ALL = 0x2120; + +// Firmware version on the boot screen. +constexpr uint16_t VP_MARLIN_VERSION = 0x3000; +constexpr uint8_t VP_MARLIN_VERSION_LEN = 16; // there is more space on the display, if needed. + +// Place for status messages. +constexpr uint16_t VP_M117 = 0x3020; +constexpr uint8_t VP_M117_LEN = 0x20; + +// Temperatures. +constexpr uint16_t VP_T_E1_Is = 0x3060; // 4 Byte Integer +constexpr uint16_t VP_T_E1_Set = 0x3062; // 2 Byte Integer +constexpr uint16_t VP_T_E2_Is = 0x3064; // 4 Byte Integer + +// reserved to support up to 6 Extruders: +//constexpr uint16_t VP_T_E2_Set = 0x3066; // 2 Byte Integer +//constexpr uint16_t VP_T_E3_Is = 0x3068; // 4 Byte Integer +//constexpr uint16_t VP_T_E3_Set = 0x306A; // 2 Byte Integer +//constexpr uint16_t VP_T_E4_Is = 0x306C; // 4 Byte Integer +//constexpr uint16_t VP_T_E4_Set = 0x306E; // 2 Byte Integer +//constexpr uint16_t VP_T_E5_Is = 0x3070; // 4 Byte Integer +//constexpr uint16_t VP_T_E5_Set = 0x3072; // 2 Byte Integer +//constexpr uint16_t VP_T_E5_Is = 0x3074; // 4 Byte Integer +//constexpr uint16_t VP_T_E5_Set = 0x3076; // 2 Byte Integer +//constexpr uint16_t VP_T_E6_Is = 0x3078; // 4 Byte Integer +//constexpr uint16_t VP_T_E6_Set = 0x307A; // 2 Byte Integer + +constexpr uint16_t VP_T_Bed_Is = 0x3080; // 4 Byte Integer +constexpr uint16_t VP_T_Bed_Set = 0x3082; // 2 Byte Integer + +constexpr uint16_t VP_Flowrate_E1 = 0x3090; // 2 Byte Integer +constexpr uint16_t VP_Flowrate_E2 = 0x3092; // 2 Byte Integer + +// reserved for up to 6 Extruders: +//constexpr uint16_t VP_Flowrate_E3 = 0x3094; +//constexpr uint16_t VP_Flowrate_E4 = 0x3096; +//constexpr uint16_t VP_Flowrate_E5 = 0x3098; +//constexpr uint16_t VP_Flowrate_E6 = 0x309A; + +constexpr uint16_t VP_Fan_Percentage = 0x3100; // 2 Byte Integer (0..100) +constexpr uint16_t VP_Feedrate_Percentage = 0x3102; // 2 Byte Integer (0..100) +constexpr uint16_t VP_PrintProgress_Percentage = 0x3104; // 2 Byte Integer (0..100) + +constexpr uint16_t VP_PrintTime = 0x3106; +constexpr uint16_t VP_PrintTime_LEN = 10; + +// Actual Position +constexpr uint16_t VP_XPos = 0x3110; // 4 Byte Fixed point number; format xxx.yy +constexpr uint16_t VP_YPos = 0x3112; // 4 Byte Fixed point number; format xxx.yy +constexpr uint16_t VP_ZPos = 0x3114; // 4 Byte Fixed point number; format xxx.yy + +constexpr uint16_t VP_EPos = 0x3120; // 4 Byte Fixed point number; format xxx.yy + +// SDCard File Listing +constexpr uint16_t VP_SD_FileName_LEN = 32; // LEN is shared for all entries. +constexpr uint16_t DGUS_SD_FILESPERSCREEN = 5; // FIXME move that info to the display and read it from there. +constexpr uint16_t VP_SD_FileName0 = 0x3200; +constexpr uint16_t VP_SD_FileName1 = 0x3220; +constexpr uint16_t VP_SD_FileName2 = 0x3240; +constexpr uint16_t VP_SD_FileName3 = 0x3260; +constexpr uint16_t VP_SD_FileName4 = 0x3280; + +// SPs for certain variables... +// located at 0x5000 and up +// Not used yet! +// This can be used e.g to make controls / data display invisible +constexpr uint16_t SP_T_E1_Is = 0x5000; +constexpr uint16_t SP_T_E1_Set = 0x5010; +constexpr uint16_t SP_T_E2_Is = 0x5020; +constexpr uint16_t SP_T_Bed_Is = 0x5030; +constexpr uint16_t SP_T_Bed_Set = 0x5040; + +// List of VPs handled by Marlin / The Display. +extern const struct DGUS_VP_Variable ListOfVP[]; diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSVPVariable.h b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSVPVariable.h new file mode 100644 index 0000000000..fdf388d84b --- /dev/null +++ b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSVPVariable.h @@ -0,0 +1,47 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * DGUSVPVariable.h + * + * Created on: Feb 9, 2019 + * Author: tobi + */ + +struct DGUS_VP_Variable { + uint16_t VP; + void* memadr; // If nullptr, the value cannot be uploaded to the display. + uint8_t size; + + // Callback that will be called if the display modified the value. + // nullptr makes it readonly for the display. + void (*set_by_display_handler)(DGUS_VP_Variable &var, void *val_ptr); + void (*send_to_display_handler)(DGUS_VP_Variable &var); + + template + DGUS_VP_Variable& operator =(T &o) { + *(T*)memadr = o; // warning this is not typesafe. + // TODO: Call out the display or mark as dirty for the next update. + return *this; + } +}; diff --git a/Marlin/src/lcd/extensible_ui/ui_api.cpp b/Marlin/src/lcd/extensible_ui/ui_api.cpp index 017b652a0c..dff8108d01 100644 --- a/Marlin/src/lcd/extensible_ui/ui_api.cpp +++ b/Marlin/src/lcd/extensible_ui/ui_api.cpp @@ -57,6 +57,7 @@ #if ENABLED(PRINTCOUNTER) #include "../../core/utility.h" + #include "../../libs/numtostr.h" #endif #if DO_SWITCH_EXTRUDER || EITHER(SWITCHING_NOZZLE, PARKING_EXTRUDER) @@ -170,12 +171,17 @@ namespace ExtUI { void enableHeater(const heater_t heater) { #if HEATER_IDLE_HANDLER - #if HAS_HEATED_BED - if (heater == BED) - thermalManager.reset_bed_idle_timer(); - else - #endif - thermalManager.reset_heater_idle_timer(heater - H0); + switch (heater) { + #if HAS_HEATED_BED + case BED: + thermalManager.reset_bed_idle_timer(); + return; + #endif + #if HAS_HEATED_CHAMBER + case CHAMBER: return; // Chamber has no idle timer + #endif + default: thermalManager.reset_heater_idle_timer(heater - H0); + } #endif } @@ -188,23 +194,31 @@ namespace ExtUI { } bool isHeaterIdle(const heater_t heater) { - return (false - #if HEATER_IDLE_HANDLER - || (heater == BED ? (false - #if HAS_HEATED_BED - || thermalManager.bed_idle.timed_out - #endif - ) : thermalManager.hotend_idle[heater - H0].timed_out) - #endif - ); + #if HEATER_IDLE_HANDLER + switch (heater) { + #if HAS_HEATED_BED + case BED: return thermalManager.bed_idle.timed_out; + #endif + #if HAS_HEATED_CHAMBER + case CHAMBER: return false; // Chamber has no idle timer + #endif + default: return thermalManager.hotend_idle[heater - H0].timed_out; + } + #else + return false; + #endif } float getActualTemp_celsius(const heater_t heater) { - return heater == BED ? (0 + switch (heater) { #if HAS_HEATED_BED - + thermalManager.degBed() + case BED: return thermalManager.degBed(); #endif - ) : thermalManager.degHotend(heater - H0); + #if HAS_HEATED_CHAMBER + case CHAMBER: return thermalManager.degChamber(); + #endif + default: return thermalManager.degHotend(heater - H0); + } } float getActualTemp_celsius(const extruder_t extruder) { @@ -212,11 +226,15 @@ namespace ExtUI { } float getTargetTemp_celsius(const heater_t heater) { - return heater == BED ? (0 + switch (heater) { #if HAS_HEATED_BED - + thermalManager.degTargetBed() + case BED: return thermalManager.degTargetBed(); #endif - ) : thermalManager.degTargetHotend(heater - H0); + #if HAS_HEATED_CHAMBER + case CHAMBER: return thermalManager.degTargetChamber(); + #endif + default: return thermalManager.degTargetHotend(heater - H0); + } } float getTargetTemp_celsius(const extruder_t extruder) { @@ -455,13 +473,13 @@ namespace ExtUI { int getTMCBumpSensitivity(const axis_t axis) { switch (axis) { #if X_SENSORLESS && AXIS_HAS_STALLGUARD(X) - case X: return stepperX.sgt(); + case X: return stepperX.homing_threshold(); #endif #if Y_SENSORLESS && AXIS_HAS_STALLGUARD(Y) - case Y: return stepperY.sgt(); + case Y: return stepperY.homing_threshold(); #endif #if Z_SENSORLESS && AXIS_HAS_STALLGUARD(Z) - case Z: return stepperZ.sgt(); + case Z: return stepperZ.homing_threshold(); #endif default: return 0; } @@ -470,13 +488,13 @@ namespace ExtUI { void setTMCBumpSensitivity(const float value, const axis_t axis) { switch (axis) { #if X_SENSORLESS && AXIS_HAS_STALLGUARD(X) - case X: stepperX.sgt(clamp(value, -64, 63)); break; + case X: stepperX.homing_threshold(value); break; #endif #if Y_SENSORLESS && AXIS_HAS_STALLGUARD(Y) - case Y: stepperY.sgt(clamp(value, -64, 63)); break; + case Y: stepperY.homing_threshold(value); break; #endif #if Z_SENSORLESS && AXIS_HAS_STALLGUARD(Z) - case Z: stepperZ.sgt(clamp(value, -64, 63)); break; + case Z: stepperZ.homing_threshold(value); break; #endif default: break; } @@ -759,10 +777,10 @@ namespace ExtUI { float getFeedrate_percent() { return feedrate_percentage; } void enqueueCommands_P(PGM_P const gcode) { - enqueue_and_echo_commands_P(gcode); + queue.inject_P(gcode); } - bool commandsInQueue() { return (planner.movesplanned() || commands_in_queue); } + bool commandsInQueue() { return (planner.movesplanned() || queue.length); } bool isAxisPositionKnown(const axis_t axis) { return TEST(axis_known_position, axis); @@ -831,35 +849,15 @@ namespace ExtUI { } void pausePrint() { - #if ENABLED(SDSUPPORT) - card.pauseSDPrint(); - print_job_timer.pause(); - #if ENABLED(PARK_HEAD_ON_PAUSE) - enqueue_and_echo_commands_P(PSTR("M125")); - #endif - ui.set_status_P(PSTR(MSG_PRINT_PAUSED)); - #endif + ui.pause_print(); } void resumePrint() { - #if ENABLED(SDSUPPORT) - ui.set_status_P(PSTR(MSG_FILAMENT_CHANGE_RESUME_1)); - #if ENABLED(PARK_HEAD_ON_PAUSE) - wait_for_heatup = wait_for_user = false; - enqueue_and_echo_commands_P(PSTR("M24")); - #else - card.startFileprint(); - print_job_timer.start(); - #endif - #endif + ui.resume_print(); } void stopPrint() { - #if ENABLED(SDSUPPORT) - wait_for_heatup = wait_for_user = false; - card.flag.abort_sd_printing = true; - ui.set_status_P(PSTR(MSG_PRINT_ABORTED)); - #endif + ui.abort_print(); } FileList::FileList() { refresh(); } diff --git a/Marlin/src/lcd/extensible_ui/ui_api.h b/Marlin/src/lcd/extensible_ui/ui_api.h index cce012f38f..689300b8ea 100644 --- a/Marlin/src/lcd/extensible_ui/ui_api.h +++ b/Marlin/src/lcd/extensible_ui/ui_api.h @@ -54,7 +54,7 @@ namespace ExtUI { enum axis_t : uint8_t { X, Y, Z }; enum extruder_t : uint8_t { E0, E1, E2, E3, E4, E5 }; - enum heater_t : uint8_t { H0, H1, H2, H3, H4, H5, BED }; + enum heater_t : uint8_t { H0, H1, H2, H3, H4, H5, BED, CHAMBER }; enum fan_t : uint8_t { FAN0, FAN1, FAN2, FAN3, FAN4, FAN5 }; constexpr uint8_t extruderCount = EXTRUDERS; diff --git a/Marlin/src/lcd/extui_dgus_lcd.cpp b/Marlin/src/lcd/extui_dgus_lcd.cpp new file mode 100644 index 0000000000..6fca8c9cdd --- /dev/null +++ b/Marlin/src/lcd/extui_dgus_lcd.cpp @@ -0,0 +1,81 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 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 . + * + */ + +/** + * extui_dgus_lcd.cpp + * + * DGUS implementation for Marlin by coldtobi, Feb-May 2019 + */ + +#include "../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD) + +#include "extensible_ui/ui_api.h" +#include "extensible_ui/lib/dgus/DGUSDisplay.h" +#include "extensible_ui/lib/dgus/DGUSDisplayDefinition.h" + +namespace ExtUI { + + void onStartup() { + dgusdisplay.InitDisplay(); + ScreenHandler.UpdateScreenVPData(); + } + + void onIdle() { ScreenHandler.loop(); } + + void onPrinterKilled(const char* msg) { + ScreenHandler.sendinfoscreen(PSTR(MSG_HALTED), msg, PSTR(""), PSTR(MSG_PLEASE_RESET), true, true, true, true); + ScreenHandler.GotoScreen(DGUSLCD_SCREEN_KILL); + while (!ScreenHandler.loop()); // Wait while anything is left to be sent + } + + void onMediaInserted() { ScreenHandler.SDCardInserted(); } + void onMediaError() { ScreenHandler.SDCardError(); } + void onMediaRemoved() { ScreenHandler.SDCardRemoved(); } + + void onPlayTone(const uint16_t frequency, const uint16_t duration) {} + void onPrintTimerStarted() {} + void onPrintTimerPaused() {} + void onPrintTimerStopped() {} + void onFilamentRunout() {} + + void onUserConfirmRequired(const char *msg) { + if (msg) { + ScreenHandler.sendinfoscreen(PSTR("Please confirm."), nullptr, msg, nullptr, true, true, false, true); + ScreenHandler.SetupConfirmAction(ExtUI::setUserConfirmed); + ScreenHandler.GotoScreen(DGUSLCD_SCREEN_POPUP); + } + else if (ScreenHandler.getCurrentScreen() == DGUSLCD_SCREEN_POPUP ) { + ScreenHandler.SetupConfirmAction(nullptr); + ScreenHandler.PopToOldScreen(); + } + } + + void onStatusChanged(const char * const msg) { ScreenHandler.setstatusmessage(msg); } + + void onFactoryReset() {} + void onLoadSettings() {} + void onStoreSettings() {} +} + +#endif // DGUS_LCD diff --git a/Marlin/src/lcd/extensible_ui/lib/example.cpp b/Marlin/src/lcd/extui_example.cpp similarity index 96% rename from Marlin/src/lcd/extensible_ui/lib/example.cpp rename to Marlin/src/lcd/extui_example.cpp index 5a52e26787..1bcfea60d0 100644 --- a/Marlin/src/lcd/extensible_ui/lib/example.cpp +++ b/Marlin/src/lcd/extui_example.cpp @@ -1,6 +1,6 @@ -/*************** - * example.cpp * - ***************/ +/********************* + * extui_example.cpp * + *********************/ /**************************************************************************** * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. * @@ -19,11 +19,11 @@ * location: . * ****************************************************************************/ -#include "../../../inc/MarlinConfigPre.h" +#include "../inc/MarlinConfigPre.h" #if BOTH(EXTUI_EXAMPLE, EXTENSIBLE_UI) -#include "../ui_api.h" +#include "extensible_ui/ui_api.h" // To implement a new UI, complete the functions below and // read or update Marlin's state using the methods in the diff --git a/Marlin/src/lcd/malyanlcd.cpp b/Marlin/src/lcd/extui_malyan_lcd.cpp similarity index 97% rename from Marlin/src/lcd/malyanlcd.cpp rename to Marlin/src/lcd/extui_malyan_lcd.cpp index a3462d295d..657b001587 100644 --- a/Marlin/src/lcd/malyanlcd.cpp +++ b/Marlin/src/lcd/extui_malyan_lcd.cpp @@ -21,7 +21,7 @@ */ /** - * malyanlcd.cpp + * extui_malyan_lcd.cpp * * LCD implementation for Malyan's LCD, a separate ESP8266 MCU running * on Serial1 for the M200 board. This module outputs a pseudo-gcode @@ -190,8 +190,8 @@ void process_lcd_j_command(const char* command) { case 'E': // enable or disable steppers // switch to relative - enqueue_and_echo_commands_now_P(PSTR("G91")); - enqueue_and_echo_commands_now_P(steppers_enabled ? PSTR("M18") : PSTR("M17")); + queue.enqueue_now_P(PSTR("G91")); + queue.enqueue_now_P(steppers_enabled ? PSTR("M18") : PSTR("M17")); steppers_enabled = !steppers_enabled; break; case 'A': @@ -204,7 +204,7 @@ void process_lcd_j_command(const char* command) { // The M200 class UI seems to send movement in .1mm values. char cmd[20]; sprintf_P(cmd, PSTR("G1 %c%03.1f"), axis, atof(command + 1) / 10.0); - enqueue_and_echo_command_now(cmd); + queue.enqueue_one_now(cmd); } break; default: SERIAL_ECHOLNPAIR("UNKNOWN J COMMAND", command); @@ -247,7 +247,7 @@ void process_lcd_p_command(const char* command) { true #endif ); - clear_command_queue(); + queue.clear(); quickstop_stepper(); print_job_timer.stop(); thermalManager.disable_all_heaters(); @@ -258,7 +258,7 @@ void process_lcd_p_command(const char* command) { break; case 'H': // Home all axis - enqueue_and_echo_commands_now_P(PSTR("G28")); + queue.enqueue_now_P(PSTR("G28")); break; default: { #if ENABLED(SDSUPPORT) @@ -321,7 +321,7 @@ void process_lcd_s_command(const char* command) { case 'H': // Home all axis - enqueue_and_echo_command("G28"); + queue.inject_P(PSTR("G28")); break; case 'L': { diff --git a/Marlin/src/lcd/language/language_de.h b/Marlin/src/lcd/language/language_de.h index 3f682a35ba..f6255453e9 100644 --- a/Marlin/src/lcd/language/language_de.h +++ b/Marlin/src/lcd/language/language_de.h @@ -99,6 +99,8 @@ #define MSG_UBL_UNHOMED _UxGT("Home XYZ zuerst") #define MSG_UBL_TOOLS _UxGT("UBL-Werkzeuge") #define MSG_UBL_LEVEL_BED _UxGT("Unified Bed Leveling") +#define MSG_LCD_PROBING_MESH _UxGT("Messpunkt") +#define MSG_LCD_TILTING_MESH _UxGT("Berührungspunkt") #define MSG_IDEX_MENU _UxGT("IDEX-Modus") #define MSG_OFFSETS_MENU _UxGT("Werkzeugversätze") #define MSG_IDEX_MODE_AUTOPARK _UxGT("Autom. Parken") @@ -231,7 +233,7 @@ #define MSG_JUNCTION_DEVIATION _UxGT("Junction Dev") #define MSG_VELOCITY _UxGT("Geschwindigkeit") #define MSG_VMAX _UxGT("V max ") // space intentional -#define MSG_VMIN _UxGT("V min") +#define MSG_VMIN _UxGT("V min ") #define MSG_VTRAV_MIN _UxGT("V min Leerfahrt") #define MSG_ACCELERATION _UxGT("Beschleunigung") #define MSG_AMAX _UxGT("A max ") // space intentional @@ -258,7 +260,7 @@ #define MSG_MOTION _UxGT("Bewegung") #define MSG_FILAMENT _UxGT("Filament") #define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm³") -#define MSG_FILAMENT_DIAM _UxGT("Durchm. Filament") +#define MSG_FILAMENT_DIAM _UxGT("Filamentdurchmesser") #define MSG_FILAMENT_UNLOAD _UxGT("Entladen mm") #define MSG_FILAMENT_LOAD _UxGT("Laden mm") #define MSG_ADVANCE_K _UxGT("Vorschubfaktor") @@ -325,9 +327,13 @@ #define MSG_BLTOUCH_DEPLOY _UxGT("BLTouch ausfahren") #define MSG_BLTOUCH_SW_MODE _UxGT("BLTouch SW-Modus") #define MSG_BLTOUCH_5V_MODE _UxGT("BLTouch 5V-Modus") -#define MSG_BLTOUCH_OD_MODE _UxGT("BLTouch OD Mode") +#define MSG_BLTOUCH_OD_MODE _UxGT("BLTouch OD-Modus") #define MSG_BLTOUCH_MODE_STORE _UxGT("BLTouch Mode Store") +#define MSG_BLTOUCH_MODE_STORE_5V _UxGT("BLTouch auf 5V") +#define MSG_BLTOUCH_MODE_STORE_OD _UxGT("BLTouch auf OD") #define MSG_BLTOUCH_STOW _UxGT("BLTouch einfahren") +#define MSG_BLTOUCH_MODE_ECHO _UxGT("BLTouch Modus: ") +#define MSG_BLTOUCH_MODE_CHANGE _UxGT("ACHTUNG: Falsche Einstellung - kann zu Beschädigung führen! Fortfahren?") #define MSG_MANUAL_DEPLOY _UxGT("Z-Sonde ausfahren") #define MSG_MANUAL_STOW _UxGT("Z-Sonde einfahren") #define MSG_HOME _UxGT("Vorher") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST @@ -418,7 +424,8 @@ #define MSG_FILAMENT_CHANGE_OPTION_PURGE _UxGT("Mehr entladen") #define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Druck weiter") #define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Düse: ") -#define MSG_RUNOUT_SENSOR _UxGT("Auslaufsensor") +#define MSG_RUNOUT_SENSOR _UxGT("Runout-Sensor") +#define MSG_RUNOUT_DISTANCE_MM _UxGT("Runout-Weg mm") #define MSG_ERR_HOMING_FAILED _UxGT("Homing gescheitert") #define MSG_ERR_PROBING_FAILED _UxGT("Probing gescheitert") #define MSG_M600_TOO_COLD _UxGT("M600: zu kalt") diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index 2887605b97..2fee46b2fe 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -934,7 +934,7 @@ #define MSG_BLTOUCH_MODE_ECHO _UxGT("Report Drain") #endif #ifndef MSG_BLTOUCH_MODE_CHANGE - #define MSG_BLTOUCH_MODE_CHANGE _UxGT(" ***WARNING*** Wrong Setting May Damage Machine! Proceed Anyway?") + #define MSG_BLTOUCH_MODE_CHANGE _UxGT("DANGER: Bad settings can cause damage! Proceed anyway?") #endif #ifndef MSG_MANUAL_DEPLOY #define MSG_MANUAL_DEPLOY _UxGT("Deploy Z-Probe") @@ -1197,6 +1197,9 @@ #ifndef MSG_RUNOUT_SENSOR #define MSG_RUNOUT_SENSOR _UxGT("Runout Sensor") #endif +#ifndef MSG_RUNOUT_DISTANCE_MM + #define MSG_RUNOUT_DISTANCE_MM _UxGT("Runout Dist mm") +#endif #ifndef MSG_ERR_HOMING_FAILED #define MSG_ERR_HOMING_FAILED _UxGT("Homing failed") #endif diff --git a/Marlin/src/lcd/language/language_fr.h b/Marlin/src/lcd/language/language_fr.h index f53bb30ca8..b6f863f1ea 100644 --- a/Marlin/src/lcd/language/language_fr.h +++ b/Marlin/src/lcd/language/language_fr.h @@ -96,9 +96,11 @@ #define MSG_USER_MENU _UxGT("Commandes perso") #define MSG_UBL_DOING_G29 _UxGT("G29 en cours") -#define MSG_UBL_UNHOMED _UxGT("Origine XYZ d'abord") +#define MSG_UBL_UNHOMED _UxGT("Origine XYZ requise") #define MSG_UBL_TOOLS _UxGT("Outils UBL") #define MSG_UBL_LEVEL_BED _UxGT("Niveau lit unifié") +#define MSG_LCD_PROBING_MESH _UxGT("Mesure point") +#define MSG_LCD_TILTING_MESH _UxGT("Touche point") #define MSG_IDEX_MENU _UxGT("Mode IDEX") #define MSG_IDEX_MODE_AUTOPARK _UxGT("Auto-Park") #define MSG_IDEX_MODE_DUPLICATE _UxGT("Duplication") @@ -321,13 +323,17 @@ #define MSG_ZPROBE_OUT _UxGT("Sonde Z hors lit") #define MSG_SKEW_FACTOR _UxGT("Facteur écart") #define MSG_BLTOUCH _UxGT("BLTouch") -#define MSG_BLTOUCH_SELFTEST _UxGT("Autotest BLTouch") -#define MSG_BLTOUCH_RESET _UxGT("RaZ BL-Touch") -#define MSG_BLTOUCH_DEPLOY _UxGT("Déployer BL-Touch") -#define MSG_BLTOUCH_SW_MODE _UxGT("Mode BLTouch SW") -#define MSG_BLTOUCH_5V_MODE _UxGT("Mode BLTouch 5V") -#define MSG_BLTOUCH_OD_MODE _UxGT("Mode BLTouch OD") -#define MSG_BLTOUCH_STOW _UxGT("Ranger BL-Touch") +#define MSG_BLTOUCH_SELFTEST _UxGT("Cmd: Self-Test") +#define MSG_BLTOUCH_RESET _UxGT("Cmd: Reset") +#define MSG_BLTOUCH_STOW _UxGT("Cmd: Ranger") +#define MSG_BLTOUCH_DEPLOY _UxGT("Cmd: Déployer") +#define MSG_BLTOUCH_SW_MODE _UxGT("Cmd: Mode SW") +#define MSG_BLTOUCH_5V_MODE _UxGT("Cmd: Mode 5V") +#define MSG_BLTOUCH_OD_MODE _UxGT("Cmd: Mode OD") +#define MSG_BLTOUCH_MODE_STORE _UxGT("Appliquer Mode") +#define MSG_BLTOUCH_MODE_STORE_5V _UxGT("Mise en 5V") +#define MSG_BLTOUCH_MODE_STORE_OD _UxGT("Mise en OD") +#define MSG_BLTOUCH_MODE_ECHO _UxGT("Afficher Mode") #define MSG_MANUAL_DEPLOY _UxGT("Déployer Sonde Z") #define MSG_MANUAL_STOW _UxGT("Ranger Sonde Z") #define MSG_HOME _UxGT("Origine") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST @@ -363,6 +369,8 @@ #define MSG_COOLING _UxGT("Refroidissement") #define MSG_BED_HEATING _UxGT("Lit en chauffe...") #define MSG_BED_COOLING _UxGT("Refroid. du lit...") +#define MSG_CHAMBER_HEATING _UxGT("Chauffe caisson...") +#define MSG_CHAMBER_COOLING _UxGT("Refroid. caisson...") #define MSG_DELTA_CALIBRATE _UxGT("Calibration Delta") #define MSG_DELTA_CALIBRATE_X _UxGT("Calibrer X") #define MSG_DELTA_CALIBRATE_Y _UxGT("Calibrer Y") diff --git a/Marlin/src/lcd/language/language_it.h b/Marlin/src/lcd/language/language_it.h index d583995674..a40a52c0a5 100644 --- a/Marlin/src/lcd/language/language_it.h +++ b/Marlin/src/lcd/language/language_it.h @@ -327,8 +327,12 @@ #define MSG_BLTOUCH_5V_MODE _UxGT("BLTouch modo 5V") #define MSG_BLTOUCH_OD_MODE _UxGT("BLTouch modo OD") #define MSG_BLTOUCH_MODE_STORE _UxGT("BLTouch modo mem.") -#define MSG_BLTOUCH_STOW _UxGT("Ritrai BLTouch") +#define MSG_BLTOUCH_MODE_STORE_5V _UxGT("Metti BLTouch a 5V") +#define MSG_BLTOUCH_MODE_STORE_OD _UxGT("Metti BLTouch a OD") +#define MSG_BLTOUCH_MODE_ECHO _UxGT("Segnala modo") +#define MSG_BLTOUCH_MODE_CHANGE _UxGT("PERICOLO: Impostazioni errate possono cause danni! Procedo comunque?") #define MSG_MANUAL_DEPLOY _UxGT("Estendi Sonda-Z") +#define MSG_BLTOUCH_STOW _UxGT("Ritrai BLTouch") #define MSG_MANUAL_STOW _UxGT("Ritrai Sonda-Z") #define MSG_HOME _UxGT("Home") // Usato come MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST #define MSG_FIRST _UxGT("prima") @@ -417,6 +421,7 @@ #define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Riprendi stampa") #define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Ugello: ") #define MSG_RUNOUT_SENSOR _UxGT("Sens.filo termin.") // Max 17 caratteri +#define MSG_RUNOUT_DISTANCE_MM _UxGT("Dist mm filo term.") #define MSG_ERR_HOMING_FAILED _UxGT("Home fallito") #define MSG_ERR_PROBING_FAILED _UxGT("Sondaggio fallito") #define MSG_M600_TOO_COLD _UxGT("M600:Troppo freddo") diff --git a/Marlin/src/lcd/language/language_sk.h b/Marlin/src/lcd/language/language_sk.h index d0d8af11df..593597c917 100644 --- a/Marlin/src/lcd/language/language_sk.h +++ b/Marlin/src/lcd/language/language_sk.h @@ -45,6 +45,7 @@ #define MSG_BACK _UxGT("Naspäť") #define MSG_SD_INSERTED _UxGT("Karta vložená") #define MSG_SD_REMOVED _UxGT("Karta vybraná") +#define MSG_SD_RELEASED _UxGT("Karta odpojená") #define MSG_LCD_ENDSTOPS _UxGT("Endstopy") // max 8 znakov #define MSG_LCD_SOFT_ENDSTOPS _UxGT("Soft. endstopy") #define MSG_MAIN _UxGT("Hlavná ponuka") @@ -105,6 +106,8 @@ #define MSG_UBL_UNHOMED _UxGT("Prejdite domov") #define MSG_UBL_TOOLS _UxGT("Nástroje UBL") #define MSG_UBL_LEVEL_BED _UxGT("UBL rovnanie") +#define MSG_LCD_PROBING_MESH _UxGT("Skúšam bod") +#define MSG_LCD_TILTING_MESH _UxGT("Vyrovnávam bod") #define MSG_IDEX_MENU _UxGT("IDEX režim") #define MSG_OFFSETS_MENU _UxGT("Offset nástrojov") #define MSG_IDEX_MODE_AUTOPARK _UxGT("Auto-parkovanie") @@ -323,16 +326,21 @@ #define MSG_INIT_SDCARD _UxGT("Načítať SD kartu") #define MSG_CHANGE_SDCARD _UxGT("Vymeniť SD kartu") +#define MSG_RELEASE_SDCARD _UxGT("Odpojiť SD kartu") #define MSG_ZPROBE_OUT _UxGT("Sonda Z mimo podl.") #define MSG_SKEW_FACTOR _UxGT("Faktor skosenia") #define MSG_BLTOUCH _UxGT("BLTouch") -#define MSG_BLTOUCH_SELFTEST _UxGT("Self-Test BLTouch") -#define MSG_BLTOUCH_RESET _UxGT("Reset BLTouch") -#define MSG_BLTOUCH_DEPLOY _UxGT("Vysunúť BLTouch") -#define MSG_BLTOUCH_SW_MODE _UxGT("SW vysun. BLTouch") -#define MSG_BLTOUCH_5V_MODE _UxGT("BLTouch režim 5V") -#define MSG_BLTOUCH_OD_MODE _UxGT("BLTouch režim OD") -#define MSG_BLTOUCH_STOW _UxGT("Zasunúť BLTouch") +#define MSG_BLTOUCH_SELFTEST _UxGT("Cmd: Self-Test") +#define MSG_BLTOUCH_RESET _UxGT("Cmd: Reset") +#define MSG_BLTOUCH_STOW _UxGT("Cmd: Zasunúť") +#define MSG_BLTOUCH_DEPLOY _UxGT("Cmd: Vysunúť") +#define MSG_BLTOUCH_SW_MODE _UxGT("Cmd: Režim SW") +#define MSG_BLTOUCH_5V_MODE _UxGT("Cmd: Režim 5V") +#define MSG_BLTOUCH_OD_MODE _UxGT("Cmd: Režim OD") +#define MSG_BLTOUCH_MODE_STORE _UxGT("Cmd: Ulož. režim") +#define MSG_BLTOUCH_MODE_STORE_5V _UxGT("Prepnúť do 5V") +#define MSG_BLTOUCH_MODE_STORE_OD _UxGT("Prepnúť do OD") +#define MSG_BLTOUCH_MODE_ECHO _UxGT("Zobraziť režim") #define MSG_MANUAL_DEPLOY _UxGT("Inštalovať sondu Z") #define MSG_MANUAL_STOW _UxGT("Odstrániť sondu Z") #define MSG_HOME _UxGT("Najskôr os") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST @@ -366,6 +374,8 @@ #define MSG_COOLING _UxGT("Ochladzovanie...") #define MSG_BED_HEATING _UxGT("Ohrev podložky...") #define MSG_BED_COOLING _UxGT("Ochladz. podložky...") +#define MSG_CHAMBER_HEATING _UxGT("Ohrev komory...") +#define MSG_CHAMBER_COOLING _UxGT("Ochladz. komory...") #define MSG_DELTA_CALIBRATE _UxGT("Delta kalibrácia") #define MSG_DELTA_CALIBRATE_X _UxGT("Kalibrovať X") #define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibrovať Y") diff --git a/Marlin/src/lcd/menu/menu.cpp b/Marlin/src/lcd/menu/menu.cpp index ff2b5fd6e9..f13b370d29 100644 --- a/Marlin/src/lcd/menu/menu.cpp +++ b/Marlin/src/lcd/menu/menu.cpp @@ -99,7 +99,7 @@ void MarlinUI::goto_previous_screen() { /////////// Common Menu Actions //////////// //////////////////////////////////////////// -void MenuItem_gcode::action(PGM_P pgcode) { enqueue_and_echo_commands_P(pgcode); } +void MenuItem_gcode::action(PGM_P const pgcode) { queue.inject_P(pgcode); } //////////////////////////////////////////// /////////// Menu Editing Actions /////////// @@ -410,15 +410,15 @@ void MarlinUI::completion_feedback(const bool good/*=true*/) { #if ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE) - void lcd_enqueue_command(const char * const cmd) { + void lcd_enqueue_one_now(const char * const cmd) { no_reentry = true; - enqueue_and_echo_command_now(cmd); + queue.enqueue_one_now(cmd); no_reentry = false; } - void lcd_enqueue_commands_P(PGM_P const cmd) { + void lcd_enqueue_one_now_P(PGM_P const cmd) { no_reentry = true; - enqueue_and_echo_commands_now_P(cmd); + queue.enqueue_now_P(cmd); no_reentry = false; } diff --git a/Marlin/src/lcd/menu/menu.h b/Marlin/src/lcd/menu/menu.h index a300096399..8135d2a973 100644 --- a/Marlin/src/lcd/menu/menu.h +++ b/Marlin/src/lcd/menu/menu.h @@ -22,6 +22,7 @@ #pragma once #include "../ultralcd.h" +#include "../../libs/numtostr.h" #include "../../inc/MarlinConfig.h" #include "limits.h" @@ -374,8 +375,8 @@ void _lcd_draw_homing(); #endif #if ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE) - void lcd_enqueue_command(const char * const cmd); - void lcd_enqueue_commands_P(PGM_P const cmd); + void lcd_enqueue_one_now(const char * const cmd); + void lcd_enqueue_one_now_P(PGM_P const cmd); #endif #if ENABLED(LEVEL_BED_CORNERS) diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp index df873fc06d..537fb769c8 100644 --- a/Marlin/src/lcd/menu/menu_advanced.cpp +++ b/Marlin/src/lcd/menu/menu_advanced.cpp @@ -43,6 +43,11 @@ #include "../../module/temperature.h" #endif +#ifdef FILAMENT_RUNOUT_DISTANCE_MM + #include "../../feature/runout.h" + float lcd_runout_distance_mm; +#endif + void menu_tmc(); void menu_backlash(); @@ -96,7 +101,7 @@ void menu_backlash(); // Set the home offset based on the current_position // void _lcd_set_home_offsets() { - enqueue_and_echo_commands_P(PSTR("M428")); + queue.inject_P(PSTR("M428")); ui.return_to_status(); } #endif @@ -214,6 +219,12 @@ void menu_backlash(); #endif // EXTRUDERS > 1 #endif + #ifdef FILAMENT_RUNOUT_DISTANCE_MM + MENU_ITEM_EDIT_CALLBACK(float3, MSG_RUNOUT_DISTANCE_MM, &lcd_runout_distance_mm, 1, 30, []{ + runout.set_runout_distance(lcd_runout_distance_mm); + }); + #endif + END_MENU(); } @@ -244,7 +255,7 @@ void menu_backlash(); autotune_temp[e] #endif ); - lcd_enqueue_command(cmd); + lcd_enqueue_one_now(cmd); } #endif // PID_AUTOTUNE_MENU @@ -603,6 +614,9 @@ void menu_backlash(); #endif // !SLIM_LCD_MENUS void menu_advanced_settings() { + #ifdef FILAMENT_RUNOUT_DISTANCE_MM + lcd_runout_distance_mm = runout.runout_distance(); + #endif START_MENU(); MENU_BACK(MSG_CONFIGURATION); @@ -674,7 +688,7 @@ void menu_advanced_settings() { #endif // M540 S - Abort on endstop hit when SD printing - #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + #if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) MENU_ITEM_EDIT(bool, MSG_ENDSTOP_ABORT, &planner.abort_on_endstop_hit); #endif diff --git a/Marlin/src/lcd/menu/menu_bed_corners.cpp b/Marlin/src/lcd/menu/menu_bed_corners.cpp index fd90043d0f..43841dd4dc 100644 --- a/Marlin/src/lcd/menu/menu_bed_corners.cpp +++ b/Marlin/src/lcd/menu/menu_bed_corners.cpp @@ -120,7 +120,7 @@ void _lcd_level_bed_corners() { ui.defer_status_screen(); if (!all_axes_known()) { set_all_unhomed(); - enqueue_and_echo_commands_P(PSTR("G28")); + queue.inject_P(PSTR("G28")); } // Disable leveling so the planner won't mess with us diff --git a/Marlin/src/lcd/menu/menu_bed_leveling.cpp b/Marlin/src/lcd/menu/menu_bed_leveling.cpp index e8107aa58a..0d534d86ee 100644 --- a/Marlin/src/lcd/menu/menu_bed_leveling.cpp +++ b/Marlin/src/lcd/menu/menu_bed_leveling.cpp @@ -105,9 +105,9 @@ ui.wait_for_bl_move = true; ui.goto_screen(_lcd_level_bed_done); #if ENABLED(MESH_BED_LEVELING) - enqueue_and_echo_commands_P(PSTR("G29 S2")); + queue.inject_P(PSTR("G29 S2")); #elif ENABLED(PROBE_MANUALLY) - enqueue_and_echo_commands_P(PSTR("G29 V1")); + queue.inject_P(PSTR("G29 V1")); #endif } else @@ -157,9 +157,9 @@ // G29 Records Z, moves, and signals when it pauses ui.wait_for_bl_move = true; #if ENABLED(MESH_BED_LEVELING) - enqueue_and_echo_commands_P(manual_probe_index ? PSTR("G29 S2") : PSTR("G29 S1")); + queue.inject_P(manual_probe_index ? PSTR("G29 S2") : PSTR("G29 S1")); #elif ENABLED(PROBE_MANUALLY) - enqueue_and_echo_commands_P(PSTR("G29 V1")); + queue.inject_P(PSTR("G29 V1")); #endif } @@ -194,7 +194,7 @@ ui.defer_status_screen(); set_all_unhomed(); ui.goto_screen(_lcd_level_bed_homing); - enqueue_and_echo_commands_P(PSTR("G28")); + queue.inject_P(PSTR("G28")); } #endif // PROBE_MANUALLY || MESH_BED_LEVELING diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp index ce2edb5104..0f17a3ca44 100644 --- a/Marlin/src/lcd/menu/menu_configuration.cpp +++ b/Marlin/src/lcd/menu/menu_configuration.cpp @@ -127,7 +127,7 @@ static void lcd_factory_settings() { auto _recalc_offsets = []{ if (active_extruder && all_axes_known()) { // For the 2nd extruder re-home so the next tool-change gets the new offsets. - enqueue_and_echo_commands_P(PSTR("G28")); // In future, we can babystep the 2nd extruder (if active), making homing unnecessary. + queue.inject_P(PSTR("G28")); // In future, we can babystep the 2nd extruder (if active), making homing unnecessary. active_extruder = 0; } }; @@ -135,7 +135,7 @@ static void lcd_factory_settings() { START_MENU(); MENU_BACK(MSG_CONFIGURATION); #if ENABLED(DUAL_X_CARRIAGE) - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float51, MSG_X_OFFSET, &hotend_offset[X_AXIS][1], (float)(X2_HOME_POS - 25), (float)(X2_HOME_POS + 25), _recalc_offsets); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float51, MSG_X_OFFSET, &hotend_offset[X_AXIS][1], float(X2_HOME_POS - 25), float(X2_HOME_POS + 25), _recalc_offsets); #else MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float52sign, MSG_X_OFFSET, &hotend_offset[X_AXIS][1], -10.0, 10.0, _recalc_offsets); #endif @@ -184,7 +184,7 @@ static void lcd_factory_settings() { ); char mess[21]; strcpy_P(mess, PSTR("BLTouch Mode - ")); - sprintf_P(&mess[15], bltouch.last_written_mode ? PSTR("5V") : PSTR("OD")); + strcpy_P(&mess[15], bltouch.last_written_mode ? PSTR("5V") : PSTR("OD")); ui.set_status(mess); ui.return_to_status(); } @@ -219,17 +219,21 @@ static void lcd_factory_settings() { #endif -#if ENABLED(MENU_ITEM_CASE_LIGHT) +#if ENABLED(CASE_LIGHT_MENU) #include "../../feature/caselight.h" - void menu_case_light() { - START_MENU(); - MENU_BACK(MSG_CONFIGURATION); - MENU_ITEM_EDIT_CALLBACK(uint8, MSG_CASE_LIGHT_BRIGHTNESS, &case_light_brightness, 0, 255, update_case_light, true); - MENU_ITEM_EDIT_CALLBACK(bool, MSG_CASE_LIGHT, (bool*)&case_light_on, update_case_light); - END_MENU(); - } + #if DISABLED(CASE_LIGHT_NO_BRIGHTNESS) + + void menu_case_light() { + START_MENU(); + MENU_BACK(MSG_CONFIGURATION); + MENU_ITEM_EDIT_CALLBACK(uint8, MSG_CASE_LIGHT_BRIGHTNESS, &case_light_brightness, 0, 255, update_case_light, true); + MENU_ITEM_EDIT_CALLBACK(bool, MSG_CASE_LIGHT, (bool*)&case_light_on, update_case_light); + END_MENU(); + } + + #endif #endif @@ -355,11 +359,13 @@ void menu_configuration() { // // Set Case light on/off/brightness // - #if ENABLED(MENU_ITEM_CASE_LIGHT) - if (PWM_PIN(CASE_LIGHT_PIN)) - MENU_ITEM(submenu, MSG_CASE_LIGHT, menu_case_light); - else - MENU_ITEM_EDIT_CALLBACK(bool, MSG_CASE_LIGHT, (bool*)&case_light_on, update_case_light); + #if ENABLED(CASE_LIGHT_MENU) + #if DISABLED(CASE_LIGHT_NO_BRIGHTNESS) + if (PWM_PIN(CASE_LIGHT_PIN)) + MENU_ITEM(submenu, MSG_CASE_LIGHT, menu_case_light); + else + #endif + MENU_ITEM_EDIT_CALLBACK(bool, MSG_CASE_LIGHT, (bool*)&case_light_on, update_case_light); #endif #if HAS_LCD_CONTRAST diff --git a/Marlin/src/lcd/menu/menu_custom.cpp b/Marlin/src/lcd/menu/menu_custom.cpp index 9d6cd9e8a1..bc9a23adfb 100644 --- a/Marlin/src/lcd/menu/menu_custom.cpp +++ b/Marlin/src/lcd/menu/menu_custom.cpp @@ -38,7 +38,7 @@ #endif void _lcd_user_gcode(PGM_P const cmd) { - enqueue_and_echo_commands_P(cmd); + queue.inject_P(cmd); #if ENABLED(USER_SCRIPT_AUDIBLE_FEEDBACK) ui.completion_feedback(); #endif diff --git a/Marlin/src/lcd/menu/menu_delta_calibrate.cpp b/Marlin/src/lcd/menu/menu_delta_calibrate.cpp index 6931f32726..54915e12f9 100644 --- a/Marlin/src/lcd/menu/menu_delta_calibrate.cpp +++ b/Marlin/src/lcd/menu/menu_delta_calibrate.cpp @@ -73,7 +73,7 @@ void _man_probe_pt(const float &rx, const float &ry) { } void _lcd_delta_calibrate_home() { - enqueue_and_echo_commands_P(PSTR("G28")); + queue.inject_P(PSTR("G28")); ui.goto_screen(_lcd_calibrate_homing); } diff --git a/Marlin/src/lcd/menu/menu_filament.cpp b/Marlin/src/lcd/menu/menu_filament.cpp index 2902d12a00..a7b6e0b4f5 100644 --- a/Marlin/src/lcd/menu/menu_filament.cpp +++ b/Marlin/src/lcd/menu/menu_filament.cpp @@ -58,7 +58,7 @@ static void _change_filament_temp(const uint16_t temperature) { char cmd[11]; sprintf_P(cmd, _change_filament_temp_command(), _change_filament_temp_extruder); thermalManager.setTargetHotend(temperature, _change_filament_temp_extruder); - lcd_enqueue_command(cmd); + lcd_enqueue_one_now(cmd); } inline void _lcd_change_filament_temp_1_func() { _change_filament_temp(ui.preheat_hotend_temp[0]); } inline void _lcd_change_filament_temp_2_func() { _change_filament_temp(ui.preheat_hotend_temp[1]); } @@ -512,7 +512,7 @@ FORCE_INLINE screenFunc_t ap_message_screen(const PauseMessage message) { case PAUSE_MESSAGE_HEAT: return lcd_pause_heat_message; case PAUSE_MESSAGE_HEATING: return lcd_pause_heating_message; case PAUSE_MESSAGE_OPTION: pause_menu_response = PAUSE_RESPONSE_WAIT_FOR; - return menu_pause_option; + return menu_pause_option; case PAUSE_MESSAGE_STATUS: default: break; } diff --git a/Marlin/src/lcd/menu/menu_info.cpp b/Marlin/src/lcd/menu/menu_info.cpp index eb58b3a56b..b5318d266b 100644 --- a/Marlin/src/lcd/menu/menu_info.cpp +++ b/Marlin/src/lcd/menu/menu_info.cpp @@ -28,6 +28,10 @@ #if HAS_LCD_MENU && ENABLED(LCD_INFO_MENU) +#if HAS_GAMES + #include "game/game.h" +#endif + #include "menu.h" // #include "../../module/motion.h" // #include "../../module/planner.h" @@ -220,6 +224,21 @@ void menu_info() { #if ENABLED(PRINTCOUNTER) MENU_ITEM(submenu, MSG_INFO_STATS_MENU, menu_info_stats); // Printer Stats > #endif + #if HAS_GAMES + MENU_ITEM(submenu, "Game", ( + #if HAS_GAME_MENU + menu_game + #elif ENABLED(MARLIN_BRICKOUT) + brickout.enter_game + #elif ENABLED(MARLIN_INVADERS) + invaders.enter_game + #elif ENABLED(MARLIN_SNAKE) + snake.enter_game + #elif ENABLED(MARLIN_MAZE) + maze.enter_game + #endif + )); + #endif END_MENU(); } diff --git a/Marlin/src/lcd/menu/menu_job_recovery.cpp b/Marlin/src/lcd/menu/menu_job_recovery.cpp index f819052977..72fe4cd992 100644 --- a/Marlin/src/lcd/menu/menu_job_recovery.cpp +++ b/Marlin/src/lcd/menu/menu_job_recovery.cpp @@ -35,7 +35,7 @@ static void lcd_power_loss_recovery_resume() { ui.return_to_status(); - enqueue_and_echo_commands_P(PSTR("M1000")); + queue.inject_P(PSTR("M1000")); } static void lcd_power_loss_recovery_cancel() { diff --git a/Marlin/src/lcd/menu/menu_main.cpp b/Marlin/src/lcd/menu/menu_main.cpp index 93ebe75781..b1887a9bb6 100644 --- a/Marlin/src/lcd/menu/menu_main.cpp +++ b/Marlin/src/lcd/menu/menu_main.cpp @@ -35,76 +35,17 @@ #include "../../module/stepper.h" #include "../../sd/cardreader.h" -#if ENABLED(POWER_LOSS_RECOVERY) - #include "../../feature/power_loss_recovery.h" -#endif - -#if ENABLED(HOST_ACTION_COMMANDS) - #include "../../feature/host_actions.h" -#endif - -#if HAS_GAMES +#if HAS_GAMES && DISABLED(LCD_INFO_MENU) #include "game/game.h" #endif #define MACHINE_CAN_STOP (EITHER(SDSUPPORT, HOST_PROMPT_SUPPORT) || defined(ACTION_ON_CANCEL)) #define MACHINE_CAN_PAUSE (ANY(SDSUPPORT, HOST_PROMPT_SUPPORT, PARK_HEAD_ON_PAUSE) || defined(ACTION_ON_PAUSE)) -#if MACHINE_CAN_PAUSE - - void lcd_pause_job() { - ui.synchronize(PSTR(MSG_PAUSE_PRINT)); - - #if ENABLED(POWER_LOSS_RECOVERY) - if (recovery.enabled) recovery.save(true, false); - #endif - - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_open(PROMPT_PAUSE_RESUME, PSTR("UI Pause"), PSTR("Resume")); - #endif - - #if ENABLED(PARK_HEAD_ON_PAUSE) - lcd_pause_show_message(PAUSE_MESSAGE_PAUSING, PAUSE_MODE_PAUSE_PRINT); // Show message immediately to let user know about pause in progress - enqueue_and_echo_commands_P(PSTR("M25 P\nM24")); - #elif ENABLED(SDSUPPORT) - enqueue_and_echo_commands_P(PSTR("M25")); - #elif defined(ACTION_ON_PAUSE) - host_action_pause(); - #endif - } - - void lcd_resume() { - #if ENABLED(SDSUPPORT) - if (card.isPaused()) enqueue_and_echo_commands_P(PSTR("M24")); - #endif - #ifdef ACTION_ON_RESUME - host_action_resume(); - #endif - } - -#endif // MACHINE_CAN_PAUSE - #if MACHINE_CAN_STOP - - void lcd_abort_job() { - #if ENABLED(SDSUPPORT) - wait_for_heatup = wait_for_user = false; - card.flag.abort_sd_printing = true; - #endif - #ifdef ACTION_ON_CANCEL - host_action_cancel(); - #endif - #if ENABLED(HOST_PROMPT_SUPPORT) - host_prompt_open(PROMPT_INFO, PSTR("UI Abort")); - #endif - ui.set_status_P(PSTR(MSG_PRINT_ABORTED), -1); - ui.return_to_status(); - } - void menu_abort_confirm() { - do_select_screen(PSTR(MSG_BUTTON_STOP), PSTR(MSG_BACK), lcd_abort_job, ui.goto_previous_screen, PSTR(MSG_STOP_PRINT), nullptr, PSTR("?")); + do_select_screen(PSTR(MSG_BUTTON_STOP), PSTR(MSG_BACK), ui.abort_print, ui.goto_previous_screen, PSTR(MSG_STOP_PRINT), nullptr, PSTR("?")); } - #endif // MACHINE_CAN_STOP #if ENABLED(PRUSA_MMU2) @@ -115,11 +56,23 @@ void menu_tune(); void menu_motion(); void menu_temperature(); void menu_configuration(); -void menu_user(); -void menu_temp_e0_filament_change(); -void menu_change_filament(); -void menu_info(); -void menu_led(); + +#if ENABLED(CUSTOM_USER_MENUS) + void menu_user(); +#endif + +#if ENABLED(ADVANCED_PAUSE_FEATURE) + void menu_temp_e0_filament_change(); + void menu_change_filament(); +#endif + +#if ENABLED(LCD_INFO_MENU) + void menu_info(); +#endif + +#if ENABLED(LED_CONTROL_MENU) + void menu_led(); +#endif #if ENABLED(MIXING_EXTRUDER) void menu_mixer(); @@ -137,16 +90,6 @@ void menu_led(); #endif #endif -#if HAS_GAME_MENU - void menu_game(); -#elif ENABLED(MARLIN_BRICKOUT) - void lcd_goto_brickout(); -#elif ENABLED(MARLIN_INVADERS) - void lcd_goto_invaders(); -#elif ENABLED(MARLIN_SNAKE) - void lcd_goto_snake(); -#endif - void menu_main() { START_MENU(); MENU_BACK(MSG_WATCH); @@ -160,7 +103,7 @@ void menu_main() { if (busy) { #if MACHINE_CAN_PAUSE - MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_pause_job); + MENU_ITEM(function, MSG_PAUSE_PRINT, ui.pause_print); #endif #if MACHINE_CAN_STOP MENU_ITEM(submenu, MSG_STOP_PRINT, menu_abort_confirm); @@ -204,7 +147,7 @@ void menu_main() { || card.isPaused() #endif ); - if (paused) MENU_ITEM(function, MSG_RESUME_PRINT, lcd_resume); + if (paused) MENU_ITEM(function, MSG_RESUME_PRINT, ui.resume_print); #endif MENU_ITEM(submenu, MSG_MOTION, menu_motion); @@ -297,7 +240,7 @@ void menu_main() { #endif #endif - #if ANY(MARLIN_BRICKOUT, MARLIN_INVADERS, MARLIN_SNAKE, MARLIN_MAZE) + #if HAS_GAMES && DISABLED(LCD_INFO_MENU) MENU_ITEM(submenu, "Game", ( #if HAS_GAME_MENU menu_game diff --git a/Marlin/src/lcd/menu/menu_temperature.cpp b/Marlin/src/lcd/menu/menu_temperature.cpp index f41fb18e79..dd6bd233a9 100644 --- a/Marlin/src/lcd/menu/menu_temperature.cpp +++ b/Marlin/src/lcd/menu/menu_temperature.cpp @@ -313,6 +313,7 @@ void _lcd_preheat(const int16_t endnum, const int16_t temph, const int16_t tempb #endif inline void _lcd_spindle_laser_off() { set_spindle_laser_enabled(false); } + void set_spindle_direction(bool); inline void _lcd_spindle_laser_on(const bool is_M4) { #if SPINDLE_DIR_CHANGE set_spindle_direction(is_M4); @@ -329,7 +330,7 @@ void _lcd_preheat(const int16_t endnum, const int16_t temph, const int16_t tempb MENU_BACK(MSG_MAIN); if (spindle_laser_enabled()) { #if ENABLED(SPINDLE_LASER_PWM) - MENU_ITEM_EDIT_CALLBACK(int3, MSG_LASER_POWER, &spindle_laser_power, SPEED_POWER_MIN, SPEED_POWER_MAX, update_spindle_laser_power); + MENU_ITEM_EDIT_CALLBACK(uint8, MSG_LASER_POWER, &spindle_laser_power, SPEED_POWER_MIN, SPEED_POWER_MAX, update_spindle_laser_power); #endif MENU_ITEM(function, MSG_LASER_OFF, _lcd_spindle_laser_off); } @@ -417,7 +418,7 @@ void menu_temperature() { #if ENABLED(SPINDLE_LASER_ENABLE) MENU_ITEM(submenu, MSG_LASER_MENU, menu_spindle_laser); #endif - + #if HAS_TEMP_HOTEND // diff --git a/Marlin/src/lcd/menu/menu_tmc.cpp b/Marlin/src/lcd/menu/menu_tmc.cpp index 585af5b5b6..1a6bf8f844 100644 --- a/Marlin/src/lcd/menu/menu_tmc.cpp +++ b/Marlin/src/lcd/menu/menu_tmc.cpp @@ -212,7 +212,7 @@ void menu_tmc_current() { #if ENABLED(SENSORLESS_HOMING) - #define TMC_EDIT_STORED_SGT(ST) MENU_ITEM_EDIT_CALLBACK(int8, MSG_##ST, &stepper##ST.stored.homing_thrs, -64, 63, refresh_homing_thrs_##ST); + #define TMC_EDIT_STORED_SGT(ST) MENU_ITEM_EDIT_CALLBACK(int4, MSG_##ST, &stepper##ST.stored.homing_thrs, stepper##ST.sgt_min, stepper##ST.sgt_max, refresh_homing_thrs_##ST); #if X_SENSORLESS void refresh_homing_thrs_X() { stepperX.refresh_homing_thrs(); } diff --git a/Marlin/src/lcd/menu/menu_ubl.cpp b/Marlin/src/lcd/menu/menu_ubl.cpp index 2bb9409794..cd8262b611 100644 --- a/Marlin/src/lcd/menu/menu_ubl.cpp +++ b/Marlin/src/lcd/menu/menu_ubl.cpp @@ -107,15 +107,15 @@ void lcd_z_offset_edit_setup(const float &initial) { * UBL Build Custom Mesh Command */ void _lcd_ubl_build_custom_mesh() { - char UBL_LCD_GCODE[20]; - enqueue_and_echo_commands_P(PSTR("G28")); + char ubl_lcd_gcode[20]; + queue.inject_P(PSTR("G28")); #if HAS_HEATED_BED - sprintf_P(UBL_LCD_GCODE, PSTR("M190 S%i"), custom_bed_temp); - lcd_enqueue_command(UBL_LCD_GCODE); + sprintf_P(ubl_lcd_gcode, PSTR("M190 S%i"), custom_bed_temp); + lcd_enqueue_one_now(ubl_lcd_gcode); #endif - sprintf_P(UBL_LCD_GCODE, PSTR("M109 S%i"), custom_hotend_temp); - lcd_enqueue_command(UBL_LCD_GCODE); - enqueue_and_echo_commands_P(PSTR("G29 P1")); + sprintf_P(ubl_lcd_gcode, PSTR("M109 S%i"), custom_hotend_temp); + lcd_enqueue_one_now(ubl_lcd_gcode); + queue.inject_P(PSTR("G29 P1")); } /** @@ -141,11 +141,11 @@ void _lcd_ubl_custom_mesh() { * UBL Adjust Mesh Height Command */ void _lcd_ubl_adjust_height_cmd() { - char UBL_LCD_GCODE[16]; + char ubl_lcd_gcode[16]; const int ind = ubl_height_amount > 0 ? 9 : 10; - strcpy_P(UBL_LCD_GCODE, PSTR("G29 P6 C -")); - sprintf_P(&UBL_LCD_GCODE[ind], PSTR(".%i"), ABS(ubl_height_amount)); - lcd_enqueue_command(UBL_LCD_GCODE); + strcpy_P(ubl_lcd_gcode, PSTR("G29 P6 C -")); + sprintf_P(&ubl_lcd_gcode[ind], PSTR(".%i"), ABS(ubl_height_amount)); + lcd_enqueue_one_now(ubl_lcd_gcode); } /** @@ -187,7 +187,7 @@ void _lcd_ubl_edit_mesh() { * UBL Validate Custom Mesh Command */ void _lcd_ubl_validate_custom_mesh() { - char UBL_LCD_GCODE[24]; + char ubl_lcd_gcode[24]; const int temp = #if HAS_HEATED_BED custom_bed_temp @@ -195,9 +195,9 @@ void _lcd_ubl_validate_custom_mesh() { 0 #endif ; - sprintf_P(UBL_LCD_GCODE, PSTR("G26 C B%i H%i P"), temp, custom_hotend_temp); - lcd_enqueue_commands_P(PSTR("G28")); - lcd_enqueue_command(UBL_LCD_GCODE); + sprintf_P(ubl_lcd_gcode, PSTR("G26 C B%i H%i P"), temp, custom_hotend_temp); + lcd_enqueue_one_now_P(PSTR("G28")); + lcd_enqueue_one_now(ubl_lcd_gcode); } /** @@ -228,9 +228,9 @@ void _lcd_ubl_validate_mesh() { * UBL Grid Leveling Command */ void _lcd_ubl_grid_level_cmd() { - char UBL_LCD_GCODE[12]; - sprintf_P(UBL_LCD_GCODE, PSTR("G29 J%i"), side_points); - lcd_enqueue_command(UBL_LCD_GCODE); + char ubl_lcd_gcode[12]; + sprintf_P(ubl_lcd_gcode, PSTR("G29 J%i"), side_points); + lcd_enqueue_one_now(ubl_lcd_gcode); } /** @@ -269,9 +269,9 @@ void _lcd_ubl_mesh_leveling() { * UBL Fill-in Amount Mesh Command */ void _lcd_ubl_fillin_amount_cmd() { - char UBL_LCD_GCODE[18]; - sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 R C.%i"), ubl_fillin_amount); - lcd_enqueue_command(UBL_LCD_GCODE); + char ubl_lcd_gcode[18]; + sprintf_P(ubl_lcd_gcode, PSTR("G29 P3 R C.%i"), ubl_fillin_amount); + lcd_enqueue_one_now(ubl_lcd_gcode); } /** @@ -361,22 +361,22 @@ void _lcd_ubl_build_mesh() { * UBL Load Mesh Command */ void _lcd_ubl_load_mesh_cmd() { - char UBL_LCD_GCODE[25]; - sprintf_P(UBL_LCD_GCODE, PSTR("G29 L%i"), ubl_storage_slot); - lcd_enqueue_command(UBL_LCD_GCODE); - sprintf_P(UBL_LCD_GCODE, PSTR("M117 " MSG_MESH_LOADED), ubl_storage_slot); - lcd_enqueue_command(UBL_LCD_GCODE); + char ubl_lcd_gcode[25]; + sprintf_P(ubl_lcd_gcode, PSTR("G29 L%i"), ubl_storage_slot); + lcd_enqueue_one_now(ubl_lcd_gcode); + sprintf_P(ubl_lcd_gcode, PSTR("M117 " MSG_MESH_LOADED), ubl_storage_slot); + lcd_enqueue_one_now(ubl_lcd_gcode); } /** * UBL Save Mesh Command */ void _lcd_ubl_save_mesh_cmd() { - char UBL_LCD_GCODE[25]; - sprintf_P(UBL_LCD_GCODE, PSTR("G29 S%i"), ubl_storage_slot); - lcd_enqueue_command(UBL_LCD_GCODE); - sprintf_P(UBL_LCD_GCODE, PSTR("M117 " MSG_MESH_SAVED), ubl_storage_slot); - lcd_enqueue_command(UBL_LCD_GCODE); + char ubl_lcd_gcode[25]; + sprintf_P(ubl_lcd_gcode, PSTR("G29 S%i"), ubl_storage_slot); + lcd_enqueue_one_now(ubl_lcd_gcode); + sprintf_P(ubl_lcd_gcode, PSTR("M117 " MSG_MESH_SAVED), ubl_storage_slot); + lcd_enqueue_one_now(ubl_lcd_gcode); } /** @@ -420,11 +420,11 @@ void _lcd_ubl_map_homing() { * UBL LCD "radar" map point editing */ void _lcd_ubl_map_lcd_edit_cmd() { - char UBL_LCD_GCODE[50], str[10], str2[10]; + char ubl_lcd_gcode[50], str[10], str2[10]; dtostrf(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]), 0, 2, str); dtostrf(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]), 0, 2, str2); - snprintf_P(UBL_LCD_GCODE, sizeof(UBL_LCD_GCODE), PSTR("G29 P4 X%s Y%s R%i"), str, str2, n_edit_pts); - lcd_enqueue_command(UBL_LCD_GCODE); + snprintf_P(ubl_lcd_gcode, sizeof(ubl_lcd_gcode), PSTR("G29 P4 X%s Y%s R%i"), str, str2, n_edit_pts); + lcd_enqueue_one_now(ubl_lcd_gcode); } /** @@ -529,7 +529,7 @@ void _lcd_ubl_output_map_lcd() { void _lcd_ubl_output_map_lcd_cmd() { if (!all_axes_known()) { set_all_unhomed(); - enqueue_and_echo_commands_P(PSTR("G28")); + queue.inject_P(PSTR("G28")); } ui.goto_screen(_lcd_ubl_map_homing); } diff --git a/Marlin/src/lcd/thermistornames.h b/Marlin/src/lcd/thermistornames.h index bb210b2dde..09162e77f4 100644 --- a/Marlin/src/lcd/thermistornames.h +++ b/Marlin/src/lcd/thermistornames.h @@ -74,6 +74,8 @@ #define THERMISTOR_NAME "E3104FXT (alt)" #elif THERMISTOR_ID == 13 #define THERMISTOR_NAME "Hisens 3950" +#elif THERMISTOR_ID == 18 + #define THERMISTOR_NAME "ATC Semitec 204GT-2" #elif THERMISTOR_ID == 20 #define THERMISTOR_NAME "PT100 UltiMB" #elif THERMISTOR_ID == 60 diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp index a044886793..3d2c25f267 100644 --- a/Marlin/src/lcd/ultralcd.cpp +++ b/Marlin/src/lcd/ultralcd.cpp @@ -22,6 +22,10 @@ #include "../inc/MarlinConfigPre.h" +#ifdef LED_BACKLIGHT_TIMEOUT + #include "../feature/leds/leds.h" +#endif + // These displays all share the MarlinUI class #if HAS_DISPLAY #include "ultralcd.h" @@ -31,6 +35,9 @@ #if ENABLED(EXTENSIBLE_UI) #define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80u) #endif + #if ENABLED(HOST_ACTION_COMMANDS) + #include "../feature/host_actions.h" + #endif #endif #if HAS_SPI_LCD @@ -97,7 +104,7 @@ #endif #endif -#if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) +#if ENABLED(SDSUPPORT) uint8_t lcd_sd_status; #endif @@ -193,20 +200,49 @@ millis_t next_button_update_ms; #endif - void _wrap_string(uint8_t &x, uint8_t &y, const char * const string, read_byte_cb_t cb_read_byte) { + void _wrap_string(uint8_t &x, uint8_t &y, const char * const string, read_byte_cb_t cb_read_byte, bool wordwrap/*=false*/) { SETCURSOR(x, y); - if (string) { - uint8_t *p = (uint8_t*)string; + if (!string) return; + + auto _newline = [&x, &y]() { + x = 0; y++; // move x to string len (plus space) + SETCURSOR(0, y); // 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 (x + c > LCD_WIDTH && x >= (LCD_WIDTH) / 4) _newline(); // should it wrap? + c += !eol; // +1 so the space will be printed + x += c; // advance x 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 { for (;;) { - wchar_t ch; p = get_utf8_value_cb(p, cb_read_byte, &ch); if (!ch) break; lcd_put_wchar(ch); x++; - if (x >= LCD_WIDTH) { - x = 0; y++; - SETCURSOR(0, y); - } + if (x >= LCD_WIDTH) _newline(); } } } @@ -218,7 +254,7 @@ millis_t next_button_update_ms; x = (LCD_WIDTH - plen - slen) / 2; y = LCD_HEIGHT > 3 ? 1 : 0; } - wrap_string_P(x, y, pref); + wrap_string_P(x, y, pref, true); if (string) { if (x) { x = 0; y++; } // Move to the start of the next line wrap_string(x, y, string); @@ -279,8 +315,10 @@ void MarlinUI::init() { #endif // HAS_SHIFT_ENCODER - #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) - SET_INPUT_PULLUP(SD_DETECT_PIN); + #if ENABLED(SDSUPPORT) + #if PIN_EXISTS(SD_DETECT) + SET_INPUT_PULLUP(SD_DETECT_PIN); + #endif lcd_sd_status = 2; // UNKNOWN #endif @@ -403,7 +441,7 @@ bool MarlinUI::get_blink() { #endif // HAS_LCD_MENU - if (!homed && RRK(EN_KEYPAD_F1)) enqueue_and_echo_commands_P(PSTR("G28")); + if (!homed && RRK(EN_KEYPAD_F1)) queue.inject_P(PSTR("G28")); return true; } @@ -531,6 +569,16 @@ void MarlinUI::status_screen() { void MarlinUI::kill_screen(PGM_P lcd_msg) { init(); set_alert_status_P(lcd_msg); + + // RED ALERT. RED ALERT. + #ifdef LED_BACKLIGHT_TIMEOUT + leds.set_color(LEDColorRed()); + #ifdef NEOPIXEL_BKGD_LED_INDEX + pixels.setPixelColor(NEOPIXEL_BKGD_LED_INDEX, 255, 0, 0, 0); + pixels.show(); + #endif + #endif + draw_kill_screen(); } @@ -682,6 +730,10 @@ void MarlinUI::update() { static millis_t next_lcd_update_ms; millis_t ms = millis(); + #ifdef LED_BACKLIGHT_TIMEOUT + leds.update_timeout(powersupply_on); + #endif + #if HAS_LCD_MENU #if LCD_TIMEOUT_TO_STATUS @@ -716,7 +768,7 @@ void MarlinUI::update() { #endif // HAS_LCD_MENU - #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) + #if ENABLED(SDSUPPORT) const uint8_t sd_status = (uint8_t)IS_SD_INSERTED(); if (sd_status != lcd_sd_status && detected()) { @@ -732,22 +784,30 @@ void MarlinUI::update() { else set_status_P(PSTR(MSG_SD_INSERTED)); } - else { - card.release(); - if (old_sd_status != 2) { - set_status_P(PSTR(MSG_SD_REMOVED)); - if (!on_status_screen()) return_to_status(); + #if PIN_EXISTS(SD_DETECT) + else { + card.release(); + if (old_sd_status != 2) { + set_status_P(PSTR(MSG_SD_REMOVED)); + if (!on_status_screen()) return_to_status(); + } } - } + + init_lcd(); // May revive the LCD if static electricity killed it + + #endif refresh(); - init_lcd(); // May revive the LCD if static electricity killed it ms = millis(); next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL; // delay LCD update until after SD activity completes + + #ifdef LED_BACKLIGHT_TIMEOUT + leds.reset_timeout(ms); + #endif } - #endif // SDSUPPORT && SD_DETECT_PIN + #endif // SDSUPPORT if (ELAPSED(ms, next_lcd_update_ms) #if HAS_GRAPHICAL_LCD @@ -819,10 +879,16 @@ void MarlinUI::update() { encoderPosition += (encoderDiff * encoderMultiplier) / (ENCODER_PULSES_PER_STEP); encoderDiff = 0; } + #if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS; #endif + refresh(LCDVIEW_REDRAW_NOW); + + #ifdef LED_BACKLIGHT_TIMEOUT + leds.reset_timeout(ms); + #endif } #endif @@ -1358,6 +1424,73 @@ void MarlinUI::update() { set_status_P(msg, -1); } + #if ENABLED(SDSUPPORT) + extern bool wait_for_user, wait_for_heatup; + #endif + + void MarlinUI::abort_print() { + #if ENABLED(SDSUPPORT) + wait_for_heatup = wait_for_user = false; + card.flag.abort_sd_printing = true; + #endif + #ifdef ACTION_ON_CANCEL + host_action_cancel(); + #endif + #if ENABLED(HOST_PROMPT_SUPPORT) + host_prompt_open(PROMPT_INFO, PSTR("UI Abort")); + #endif + print_job_timer.stop(); + set_status_P(PSTR(MSG_PRINT_ABORTED)); + #if HAS_SPI_LCD + return_to_status(); + #endif + } + + #if ANY(PARK_HEAD_ON_PAUSE, SDSUPPORT) + #include "../gcode/queue.h" + #endif + + void MarlinUI::pause_print() { + #if HAS_LCD_MENU + synchronize(PSTR(MSG_PAUSE_PRINT)); + #endif + + #if ENABLED(POWER_LOSS_RECOVERY) + if (recovery.enabled) recovery.save(true, false); + #endif + + #if ENABLED(HOST_PROMPT_SUPPORT) + host_prompt_open(PROMPT_PAUSE_RESUME, PSTR("UI Pause"), PSTR("Resume")); + #endif + + set_status_P(PSTR(MSG_PRINT_PAUSED)); + + #if ENABLED(PARK_HEAD_ON_PAUSE) + #if HAS_SPI_LCD + lcd_pause_show_message(PAUSE_MESSAGE_PAUSING, PAUSE_MODE_PAUSE_PRINT); // Show message immediately to let user know about pause in progress + #endif + queue.inject_P(PSTR("M25 P\nM24")); + #elif ENABLED(SDSUPPORT) + queue.inject_P(PSTR("M25")); + #elif defined(ACTION_ON_PAUSE) + host_action_pause(); + #endif + } + + void MarlinUI::resume_print() { + reset_status(); + #if ENABLED(PARK_HEAD_ON_PAUSE) + wait_for_heatup = wait_for_user = false; + #endif + #if ENABLED(SDSUPPORT) + if (card.isPaused()) queue.inject_P(PSTR("M24")); + #endif + #ifdef ACTION_ON_RESUME + host_action_resume(); + #endif + print_job_timer.start(); // Also called by M24 + } + #if HAS_PRINT_PROGRESS uint8_t MarlinUI::get_progress() { #if ENABLED(LCD_SET_PROGRESS_MANUALLY) diff --git a/Marlin/src/lcd/ultralcd.h b/Marlin/src/lcd/ultralcd.h index fc573211b3..aa4cc47766 100644 --- a/Marlin/src/lcd/ultralcd.h +++ b/Marlin/src/lcd/ultralcd.h @@ -74,9 +74,9 @@ #include "fontutils.h" - void _wrap_string(uint8_t &x, uint8_t &y, const char * const string, read_byte_cb_t cb_read_byte); - inline void wrap_string_P(uint8_t &x, uint8_t &y, PGM_P const pstr) { _wrap_string(x, y, pstr, read_byte_rom); } - inline void wrap_string(uint8_t &x, uint8_t &y, const char * const string) { _wrap_string(x, y, string, read_byte_ram); } + void _wrap_string(uint8_t &x, uint8_t &y, const char * const string, read_byte_cb_t cb_read_byte, const bool wordwrap=false); + inline void wrap_string_P(uint8_t &x, uint8_t &y, PGM_P const pstr, const bool wordwrap=false) { _wrap_string(x, y, pstr, read_byte_rom, wordwrap); } + inline void wrap_string(uint8_t &x, uint8_t &y, const char * const string, const bool wordwrap=false) { _wrap_string(x, y, string, read_byte_ram, wordwrap); } #if ENABLED(SDSUPPORT) #include "../sd/cardreader.h" @@ -286,6 +286,10 @@ public: static char* status_and_len(uint8_t &len); #endif + static void abort_print(); + static void pause_print(); + static void resume_print(); + #if HAS_PRINT_PROGRESS #if ENABLED(LCD_SET_PROGRESS_MANUALLY) static uint8_t progress_bar_percent; diff --git a/Marlin/src/libs/crc16.cpp b/Marlin/src/libs/crc16.cpp new file mode 100644 index 0000000000..a5a8a2809e --- /dev/null +++ b/Marlin/src/libs/crc16.cpp @@ -0,0 +1,32 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "crc16.h" + +void crc16(uint16_t *crc, const void * const data, uint16_t cnt) { + uint8_t *ptr = (uint8_t *)data; + while (cnt--) { + *crc = (uint16_t)(*crc ^ (uint16_t)(((uint16_t)*ptr++) << 8)); + for (uint8_t i = 0; i < 8; i++) + *crc = (uint16_t)((*crc & 0x8000) ? ((uint16_t)(*crc << 1) ^ 0x1021) : (*crc << 1)); + } +} diff --git a/Marlin/src/libs/crc16.h b/Marlin/src/libs/crc16.h new file mode 100644 index 0000000000..507ad48ef3 --- /dev/null +++ b/Marlin/src/libs/crc16.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +void crc16(uint16_t *crc, const void * const data, uint16_t cnt); diff --git a/Marlin/src/libs/numtostr.cpp b/Marlin/src/libs/numtostr.cpp new file mode 100644 index 0000000000..09ebf64d2f --- /dev/null +++ b/Marlin/src/libs/numtostr.cpp @@ -0,0 +1,289 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "numtostr.h" +#include "../core/utility.h" + +char conv[8] = { 0 }; + +#define DIGIT(n) ('0' + (n)) +#define DIGIMOD(n, f) DIGIT((n)/(f) % 10) +#define RJDIGIT(n, f) ((n) >= (f) ? DIGIMOD(n, f) : ' ') +#define MINUSOR(n, alt) (n >= 0 ? (alt) : (n = -n, '-')) + +// Convert a full-range unsigned 8bit int to a percentage +char* ui8tostr4pct(const uint8_t i) { + const uint8_t n = ui8_to_percent(i); + conv[3] = RJDIGIT(n, 100); + conv[4] = RJDIGIT(n, 10); + conv[5] = DIGIMOD(n, 1); + conv[6] = '%'; + return &conv[3]; +} + +// Convert unsigned 8bit int to string 123 format +char* ui8tostr3(const uint8_t i) { + conv[4] = RJDIGIT(i, 100); + conv[5] = RJDIGIT(i, 10); + conv[6] = DIGIMOD(i, 1); + return &conv[4]; +} + +// Convert signed 8bit int to rj string with 123 or -12 format +char* i8tostr3(const int8_t x) { + int xx = x; + conv[4] = MINUSOR(xx, RJDIGIT(xx, 100)); + conv[5] = RJDIGIT(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return &conv[4]; +} + +// Convert unsigned 16bit int to string 123 format +char* ui16tostr3(const uint16_t xx) { + conv[4] = RJDIGIT(xx, 100); + conv[5] = RJDIGIT(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return &conv[4]; +} + +// Convert unsigned 16bit int to string 1234 format +char* ui16tostr4(const uint16_t xx) { + conv[3] = RJDIGIT(xx, 1000); + conv[4] = RJDIGIT(xx, 100); + conv[5] = RJDIGIT(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return &conv[3]; +} + +// Convert signed 16bit int to rj string with 123 or -12 format +char* i16tostr3(const int16_t x) { + int xx = x; + conv[4] = MINUSOR(xx, RJDIGIT(xx, 100)); + conv[5] = RJDIGIT(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return &conv[4]; +} + +// Convert unsigned 16bit int to lj string with 123 format +char* i16tostr3left(const int16_t i) { + char *str = &conv[6]; + *str = DIGIMOD(i, 1); + if (i >= 10) { + *(--str) = DIGIMOD(i, 10); + if (i >= 100) + *(--str) = DIGIMOD(i, 100); + } + return str; +} + +// Convert signed 16bit int to rj string with 1234, _123, -123, _-12, or __-1 format +char* i16tostr4sign(const int16_t i) { + const bool neg = i < 0; + const int ii = neg ? -i : i; + if (i >= 1000) { + conv[3] = DIGIMOD(ii, 1000); + conv[4] = DIGIMOD(ii, 100); + conv[5] = DIGIMOD(ii, 10); + } + else if (ii >= 100) { + conv[3] = neg ? '-' : ' '; + conv[4] = DIGIMOD(ii, 100); + conv[5] = DIGIMOD(ii, 10); + } + else { + conv[3] = ' '; + conv[4] = ' '; + if (ii >= 10) { + conv[4] = neg ? '-' : ' '; + conv[5] = DIGIMOD(ii, 10); + } + else { + conv[5] = neg ? '-' : ' '; + } + } + conv[6] = DIGIMOD(ii, 1); + return &conv[3]; +} + +// Convert unsigned float to string with 1.23 format +char* ftostr12ns(const float &f) { + const long i = ((f < 0 ? -f : f) * 1000 + 5) / 10; + conv[3] = DIGIMOD(i, 100); + conv[4] = '.'; + conv[5] = DIGIMOD(i, 10); + conv[6] = DIGIMOD(i, 1); + return &conv[3]; +} + +// Convert signed float to fixed-length string with 12.34 / -2.34 format or 123.45 / -23.45 format +char* ftostr42_52(const float &f) { + if (f <= -10 || f >= 100) return ftostr52(f); // need more digits + long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; + conv[2] = (f >= 0 && f < 10) ? ' ' : MINUSOR(i, DIGIMOD(i, 1000)); + conv[3] = DIGIMOD(i, 100); + conv[4] = '.'; + conv[5] = DIGIMOD(i, 10); + conv[6] = DIGIMOD(i, 1); + return &conv[2]; +} + +// Convert signed float to fixed-length string with 023.45 / -23.45 format +char* ftostr52(const float &f) { + long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; + conv[1] = MINUSOR(i, DIGIMOD(i, 10000)); + conv[2] = DIGIMOD(i, 1000); + conv[3] = DIGIMOD(i, 100); + conv[4] = '.'; + conv[5] = DIGIMOD(i, 10); + conv[6] = DIGIMOD(i, 1); + return &conv[1]; +} + +#if ENABLED(LCD_DECIMAL_SMALL_XY) + + // Convert float to rj string with 1234, _123, -123, _-12, 12.3, _1.2, or -1.2 format + char* ftostr4sign(const float &f) { + const int i = (f * 100 + (f < 0 ? -5: 5)) / 10; + if (!WITHIN(i, -99, 999)) return i16tostr4sign((int)f); + const bool neg = i < 0; + const int ii = neg ? -i : i; + conv[3] = neg ? '-' : (ii >= 100 ? DIGIMOD(ii, 100) : ' '); + conv[4] = DIGIMOD(ii, 10); + conv[5] = '.'; + conv[6] = DIGIMOD(ii, 1); + return &conv[3]; + } + +#endif // LCD_DECIMAL_SMALL_XY + +// Convert float to fixed-length string with +123.4 / -123.4 format +char* ftostr41sign(const float &f) { + int i = (f * 100 + (f < 0 ? -5: 5)) / 10; + conv[1] = MINUSOR(i, '+'); + conv[2] = DIGIMOD(i, 1000); + conv[3] = DIGIMOD(i, 100); + conv[4] = DIGIMOD(i, 10); + conv[5] = '.'; + conv[6] = DIGIMOD(i, 1); + return &conv[1]; +} + +// Convert signed float to string (6 digit) with -1.234 / _0.000 / +1.234 format +char* ftostr43sign(const float &f, char plus/*=' '*/) { + long i = (f * 10000 + (f < 0 ? -5: 5)) / 10; + conv[1] = i ? MINUSOR(i, plus) : ' '; + conv[2] = DIGIMOD(i, 1000); + conv[3] = '.'; + conv[4] = DIGIMOD(i, 100); + conv[5] = DIGIMOD(i, 10); + conv[6] = DIGIMOD(i, 1); + return &conv[1]; +} + +// Convert signed float to string (5 digit) with -1.2345 / _0.0000 / +1.2345 format +char* ftostr54sign(const float &f, char plus/*=' '*/) { + long i = (f * 100000 + (f < 0 ? -5: 5)) / 10; + conv[0] = i ? MINUSOR(i, plus) : ' '; + conv[1] = DIGIMOD(i, 10000); + conv[2] = '.'; + conv[3] = DIGIMOD(i, 1000); + conv[4] = DIGIMOD(i, 100); + conv[5] = DIGIMOD(i, 10); + conv[6] = DIGIMOD(i, 1); + return &conv[0]; +} + +// Convert unsigned float to rj string with 12345 format +char* ftostr5rj(const float &f) { + const long i = ((f < 0 ? -f : f) * 10 + 5) / 10; + conv[2] = RJDIGIT(i, 10000); + conv[3] = RJDIGIT(i, 1000); + conv[4] = RJDIGIT(i, 100); + conv[5] = RJDIGIT(i, 10); + conv[6] = DIGIMOD(i, 1); + return &conv[2]; +} + +// Convert signed float to string with +1234.5 format +char* ftostr51sign(const float &f) { + long i = (f * 100 + (f < 0 ? -5: 5)) / 10; + conv[0] = MINUSOR(i, '+'); + conv[1] = DIGIMOD(i, 10000); + conv[2] = DIGIMOD(i, 1000); + conv[3] = DIGIMOD(i, 100); + conv[4] = DIGIMOD(i, 10); + conv[5] = '.'; + conv[6] = DIGIMOD(i, 1); + return conv; +} + +// Convert signed float to string with +123.45 format +char* ftostr52sign(const float &f) { + long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; + conv[0] = MINUSOR(i, '+'); + conv[1] = DIGIMOD(i, 10000); + conv[2] = DIGIMOD(i, 1000); + conv[3] = DIGIMOD(i, 100); + conv[4] = '.'; + conv[5] = DIGIMOD(i, 10); + conv[6] = DIGIMOD(i, 1); + return conv; +} + +// Convert unsigned float to string with 1234.5 format omitting trailing zeros +char* ftostr51rj(const float &f) { + const long i = ((f < 0 ? -f : f) * 100 + 5) / 10; + conv[0] = ' '; + conv[1] = RJDIGIT(i, 10000); + conv[2] = RJDIGIT(i, 1000); + conv[3] = RJDIGIT(i, 100); + conv[4] = DIGIMOD(i, 10); + conv[5] = '.'; + conv[6] = DIGIMOD(i, 1); + return conv; +} + +// Convert signed float to space-padded string with -_23.4_ format +char* ftostr52sp(const float &f) { + long i = (f * 1000 + (f < 0 ? -5: 5)) / 10; + uint8_t dig; + conv[0] = MINUSOR(i, ' '); + conv[1] = RJDIGIT(i, 10000); + conv[2] = RJDIGIT(i, 1000); + conv[3] = DIGIMOD(i, 100); + + if ((dig = i % 10)) { // second digit after decimal point? + conv[4] = '.'; + conv[5] = DIGIMOD(i, 10); + conv[6] = DIGIT(dig); + } + else { + if ((dig = (i / 10) % 10)) { // first digit after decimal point? + conv[4] = '.'; + conv[5] = DIGIT(dig); + } + else // nothing after decimal point + conv[4] = conv[5] = ' '; + conv[6] = ' '; + } + return conv; +} diff --git a/Marlin/src/libs/numtostr.h b/Marlin/src/libs/numtostr.h new file mode 100644 index 0000000000..a0da4804ed --- /dev/null +++ b/Marlin/src/libs/numtostr.h @@ -0,0 +1,92 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../inc/MarlinConfigPre.h" + +// Convert a full-range unsigned 8bit int to a percentage +char* ui8tostr4pct(const uint8_t i); + +// Convert uint8_t to string with 123 format +char* ui8tostr3(const uint8_t i); + +// Convert int8_t to string with 123 format +char* i8tostr3(const int8_t x); + +// Convert uint16_t to string with 123 format +char* ui16tostr3(const uint16_t x); + +// Convert uint16_t to string with 1234 format +char* ui16tostr4(const uint16_t x); + +// Convert int16_t to string with 123 format +char* i16tostr3(const int16_t x); + +// Convert unsigned int to lj string with 123 format +char* i16tostr3left(const int16_t xx); + +// Convert signed int to rj string with _123, -123, _-12, or __-1 format +char* i16tostr4sign(const int16_t x); + +// Convert unsigned float to string with 1.23 format +char* ftostr12ns(const float &x); + +// Convert signed float to fixed-length string with 12.34 / -2.34 or 023.45 / -23.45 format +char* ftostr42_52(const float &x); + +// Convert signed float to fixed-length string with 023.45 / -23.45 format +char* ftostr52(const float &x); + +// Convert float to fixed-length string with +123.4 / -123.4 format +char* ftostr41sign(const float &x); + +// Convert signed float to string (6 digit) with -1.234 / _0.000 / +1.234 format +char* ftostr43sign(const float &x, char plus=' '); + +// Convert signed float to string (5 digit) with -1.2345 / _0.0000 / +1.2345 format +char* ftostr54sign(const float &x, char plus=' '); + +// Convert unsigned float to rj string with 12345 format +char* ftostr5rj(const float &x); + +// Convert signed float to string with +1234.5 format +char* ftostr51sign(const float &x); + +// Convert signed float to space-padded string with -_23.4_ format +char* ftostr52sp(const float &x); + +// Convert signed float to string with +123.45 format +char* ftostr52sign(const float &x); + +// Convert unsigned float to string with 1234.5 format omitting trailing zeros +char* ftostr51rj(const float &x); + +// Convert float to rj string with 123 or -12 format +FORCE_INLINE char* ftostr3(const float &x) { return i16tostr3(int16_t(x + (x < 0 ? -0.5f : 0.5f))); } + +#if ENABLED(LCD_DECIMAL_SMALL_XY) + // Convert float to rj string with 1234, _123, 12.3, _1.2, -123, _-12, or -1.2 format + char* ftostr4sign(const float &fx); +#else + // Convert float to rj string with 1234, _123, -123, __12, _-12, ___1, or __-1 format + FORCE_INLINE char* ftostr4sign(const float &x) { return i16tostr4sign(int16_t(x + (x < 0 ? -0.5f : 0.5f))); } +#endif diff --git a/Marlin/src/module/configuration_store.cpp b/Marlin/src/module/configuration_store.cpp index df9f62fce8..fd0ea2f5f0 100644 --- a/Marlin/src/module/configuration_store.cpp +++ b/Marlin/src/module/configuration_store.cpp @@ -1051,13 +1051,13 @@ void MarlinSettings::postprocess() { tmc_sgt_t tmc_sgt = { 0, 0, 0 }; #if USE_SENSORLESS #if X_SENSORLESS - tmc_sgt.X = stepperX.sgt(); + tmc_sgt.X = stepperX.homing_threshold(); #endif #if Y_SENSORLESS - tmc_sgt.Y = stepperY.sgt(); + tmc_sgt.Y = stepperY.homing_threshold(); #endif #if Z_SENSORLESS - tmc_sgt.Z = stepperZ.sgt(); + tmc_sgt.Z = stepperZ.homing_threshold(); #endif #endif EEPROM_WRITE(tmc_sgt); @@ -1834,29 +1834,29 @@ void MarlinSettings::postprocess() { if (!validating) { #ifdef X_STALL_SENSITIVITY #if AXIS_HAS_STALLGUARD(X) - stepperX.sgt(tmc_sgt.X); + stepperX.homing_threshold(tmc_sgt.X); #endif #if AXIS_HAS_STALLGUARD(X2) - stepperX2.sgt(tmc_sgt.X); + stepperX2.homing_threshold(tmc_sgt.X); #endif #endif #ifdef Y_STALL_SENSITIVITY #if AXIS_HAS_STALLGUARD(Y) - stepperY.sgt(tmc_sgt.Y); + stepperY.homing_threshold(tmc_sgt.Y); #endif #if AXIS_HAS_STALLGUARD(Y2) - stepperY2.sgt(tmc_sgt.Y); + stepperY2.homing_threshold(tmc_sgt.Y); #endif #endif #ifdef Z_STALL_SENSITIVITY #if AXIS_HAS_STALLGUARD(Z) - stepperZ.sgt(tmc_sgt.Z); + stepperZ.homing_threshold(tmc_sgt.Z); #endif #if AXIS_HAS_STALLGUARD(Z2) - stepperZ2.sgt(tmc_sgt.Z); + stepperZ2.homing_threshold(tmc_sgt.Z); #endif #if AXIS_HAS_STALLGUARD(Z3) - stepperZ3.sgt(tmc_sgt.Z); + stepperZ3.homing_threshold(tmc_sgt.Z); #endif #endif } @@ -3259,13 +3259,13 @@ void MarlinSettings::reset() { #if X_SENSORLESS || Y_SENSORLESS || Z_SENSORLESS say_M914(); #if X_SENSORLESS - SERIAL_ECHOPAIR(" X", stepperX.sgt()); + SERIAL_ECHOPAIR(" X", stepperX.homing_threshold()); #endif #if Y_SENSORLESS - SERIAL_ECHOPAIR(" Y", stepperY.sgt()); + SERIAL_ECHOPAIR(" Y", stepperY.homing_threshold()); #endif #if Z_SENSORLESS - SERIAL_ECHOPAIR(" Z", stepperZ.sgt()); + SERIAL_ECHOPAIR(" Z", stepperZ.homing_threshold()); #endif SERIAL_EOL(); #endif @@ -3278,20 +3278,20 @@ void MarlinSettings::reset() { say_M914(); SERIAL_ECHOPGM(" I1"); #if HAS_X2_SENSORLESS - SERIAL_ECHOPAIR(" X", stepperX2.sgt()); + SERIAL_ECHOPAIR(" X", stepperX2.homing_threshold()); #endif #if HAS_Y2_SENSORLESS - SERIAL_ECHOPAIR(" Y", stepperY2.sgt()); + SERIAL_ECHOPAIR(" Y", stepperY2.homing_threshold()); #endif #if HAS_Z2_SENSORLESS - SERIAL_ECHOPAIR(" Z", stepperZ2.sgt()); + SERIAL_ECHOPAIR(" Z", stepperZ2.homing_threshold()); #endif SERIAL_EOL(); #endif #if HAS_Z3_SENSORLESS say_M914(); - SERIAL_ECHOLNPAIR(" I2 Z", stepperZ3.sgt()); + SERIAL_ECHOLNPAIR(" I2 Z", stepperZ3.homing_threshold()); #endif #endif // USE_SENSORLESS diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index deba8b33a4..a70ef19da9 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -36,7 +36,7 @@ #include HAL_PATH(../HAL, endstop_interrupts.h) #endif -#if BOTH(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED, SDSUPPORT) +#if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT) #include "printcounter.h" // for print_job_timer #endif @@ -365,7 +365,7 @@ void Endstops::event_handler() { ui.status_printf_P(0, PSTR(MSG_LCD_ENDSTOPS " %c %c %c %c"), chrX, chrY, chrZ, chrP); #endif - #if BOTH(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED, SDSUPPORT) + #if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT) if (planner.abort_on_endstop_hit) { card.stopSDPrint(); quickstop_stepper(); @@ -896,7 +896,7 @@ void Endstops::update() { ES_REPORT_CHANGE(Z3_MAX); #endif SERIAL_ECHOLNPGM("\n"); - analogWrite(LED_PIN, local_LED_status); + analogWrite(pin_t(LED_PIN), local_LED_status); local_LED_status ^= 255; old_live_state_local = live_state_local; } diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index ff6e0e71c7..de4ed3ddde 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -139,7 +139,7 @@ float Planner::steps_to_mm[XYZE_N]; // (mm) Millimeters per step #endif #endif -#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) +#if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) bool Planner::abort_on_endstop_hit = false; #endif @@ -1294,16 +1294,17 @@ void Planner::check_axes_activity() { #else #if HAS_FAN0 - analogWrite(FAN_PIN, CALC_FAN_SPEED(0)); + analogWrite(pin_t(FAN_PIN), CALC_FAN_SPEED(0)); #endif #if HAS_FAN1 - analogWrite(FAN1_PIN, CALC_FAN_SPEED(1)); + analogWrite(pin_t(FAN1_PIN), CALC_FAN_SPEED(1)); #endif #if HAS_FAN2 - analogWrite(FAN2_PIN, CALC_FAN_SPEED(2)); + analogWrite(pin_t(FAN2_PIN), CALC_FAN_SPEED(2)); #endif #endif - + #else + UNUSED(tail_fan_speed); #endif // FAN_COUNT > 0 #if ENABLED(AUTOTEMP) diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index 39309a3e95..5bcb37f39a 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -287,7 +287,7 @@ class Planner { static skew_factor_t skew_factor; - #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + #if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) static bool abort_on_endstop_hit; #endif @@ -735,7 +735,7 @@ class Planner { if (cleaning_buffer_counter) { --cleaning_buffer_counter; #if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND) - if (!cleaning_buffer_counter) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + if (!cleaning_buffer_counter) queue.inject_P(PSTR(SD_FINISHED_RELEASECOMMAND)); #endif } } diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp index 207490405d..9f8d520246 100644 --- a/Marlin/src/module/probe.cpp +++ b/Marlin/src/module/probe.cpp @@ -103,6 +103,26 @@ float zprobe_zoffset; // Initialized by settings.load() #endif } +#elif ENABLED(TOUCH_MI_PROBE) + + // Move to the magnet to unlock the probe + void run_deploy_moves_script() { + #ifndef TOUCH_MI_DEPLOY_XPOS + #define TOUCH_MI_DEPLOY_XPOS 0 + #elif X_HOME_DIR > 0 && TOUCH_MI_DEPLOY_XPOS > X_MAX_BED + TemporaryGlobalEndstopsState unlock_x(false); + #endif + do_blocking_move_to_x(TOUCH_MI_DEPLOY_XPOS); + } + + // Move down to the bed to stow the probe + void run_stow_moves_script() { + const float old_pos[] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] }; + endstops.enable_z_probe(false); + do_blocking_move_to_z(TOUCH_MI_RETRACT_Z, MMM_TO_MMS(HOMING_FEEDRATE_Z)); + do_blocking_move_to(old_pos, MMM_TO_MMS(HOMING_FEEDRATE_Z)); + } + #elif ENABLED(Z_PROBE_ALLEN_KEY) void run_deploy_moves_script() { @@ -356,17 +376,15 @@ FORCE_INLINE void probe_specific_action(const bool deploy) { dock_sled(!deploy); + #elif ENABLED(BLTOUCH) + + deploy ? bltouch.deploy() : bltouch.stow(); + #elif HAS_Z_SERVO_PROBE - #if DISABLED(BLTOUCH) - MOVE_SERVO(Z_PROBE_SERVO_NR, servo_angles[Z_PROBE_SERVO_NR][deploy ? 0 : 1]); - #elif ENABLED(BLTOUCH_HS_MODE) - // In HIGH SPEED MODE, use the normal retractable probe logic in this code - // i.e. no intermediate STOWs and DEPLOYs in between individual probe actions - if (deploy) bltouch.deploy(); else bltouch.stow(); - #endif + MOVE_SERVO(Z_PROBE_SERVO_NR, servo_angles[Z_PROBE_SERVO_NR][deploy ? 0 : 1]); - #elif ENABLED(Z_PROBE_ALLEN_KEY) + #elif EITHER(TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY) deploy ? run_deploy_moves_script() : run_stow_moves_script(); @@ -427,14 +445,12 @@ bool set_probe_deployed(const bool deploy) { oldYpos = current_position[Y_AXIS]; #if ENABLED(PROBE_TRIGGERED_WHEN_STOWED_TEST) + #if USES_Z_MIN_PROBE_ENDSTOP #define PROBE_STOWED() (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING) #else #define PROBE_STOWED() (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING) #endif - #endif - - #ifdef PROBE_STOWED // Only deploy/stow if needed if (PROBE_STOWED() == deploy) { @@ -568,10 +584,12 @@ static bool do_probe_move(const float z, const float fr_mm_s) { } /** - * @details Used by probe_pt to do a single Z probe at the current position. + * @brief Probe at the current XY (possibly more than once) to find the bed Z. + * + * @details Used by probe_pt to get the bed Z height at the current XY. * Leaves current_position[Z_AXIS] at the height where the probe triggered. * - * @return The raw Z position where the probe was triggered + * @return The Z position of the bed at the current XY or NAN on error. */ static float run_z_probe() { @@ -582,7 +600,7 @@ static float run_z_probe() { const float z_probe_low_point = TEST(axis_known_position, Z_AXIS) ? -zprobe_zoffset + Z_PROBE_LOW_POINT : -10.0; // Double-probing does a fast probe followed by a slow probe - #if MULTIPLE_PROBING == 2 + #if TOTAL_PROBING == 2 // Do a first probe at the fast speed if (do_probe_move(z_probe_low_point, MMM_TO_MMS(Z_PROBE_SPEED_FAST))) { @@ -593,11 +611,11 @@ static float run_z_probe() { return NAN; } - float first_probe_z = current_position[Z_AXIS]; + const float first_probe_z = current_position[Z_AXIS]; if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("1st Probe Z:", first_probe_z); - // move up to make clearance for the probe + // Raise to give the probe clearance do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_MULTI_PROBE, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); #elif Z_PROBE_SPEED_FAST != Z_PROBE_SPEED_SLOW @@ -606,18 +624,28 @@ static float run_z_probe() { // move down quickly before doing the slow probe const float z = Z_CLEARANCE_DEPLOY_PROBE + 5.0 + (zprobe_zoffset < 0 ? -zprobe_zoffset : 0); if (current_position[Z_AXIS] > z) { - // If we don't make it to the z position (i.e. the probe triggered), move up to make clearance for the probe + // Probe down fast. If the probe never triggered, raise for probe clearance if (!do_probe_move(z, MMM_TO_MMS(Z_PROBE_SPEED_FAST))) do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); } #endif - #if MULTIPLE_PROBING > 2 - float probes_total = 0; - for (uint8_t p = MULTIPLE_PROBING + 1; --p;) { + #ifdef EXTRA_PROBING + float probes[TOTAL_PROBING]; #endif - // move down slowly to find bed + #if TOTAL_PROBING > 2 + float probes_total = 0; + for ( + #if EXTRA_PROBING + uint8_t p = 0; p < TOTAL_PROBING; p++ + #else + uint8_t p = TOTAL_PROBING; p--; + #endif + ) + #endif + { + // Probe downward slowly to find the bed if (do_probe_move(z_probe_low_point, MMM_TO_MMS(Z_PROBE_SPEED_SLOW))) { if (DEBUGGING(LEVELING)) { DEBUG_ECHOLNPGM("SLOW Probe fail!"); @@ -630,18 +658,56 @@ static float run_z_probe() { backlash.measure_with_probe(); #endif - #if MULTIPLE_PROBING > 2 - probes_total += current_position[Z_AXIS]; - if (p > 1) do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_MULTI_PROBE, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); + const float z = current_position[Z_AXIS]; + + #if EXTRA_PROBING + // Insert Z measurement into probes[]. Keep it sorted ascending. + for (uint8_t i = 0; i <= p; i++) { // Iterate the saved Zs to insert the new Z + if (i == p || probes[i] > z) { // Last index or new Z is smaller than this Z + for (int8_t m = p; --m >= i;) probes[m + 1] = probes[m]; // Shift items down after the insertion point + probes[i] = z; // Insert the new Z measurement + break; // Only one to insert. Done! + } + } + #elif TOTAL_PROBING > 2 + probes_total += z; + #else + UNUSED(z); + #endif + + #if TOTAL_PROBING > 2 + // Small Z raise after all but the last probe + if (p + #if EXTRA_PROBING + < TOTAL_PROBING - 1 + #endif + ) do_blocking_move_to_z(z + Z_CLEARANCE_MULTI_PROBE, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); + #endif } - #endif - #if MULTIPLE_PROBING > 2 + #if TOTAL_PROBING > 2 + + #if EXTRA_PROBING + // Take the center value (or average the two middle values) as the median + static constexpr int PHALF = (TOTAL_PROBING - 1) / 2; + const float middle = probes[PHALF], + median = ((TOTAL_PROBING) & 1) ? middle : (middle + probes[PHALF + 1]) * 0.5f; + + // Remove values farthest from the median + uint8_t min_avg_idx = 0, max_avg_idx = TOTAL_PROBING - 1; + for (uint8_t i = EXTRA_PROBING; i--;) + if (ABS(probes[max_avg_idx] - median) > ABS(probes[min_avg_idx] - median)) + max_avg_idx--; else min_avg_idx++; + + // Return the average value of all remaining probes. + for (uint8_t i = min_avg_idx; i <= max_avg_idx; i++) + probes_total += probes[i]; + + #endif - // Return the average value of all probes const float measured_z = probes_total * (1.0f / (MULTIPLE_PROBING)); - #elif MULTIPLE_PROBING == 2 + #elif TOTAL_PROBING == 2 const float z2 = current_position[Z_AXIS]; diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index b3f53fc4b6..17f78ae1aa 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -109,21 +109,21 @@ #endif // Add time for each stepper -#ifdef HAS_X_STEP +#if HAS_X_STEP #define ISR_START_X_STEPPER_CYCLES ISR_START_STEPPER_CYCLES #define ISR_X_STEPPER_CYCLES ISR_STEPPER_CYCLES #else #define ISR_START_X_STEPPER_CYCLES 0UL #define ISR_X_STEPPER_CYCLES 0UL #endif -#ifdef HAS_Y_STEP +#if HAS_Y_STEP #define ISR_START_Y_STEPPER_CYCLES ISR_START_STEPPER_CYCLES #define ISR_Y_STEPPER_CYCLES ISR_STEPPER_CYCLES #else #define ISR_START_Y_STEPPER_CYCLES 0UL #define ISR_Y_STEPPER_CYCLES 0UL #endif -#ifdef HAS_Z_STEP +#if HAS_Z_STEP #define ISR_START_Z_STEPPER_CYCLES ISR_START_STEPPER_CYCLES #define ISR_Z_STEPPER_CYCLES ISR_STEPPER_CYCLES #else @@ -135,13 +135,8 @@ #define ISR_START_E_STEPPER_CYCLES ISR_START_STEPPER_CYCLES #define ISR_E_STEPPER_CYCLES ISR_STEPPER_CYCLES -// If linear advance is disabled, then the loop also handles them -#if DISABLED(LIN_ADVANCE) && ENABLED(MIXING_EXTRUDER) // ToDo: ??? - // HELP ME: What is what? - // Directions are set up for MIXING_STEPPERS - like before. - // Finding the right stepper may last up to MIXING_STEPPERS loops in get_next_stepper(). - // These loops are a bit faster than advancing a bresenham counter. - // Always only one e-stepper is stepped. +// If linear advance is disabled, the loop also handles them +#if DISABLED(LIN_ADVANCE) && ENABLED(MIXING_EXTRUDER) #define ISR_START_MIXING_STEPPER_CYCLES ((MIXING_STEPPERS) * (ISR_START_STEPPER_CYCLES)) #define ISR_MIXING_STEPPER_CYCLES ((MIXING_STEPPERS) * (ISR_STEPPER_CYCLES)) #else diff --git a/Marlin/src/module/stepper_indirection.cpp b/Marlin/src/module/stepper_indirection.cpp index cb1b4113e1..3dacfc7cfb 100644 --- a/Marlin/src/module/stepper_indirection.cpp +++ b/Marlin/src/module/stepper_indirection.cpp @@ -163,8 +163,8 @@ #define __TMC_SPI_DEFINE(IC, ST, L, AI) TMCMarlin stepper##ST(ST##_CS_PIN, ST##_RSENSE) #endif - #define TMC_UART_HW_DEFINE(IC, ST, L, AI) TMCMarlin stepper##ST(&ST##_HARDWARE_SERIAL, ST##_RSENSE) - #define TMC_UART_SW_DEFINE(IC, ST, L, AI) TMCMarlin stepper##ST(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN, ST##_RSENSE, ST##_SERIAL_RX_PIN > -1) + #define TMC_UART_HW_DEFINE(IC, ST, L, AI) TMCMarlin stepper##ST(&ST##_HARDWARE_SERIAL, ST##_RSENSE, ST##_SLAVE_ADDRESS) + #define TMC_UART_SW_DEFINE(IC, ST, L, AI) TMCMarlin stepper##ST(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN, ST##_RSENSE, ST##_SLAVE_ADDRESS, ST##_SERIAL_RX_PIN > -1) #define _TMC_SPI_DEFINE(IC, ST, AI) __TMC_SPI_DEFINE(IC, ST, TMC_##ST##_LABEL, AI) #define TMC_SPI_DEFINE(ST, AI) _TMC_SPI_DEFINE(ST##_DRIVER_TYPE, ST, AI##_AXIS) @@ -234,6 +234,9 @@ chopconf.intpol = INTERPOLATE; chopconf.hend = chopper_timing.hend + 3; chopconf.hstrt = chopper_timing.hstrt - 1; + #if ENABLED(SQUARE_WAVE_STEPPING) + chopconf.dedge = true; + #endif st.CHOPCONF(chopconf.sr); st.rms_current(mA, HOLD_MULTIPLIER); @@ -266,36 +269,33 @@ void tmc_init(TMCMarlin &st, const uint16_t mA, const uint16_t microsteps, const uint32_t thrs, const bool stealth) { st.begin(); - static constexpr int8_t timings[] = CHOPPER_TIMING; // Default 4, -2, 1 - CHOPCONF_t chopconf{0}; chopconf.tbl = 1; - chopconf.toff = timings[0]; + chopconf.toff = chopper_timing.toff; chopconf.intpol = INTERPOLATE; - chopconf.hend = timings[1] + 3; - chopconf.hstrt = timings[2] - 1; + chopconf.hend = chopper_timing.hend + 3; + chopconf.hstrt = chopper_timing.hstrt - 1; + #if ENABLED(SQUARE_WAVE_STEPPING) + chopconf.dedge = true; + #endif st.CHOPCONF(chopconf.sr); st.rms_current(mA, HOLD_MULTIPLIER); st.microsteps(microsteps); st.iholddelay(10); st.TPOWERDOWN(128); // ~2s until driver lowers to hold current - st.TCOOLTHRS(0xFFFFF); - - #if ENABLED(ADAPTIVE_CURRENT) - COOLCONF_t coolconf{0}; - coolconf.semin = INCREASE_CURRENT_THRS; - coolconf.semax = REDUCE_CURRENT_THRS; - st.COOLCONF(coolconf.sr); - #endif st.en_pwm_mode(stealth); + st.stored.stealthChop_enabled = stealth; - PWMCONF_t pwmconf{0}; - pwmconf.pwm_freq = 0b01; // f_pwm = 2/683 f_clk + TMC2160_n::PWMCONF_t pwmconf{0}; + pwmconf.pwm_lim = 12; + pwmconf.pwm_reg = 8; + pwmconf.pwm_autograd = true; pwmconf.pwm_autoscale = true; - pwmconf.pwm_grad = 5; - pwmconf.pwm_ampl = 180; + pwmconf.pwm_freq = 0b01; + pwmconf.pwm_grad = 14; + pwmconf.pwm_ofs = 36; st.PWMCONF(pwmconf.sr); #if ENABLED(HYBRID_THRESHOLD) @@ -309,95 +309,94 @@ #endif // TMC2160 // -// TMC2208 Driver objects and inits +// TMC2208/2209 Driver objects and inits // -#if HAS_DRIVER(TMC2208) - // Stepper objects of TMC2208 steppers used - #if AXIS_DRIVER_TYPE_X(TMC2208) +#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) + #if AXIS_HAS_UART(X) #ifdef X_HARDWARE_SERIAL TMC_UART_DEFINE(HW, X, X); #else TMC_UART_DEFINE(SW, X, X); #endif #endif - #if AXIS_DRIVER_TYPE_X2(TMC2208) + #if AXIS_HAS_UART(X2) #ifdef X2_HARDWARE_SERIAL TMC_UART_DEFINE(HW, X2, X); #else TMC_UART_DEFINE(SW, X2, X); #endif #endif - #if AXIS_DRIVER_TYPE_Y(TMC2208) + #if AXIS_HAS_UART(Y) #ifdef Y_HARDWARE_SERIAL TMC_UART_DEFINE(HW, Y, Y); #else TMC_UART_DEFINE(SW, Y, Y); #endif #endif - #if AXIS_DRIVER_TYPE_Y2(TMC2208) + #if AXIS_HAS_UART(Y2) #ifdef Y2_HARDWARE_SERIAL TMC_UART_DEFINE(HW, Y2, Y); #else TMC_UART_DEFINE(SW, Y2, Y); #endif #endif - #if AXIS_DRIVER_TYPE_Z(TMC2208) + #if AXIS_HAS_UART(Z) #ifdef Z_HARDWARE_SERIAL TMC_UART_DEFINE(HW, Z, Z); #else TMC_UART_DEFINE(SW, Z, Z); #endif #endif - #if AXIS_DRIVER_TYPE_Z2(TMC2208) + #if AXIS_HAS_UART(Z2) #ifdef Z2_HARDWARE_SERIAL TMC_UART_DEFINE(HW, Z2, Z); #else TMC_UART_DEFINE(SW, Z2, Z); #endif #endif - #if AXIS_DRIVER_TYPE_Z3(TMC2208) + #if AXIS_HAS_UART(Z3) #ifdef Z3_HARDWARE_SERIAL TMC_UART_DEFINE(HW, Z3, Z); #else TMC_UART_DEFINE(SW, Z3, Z); #endif #endif - #if AXIS_DRIVER_TYPE_E0(TMC2208) + #if AXIS_HAS_UART(E0) #ifdef E0_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 0); #else TMC_UART_DEFINE_E(SW, 0); #endif #endif - #if AXIS_DRIVER_TYPE_E1(TMC2208) + #if AXIS_HAS_UART(E1) #ifdef E1_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 1); #else TMC_UART_DEFINE_E(SW, 1); #endif #endif - #if AXIS_DRIVER_TYPE_E2(TMC2208) + #if AXIS_HAS_UART(E2) #ifdef E2_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 2); #else TMC_UART_DEFINE_E(SW, 2); #endif #endif - #if AXIS_DRIVER_TYPE_E3(TMC2208) + #if AXIS_HAS_UART(E3) #ifdef E3_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 3); #else TMC_UART_DEFINE_E(SW, 3); #endif #endif - #if AXIS_DRIVER_TYPE_E4(TMC2208) + #if AXIS_HAS_UART(E4) #ifdef E4_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 4); #else TMC_UART_DEFINE_E(SW, 4); #endif #endif - #if AXIS_DRIVER_TYPE_E5(TMC2208) + #if AXIS_HAS_UART(E5) #ifdef E5_HARDWARE_SERIAL TMC_UART_DEFINE_E(HW, 5); #else @@ -405,92 +404,92 @@ #endif #endif - void tmc2208_serial_begin() { - #if AXIS_DRIVER_TYPE_X(TMC2208) + void tmc_serial_begin() { + #if AXIS_HAS_UART(X) #ifdef X_HARDWARE_SERIAL X_HARDWARE_SERIAL.begin(115200); #else stepperX.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_X2(TMC2208) + #if AXIS_HAS_UART(X2) #ifdef X2_HARDWARE_SERIAL X2_HARDWARE_SERIAL.begin(115200); #else stepperX2.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_Y(TMC2208) + #if AXIS_HAS_UART(Y) #ifdef Y_HARDWARE_SERIAL Y_HARDWARE_SERIAL.begin(115200); #else stepperY.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_Y2(TMC2208) + #if AXIS_HAS_UART(Y2) #ifdef Y2_HARDWARE_SERIAL Y2_HARDWARE_SERIAL.begin(115200); #else stepperY2.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_Z(TMC2208) + #if AXIS_HAS_UART(Z) #ifdef Z_HARDWARE_SERIAL Z_HARDWARE_SERIAL.begin(115200); #else stepperZ.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_Z2(TMC2208) + #if AXIS_HAS_UART(Z2) #ifdef Z2_HARDWARE_SERIAL Z2_HARDWARE_SERIAL.begin(115200); #else stepperZ2.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_Z3(TMC2208) + #if AXIS_HAS_UART(Z3) #ifdef Z3_HARDWARE_SERIAL Z3_HARDWARE_SERIAL.begin(115200); #else stepperZ3.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_E0(TMC2208) + #if AXIS_HAS_UART(E0) #ifdef E0_HARDWARE_SERIAL E0_HARDWARE_SERIAL.begin(115200); #else stepperE0.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_E1(TMC2208) + #if AXIS_HAS_UART(E1) #ifdef E1_HARDWARE_SERIAL E1_HARDWARE_SERIAL.begin(115200); #else stepperE1.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_E2(TMC2208) + #if AXIS_HAS_UART(E2) #ifdef E2_HARDWARE_SERIAL E2_HARDWARE_SERIAL.begin(115200); #else stepperE2.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_E3(TMC2208) + #if AXIS_HAS_UART(E3) #ifdef E3_HARDWARE_SERIAL E3_HARDWARE_SERIAL.begin(115200); #else stepperE3.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_E4(TMC2208) + #if AXIS_HAS_UART(E4) #ifdef E4_HARDWARE_SERIAL E4_HARDWARE_SERIAL.begin(115200); #else stepperE4.beginSerial(115200); #endif #endif - #if AXIS_DRIVER_TYPE_E5(TMC2208) + #if AXIS_HAS_UART(E5) #ifdef E5_HARDWARE_SERIAL E5_HARDWARE_SERIAL.begin(115200); #else @@ -498,7 +497,9 @@ #endif #endif } +#endif +#if HAS_DRIVER(TMC2208) template void tmc_init(TMCMarlin &st, const uint16_t mA, const uint16_t microsteps, const uint32_t thrs, const bool stealth) { TMC2208_n::GCONF_t gconf{0}; @@ -515,6 +516,9 @@ chopconf.intpol = INTERPOLATE; chopconf.hend = chopper_timing.hend + 3; chopconf.hstrt = chopper_timing.hstrt - 1; + #if ENABLED(SQUARE_WAVE_STEPPING) + chopconf.dedge = true; + #endif st.CHOPCONF(chopconf.sr); st.rms_current(mA, HOLD_MULTIPLIER); @@ -543,6 +547,53 @@ } #endif // TMC2208 +#if HAS_DRIVER(TMC2209) + template + void tmc_init(TMCMarlin &st, const uint16_t mA, const uint16_t microsteps, const uint32_t thrs, const bool stealth) { + TMC2208_n::GCONF_t gconf{0}; + gconf.pdn_disable = true; // Use UART + gconf.mstep_reg_select = true; // Select microsteps with UART + gconf.i_scale_analog = false; + gconf.en_spreadcycle = !stealth; + st.GCONF(gconf.sr); + st.stored.stealthChop_enabled = stealth; + + TMC2208_n::CHOPCONF_t chopconf{0}; + chopconf.tbl = 0b01; // blank_time = 24 + chopconf.toff = chopper_timing.toff; + chopconf.intpol = INTERPOLATE; + chopconf.hend = chopper_timing.hend + 3; + chopconf.hstrt = chopper_timing.hstrt - 1; + #if ENABLED(SQUARE_WAVE_STEPPING) + chopconf.dedge = true; + #endif + st.CHOPCONF(chopconf.sr); + + st.rms_current(mA, HOLD_MULTIPLIER); + st.microsteps(microsteps); + st.iholddelay(10); + st.TPOWERDOWN(128); // ~2s until driver lowers to hold current + + TMC2208_n::PWMCONF_t pwmconf{0}; + pwmconf.pwm_lim = 12; + pwmconf.pwm_reg = 8; + pwmconf.pwm_autograd = true; + pwmconf.pwm_autoscale = true; + pwmconf.pwm_freq = 0b01; + pwmconf.pwm_grad = 14; + pwmconf.pwm_ofs = 36; + st.PWMCONF(pwmconf.sr); + + #if ENABLED(HYBRID_THRESHOLD) + st.set_pwm_thrs(thrs); + #else + UNUSED(thrs); + #endif + + st.GSTAT(0b111); // Clear + } +#endif // TMC2209 + #if HAS_DRIVER(TMC2660) template void tmc_init(TMCMarlin &st, const uint16_t mA, const uint16_t microsteps, const uint32_t, const bool) { @@ -555,8 +606,12 @@ chopconf.hstrt = chopper_timing.hstrt - 1; st.CHOPCONF(chopconf.sr); + st.sdoff(0); st.rms_current(mA); st.microsteps(microsteps); + #if ENABLED(SQUARE_WAVE_STEPPING) + st.dedge(true); + #endif st.intpol(INTERPOLATE); st.diss2g(true); // Disable short to ground protection. Too many false readings? @@ -577,6 +632,9 @@ chopconf.intpol = INTERPOLATE; chopconf.hend = chopper_timing.hend + 3; chopconf.hstrt = chopper_timing.hstrt - 1; + #if ENABLED(SQUARE_WAVE_STEPPING) + chopconf.dedge = true; + #endif st.CHOPCONF(chopconf.sr); st.rms_current(mA, HOLD_MULTIPLIER); @@ -609,14 +667,15 @@ void tmc_init(TMCMarlin &st, const uint16_t mA, const uint16_t microsteps, const uint32_t thrs, const bool stealth) { st.begin(); - int8_t timings[] = CHOPPER_TIMING; // Default 4, -2, 1 - CHOPCONF_t chopconf{0}; chopconf.tbl = 1; - chopconf.toff = timings[0]; + chopconf.toff = chopper_timing.toff; chopconf.intpol = INTERPOLATE; - chopconf.hend = timings[1] + 3; - chopconf.hstrt = timings[2] - 1; + chopconf.hend = chopper_timing.hend + 3; + chopconf.hstrt = chopper_timing.hstrt - 1; + #if ENABLED(SQUARE_WAVE_STEPPING) + chopconf.dedge = true; + #endif st.CHOPCONF(chopconf.sr); st.rms_current(mA, HOLD_MULTIPLIER); @@ -624,20 +683,17 @@ st.iholddelay(10); st.TPOWERDOWN(128); // ~2s until driver lowers to hold current - #if ENABLED(ADAPTIVE_CURRENT) - COOLCONF_t coolconf{0}; - coolconf.semin = INCREASE_CURRENT_THRS; - coolconf.semax = REDUCE_CURRENT_THRS; - st.COOLCONF(coolconf.sr); - #endif - st.en_pwm_mode(stealth); + st.stored.stealthChop_enabled = stealth; - PWMCONF_t pwmconf{0}; - pwmconf.pwm_freq = 0b01; // f_pwm = 2/683 f_clk + TMC2160_n::PWMCONF_t pwmconf{0}; + pwmconf.pwm_lim = 12; + pwmconf.pwm_reg = 8; + pwmconf.pwm_autograd = true; pwmconf.pwm_autoscale = true; - pwmconf.pwm_grad = 5; - pwmconf.pwm_ampl = 180; + pwmconf.pwm_freq = 0b01; + pwmconf.pwm_grad = 14; + pwmconf.pwm_ofs = 36; st.PWMCONF(pwmconf.sr); #if ENABLED(HYBRID_THRESHOLD) @@ -766,29 +822,29 @@ void reset_stepper_drivers() { #if USE_SENSORLESS #if X_SENSORLESS #if AXIS_HAS_STALLGUARD(X) - stepperX.sgt(X_STALL_SENSITIVITY); + stepperX.homing_threshold(X_STALL_SENSITIVITY); #endif #if AXIS_HAS_STALLGUARD(X2) - stepperX2.sgt(X_STALL_SENSITIVITY); + stepperX2.homing_threshold(X_STALL_SENSITIVITY); #endif #endif #if Y_SENSORLESS #if AXIS_HAS_STALLGUARD(Y) - stepperY.sgt(Y_STALL_SENSITIVITY); + stepperY.homing_threshold(Y_STALL_SENSITIVITY); #endif #if AXIS_HAS_STALLGUARD(Y2) - stepperY2.sgt(Y_STALL_SENSITIVITY); + stepperY2.homing_threshold(Y_STALL_SENSITIVITY); #endif #endif #if Z_SENSORLESS #if AXIS_HAS_STALLGUARD(Z) - stepperZ.sgt(Z_STALL_SENSITIVITY); + stepperZ.homing_threshold(Z_STALL_SENSITIVITY); #endif #if AXIS_HAS_STALLGUARD(Z2) - stepperZ2.sgt(Z_STALL_SENSITIVITY); + stepperZ2.homing_threshold(Z_STALL_SENSITIVITY); #endif #if AXIS_HAS_STALLGUARD(Z3) - stepperZ3.sgt(Z_STALL_SENSITIVITY); + stepperZ3.homing_threshold(Z_STALL_SENSITIVITY); #endif #endif #endif diff --git a/Marlin/src/module/stepper_indirection.h b/Marlin/src/module/stepper_indirection.h index 8afe82b050..50bbc50770 100644 --- a/Marlin/src/module/stepper_indirection.h +++ b/Marlin/src/module/stepper_indirection.h @@ -58,15 +58,20 @@ #if HAS_TRINAMIC #include #include "../feature/tmc_util.h" - #if TMCSTEPPER_VERSION < 0x000202 - #error "Update TMCStepper library to 0.2.2 or newer." + #if TMCSTEPPER_VERSION < 0x000405 + #error "Update TMCStepper library to 0.4.5 or newer." #endif #define ____TMC_CLASS(MODEL, A, I, E) TMCMarlin #define ___TMC_CLASS(MODEL, A, I, E) ____TMC_CLASS(MODEL, A, I, E) #define __TMC_CLASS(MODEL, A, I, E) ___TMC_CLASS(_##MODEL, A, I, E) #define _TMC_CLASS(MODEL, L, E) __TMC_CLASS(MODEL, L, E) - #define TMC_CLASS(ST) _TMC_CLASS(ST##_DRIVER_TYPE, TMC_##ST##_LABEL, ST##_AXIS) + #define TMC_CLASS(ST, A) _TMC_CLASS(ST##_DRIVER_TYPE, TMC_##ST##_LABEL, A##_AXIS) + #if ENABLED(DISTINCT_E_FACTORS) + #define TMC_CLASS_E(I) TMC_CLASS(E##I, E##I) + #else + #define TMC_CLASS_E(I) TMC_CLASS(E##I, E) + #endif typedef struct { uint8_t toff; @@ -76,8 +81,8 @@ static constexpr chopper_timing_t chopper_timing = CHOPPER_TIMING; - #if HAS_DRIVER(TMC2208) - void tmc2208_serial_begin(); + #if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) + void tmc_serial_begin(); #endif #endif @@ -90,6 +95,8 @@ void restore_stepper_drivers(); // Called by PSU_ON void reset_stepper_drivers(); // Called by settings.load / settings.reset +#define AXIS_HAS_SQUARE_WAVE(A) (AXIS_IS_TMC(A) && ENABLED(SQUARE_WAVE_STEPPING)) + // X Stepper #if AXIS_DRIVER_TYPE_X(L6470) extern L6470 stepperX; @@ -101,7 +108,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define X_DIR_READ (stepperX.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(X) - extern TMC_CLASS(X) stepperX; + extern TMC_CLASS(X, X) stepperX; #endif #if AXIS_DRIVER_TYPE_X(TMC26X) extern TMC26XStepper stepperX; @@ -122,7 +129,11 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define X_DIR_READ READ(X_DIR_PIN) #endif #define X_STEP_INIT SET_OUTPUT(X_STEP_PIN) -#define X_STEP_WRITE(STATE) WRITE(X_STEP_PIN,STATE) +#if AXIS_HAS_SQUARE_WAVE(X) + #define X_STEP_WRITE(STATE) do { if(STATE) TOGGLE(X_STEP_PIN); } while(0) +#else + #define X_STEP_WRITE(STATE) WRITE(X_STEP_PIN,STATE) +#endif #define X_STEP_READ READ(X_STEP_PIN) // Y Stepper @@ -136,7 +147,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define Y_DIR_READ (stepperY.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(Y) - extern TMC_CLASS(Y) stepperY; + extern TMC_CLASS(Y, Y) stepperY; #endif #if AXIS_DRIVER_TYPE_Y(TMC26X) extern TMC26XStepper stepperY; @@ -157,7 +168,11 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define Y_DIR_READ READ(Y_DIR_PIN) #endif #define Y_STEP_INIT SET_OUTPUT(Y_STEP_PIN) -#define Y_STEP_WRITE(STATE) WRITE(Y_STEP_PIN,STATE) +#if AXIS_HAS_SQUARE_WAVE(Y) + #define Y_STEP_WRITE(STATE) do { if (STATE) TOGGLE(Y_STEP_PIN); } while(0) +#else + #define Y_STEP_WRITE(STATE) WRITE(Y_STEP_PIN,STATE) +#endif #define Y_STEP_READ READ(Y_STEP_PIN) // Z Stepper @@ -171,7 +186,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define Z_DIR_READ (stepperZ.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(Z) - extern TMC_CLASS(Z) stepperZ; + extern TMC_CLASS(Z, Z) stepperZ; #endif #if AXIS_DRIVER_TYPE_Z(TMC26X) extern TMC26XStepper stepperZ; @@ -192,7 +207,11 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define Z_DIR_READ READ(Z_DIR_PIN) #endif #define Z_STEP_INIT SET_OUTPUT(Z_STEP_PIN) -#define Z_STEP_WRITE(STATE) WRITE(Z_STEP_PIN,STATE) +#if AXIS_HAS_SQUARE_WAVE(Z) + #define Z_STEP_WRITE(STATE) do { if(STATE) TOGGLE(Z_STEP_PIN); } while(0) +#else + #define Z_STEP_WRITE(STATE) WRITE(Z_STEP_PIN,STATE) +#endif #define Z_STEP_READ READ(Z_STEP_PIN) // X2 Stepper @@ -207,7 +226,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define X2_DIR_READ (stepperX2.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(X2) - extern TMC_CLASS(X2) stepperX2; + extern TMC_CLASS(X2, X) stepperX2; #endif #if AXIS_DRIVER_TYPE_X2(TMC26X) extern TMC26XStepper stepperX2; @@ -228,7 +247,12 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define X2_DIR_READ READ(X2_DIR_PIN) #endif #define X2_STEP_INIT SET_OUTPUT(X2_STEP_PIN) - #define X2_STEP_WRITE(STATE) WRITE(X2_STEP_PIN,STATE) + #if AXIS_HAS_SQUARE_WAVE(X2) + #define X2_STEP_WRITE(STATE) do { if(STATE) TOGGLE(X2_STEP_PIN); } while(0) + #else + #define X2_STEP_WRITE(STATE) WRITE(X2_STEP_PIN,STATE) + #endif + #define X2_STEP_READ READ(X2_STEP_PIN) #endif @@ -244,7 +268,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define Y2_DIR_READ (stepperY2.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(Y2) - extern TMC_CLASS(Y2) stepperY2; + extern TMC_CLASS(Y2, Y) stepperY2; #endif #if AXIS_DRIVER_TYPE_Y2(TMC26X) extern TMC26XStepper stepperY2; @@ -265,7 +289,12 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define Y2_DIR_READ READ(Y2_DIR_PIN) #endif #define Y2_STEP_INIT SET_OUTPUT(Y2_STEP_PIN) - #define Y2_STEP_WRITE(STATE) WRITE(Y2_STEP_PIN,STATE) + #if AXIS_HAS_SQUARE_WAVE(Y2) + #define Y2_STEP_WRITE(STATE) do { if(STATE) TOGGLE(Y2_STEP_PIN); } while(0) + #else + #define Y2_STEP_WRITE(STATE) WRITE(Y2_STEP_PIN,STATE) + #endif + #define Y2_STEP_READ READ(Y2_STEP_PIN) #else #define Y2_DIR_WRITE(STATE) NOOP @@ -283,7 +312,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define Z2_DIR_READ (stepperZ2.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(Z2) - extern TMC_CLASS(Z2) stepperZ2; + extern TMC_CLASS(Z2, Z) stepperZ2; #endif #if AXIS_DRIVER_TYPE_Z2(TMC26X) extern TMC26XStepper stepperZ2; @@ -304,7 +333,12 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define Z2_DIR_READ READ(Z2_DIR_PIN) #endif #define Z2_STEP_INIT SET_OUTPUT(Z2_STEP_PIN) - #define Z2_STEP_WRITE(STATE) WRITE(Z2_STEP_PIN,STATE) + #if AXIS_HAS_SQUARE_WAVE(Z2) + #define Z2_STEP_WRITE(STATE) do { if(STATE) TOGGLE(Z2_STEP_PIN); } while(0) + #else + #define Z2_STEP_WRITE(STATE) WRITE(Z2_STEP_PIN,STATE) + #endif + #define Z2_STEP_READ READ(Z2_STEP_PIN) #else #define Z2_DIR_WRITE(STATE) NOOP @@ -322,7 +356,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define Z3_DIR_READ (stepperZ3.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(Z3) - extern TMC_CLASS(Z3) stepperZ3; + extern TMC_CLASS(Z3, Z) stepperZ3; #endif #if ENABLED(Z3_IS_TMC26X) extern TMC26XStepper stepperZ3; @@ -343,7 +377,12 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define Z3_DIR_READ READ(Z3_DIR_PIN) #endif #define Z3_STEP_INIT SET_OUTPUT(Z3_STEP_PIN) - #define Z3_STEP_WRITE(STATE) WRITE(Z3_STEP_PIN,STATE) + #if AXIS_HAS_SQUARE_WAVE(Z3) + #define Z3_STEP_WRITE(STATE) do { if(STATE) TOGGLE(Z3_STEP_PIN); } while(0) + #else + #define Z3_STEP_WRITE(STATE) WRITE(Z3_STEP_PIN,STATE) + #endif + #define Z3_STEP_READ READ(Z3_STEP_PIN) #else #define Z3_DIR_WRITE(STATE) NOOP @@ -360,7 +399,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E0_DIR_READ (stepperE0.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(E0) - extern TMC_CLASS(E0) stepperE0; + extern TMC_CLASS_E(0) stepperE0; #endif #if AXIS_DRIVER_TYPE_E0(TMC26X) extern TMC26XStepper stepperE0; @@ -381,7 +420,11 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E0_DIR_READ READ(E0_DIR_PIN) #endif #define E0_STEP_INIT SET_OUTPUT(E0_STEP_PIN) -#define E0_STEP_WRITE(STATE) WRITE(E0_STEP_PIN,STATE) +#if AXIS_HAS_SQUARE_WAVE(E0) + #define E0_STEP_WRITE(STATE) do { if(STATE) TOGGLE(E0_STEP_PIN); } while(0) +#else + #define E0_STEP_WRITE(STATE) WRITE(E0_STEP_PIN,STATE) +#endif #define E0_STEP_READ READ(E0_STEP_PIN) // E1 Stepper @@ -395,7 +438,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E1_DIR_READ (stepperE1.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(E1) - extern TMC_CLASS(E1) stepperE1; + extern TMC_CLASS_E(1) stepperE1; #endif #if AXIS_DRIVER_TYPE_E1(TMC26X) extern TMC26XStepper stepperE1; @@ -416,7 +459,11 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E1_DIR_READ READ(E1_DIR_PIN) #endif #define E1_STEP_INIT SET_OUTPUT(E1_STEP_PIN) -#define E1_STEP_WRITE(STATE) WRITE(E1_STEP_PIN,STATE) +#if AXIS_HAS_SQUARE_WAVE(E1) + #define E1_STEP_WRITE(STATE) do { if(STATE) TOGGLE(E1_STEP_PIN); } while(0) +#else + #define E1_STEP_WRITE(STATE) WRITE(E1_STEP_PIN,STATE) +#endif #define E1_STEP_READ READ(E1_STEP_PIN) // E2 Stepper @@ -430,7 +477,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E2_DIR_READ (stepperE2.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(E2) - extern TMC_CLASS(E2) stepperE2; + extern TMC_CLASS_E(2) stepperE2; #endif #if AXIS_DRIVER_TYPE_E2(TMC26X) extern TMC26XStepper stepperE2; @@ -451,7 +498,11 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E2_DIR_READ READ(E2_DIR_PIN) #endif #define E2_STEP_INIT SET_OUTPUT(E2_STEP_PIN) -#define E2_STEP_WRITE(STATE) WRITE(E2_STEP_PIN,STATE) +#if AXIS_HAS_SQUARE_WAVE(E2) + #define E2_STEP_WRITE(STATE) do { if(STATE) TOGGLE(E2_STEP_PIN); } while(0) +#else + #define E2_STEP_WRITE(STATE) WRITE(E2_STEP_PIN,STATE) +#endif #define E2_STEP_READ READ(E2_STEP_PIN) // E3 Stepper @@ -465,7 +516,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E3_DIR_READ (stepperE3.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(E3) - extern TMC_CLASS(E3) stepperE3; + extern TMC_CLASS_E(3) stepperE3; #endif #if AXIS_DRIVER_TYPE_E3(TMC26X) extern TMC26XStepper stepperE3; @@ -486,7 +537,11 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E3_DIR_READ READ(E3_DIR_PIN) #endif #define E3_STEP_INIT SET_OUTPUT(E3_STEP_PIN) -#define E3_STEP_WRITE(STATE) WRITE(E3_STEP_PIN,STATE) +#if AXIS_HAS_SQUARE_WAVE(E3) + #define E3_STEP_WRITE(STATE) do { if(STATE) TOGGLE(E3_STEP_PIN); } while(0) +#else + #define E3_STEP_WRITE(STATE) WRITE(E3_STEP_PIN,STATE) +#endif #define E3_STEP_READ READ(E3_STEP_PIN) // E4 Stepper @@ -500,7 +555,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E4_DIR_READ (stepperE4.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(E4) - extern TMC_CLASS(E4) stepperE4; + extern TMC_CLASS_E(4) stepperE4; #endif #if AXIS_DRIVER_TYPE_E4(TMC26X) extern TMC26XStepper stepperE4; @@ -521,7 +576,11 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E4_DIR_READ READ(E4_DIR_PIN) #endif #define E4_STEP_INIT SET_OUTPUT(E4_STEP_PIN) -#define E4_STEP_WRITE(STATE) WRITE(E4_STEP_PIN,STATE) +#if AXIS_HAS_SQUARE_WAVE(E4) + #define E4_STEP_WRITE(STATE) do { if(STATE) TOGGLE(E4_STEP_PIN); } while(0) +#else + #define E4_STEP_WRITE(STATE) WRITE(E4_STEP_PIN,STATE) +#endif #define E4_STEP_READ READ(E4_STEP_PIN) // E5 Stepper @@ -535,7 +594,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E5_DIR_READ (stepperE5.getStatus() & STATUS_DIR) #else #if AXIS_IS_TMC(E5) - extern TMC_CLASS(E5) stepperE5; + extern TMC_CLASS_E(5) stepperE5; #endif #if AXIS_DRIVER_TYPE_E5(TMC26X) extern TMC26XStepper stepperE5; @@ -556,7 +615,11 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #define E5_DIR_READ READ(E5_DIR_PIN) #endif #define E5_STEP_INIT SET_OUTPUT(E5_STEP_PIN) -#define E5_STEP_WRITE(STATE) WRITE(E5_STEP_PIN,STATE) +#if AXIS_HAS_SQUARE_WAVE(E5) + #define E5_STEP_WRITE(STATE) do { if(STATE) TOGGLE(E5_STEP_PIN); } while(0) +#else + #define E5_STEP_WRITE(STATE) WRITE(E5_STEP_PIN,STATE) +#endif #define E5_STEP_READ READ(E5_STEP_PIN) /** diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 717489857c..23f2d003da 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -82,6 +82,10 @@ #endif #endif +#ifndef THERMAL_PROTECTION_GRACE_PERIOD + #define THERMAL_PROTECTION_GRACE_PERIOD 0 // No grace period needed on well-behaved boards +#endif + Temperature thermalManager; /** @@ -346,11 +350,13 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0 PID_t tune_pid = { 0, 0, 0 }; float max = 0, min = 10000; + const bool isbed = (heater < 0); + #if HAS_PID_FOR_BOTH - #define GHV(B,H) (heater < 0 ? (B) : (H)) - #define SHV(B,H) do{ if (heater < 0) temp_bed.soft_pwm_amount = B; else temp_hotend[heater].soft_pwm_amount = H; }while(0) - #define ONHEATINGSTART() (heater < 0 ? printerEventLEDs.onBedHeatingStart() : printerEventLEDs.onHotendHeatingStart()) - #define ONHEATING(S,C,T) do{ if (heater < 0) printerEventLEDs.onBedHeating(S,C,T); else printerEventLEDs.onHotendHeating(S,C,T); }while(0) + #define GHV(B,H) (isbed ? (B) : (H)) + #define SHV(B,H) do{ if (isbed) temp_bed.soft_pwm_amount = B; else temp_hotend[heater].soft_pwm_amount = H; }while(0) + #define ONHEATINGSTART() (isbed ? printerEventLEDs.onBedHeatingStart() : printerEventLEDs.onHotendHeatingStart()) + #define ONHEATING(S,C,T) (isbed ? printerEventLEDs.onBedHeating(S,C,T) : printerEventLEDs.onHotendHeating(S,C,T)) #elif ENABLED(PIDTEMPBED) #define GHV(B,H) B #define SHV(B,H) (temp_bed.soft_pwm_amount = B) @@ -366,7 +372,7 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0 #if WATCH_BED || WATCH_HOTENDS #define HAS_TP_BED BOTH(THERMAL_PROTECTION_BED, PIDTEMPBED) #if HAS_TP_BED && BOTH(THERMAL_PROTECTION_HOTENDS, PIDTEMP) - #define GTV(B,H) (heater < 0 ? (B) : (H)) + #define GTV(B,H) (isbed ? (B) : (H)) #elif HAS_TP_BED #define GTV(B,H) (B) #else @@ -452,23 +458,25 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0 SERIAL_ECHOPAIR(MSG_BIAS, bias, MSG_D, d, MSG_T_MIN, min, MSG_T_MAX, max); if (cycles > 2) { - float Ku = (4.0f * d) / (float(M_PI) * (max - min) * 0.5f), - Tu = ((float)(t_low + t_high) * 0.001f); - tune_pid.Kp = 0.6f * Ku; + const float Ku = (4.0f * d) / (float(M_PI) * (max - min) * 0.5f), + Tu = float(t_low + t_high) * 0.001f, + pf = isbed ? 0.2f : 0.6f, + df = isbed ? 1.0f / 3.0f : 1.0f / 8.0f; + tune_pid.Kp = Ku * pf; + tune_pid.Kd = tune_pid.Kp * Tu * df; tune_pid.Ki = 2 * tune_pid.Kp / Tu; - tune_pid.Kd = tune_pid.Kp * Tu * 0.125f; SERIAL_ECHOPAIR(MSG_KU, Ku, MSG_TU, Tu); SERIAL_ECHOLNPGM("\n" MSG_CLASSIC_PID); SERIAL_ECHOLNPAIR(MSG_KP, tune_pid.Kp, MSG_KI, tune_pid.Ki, MSG_KD, tune_pid.Kd); /** - tune_pid.Kp = 0.33*Ku; - tune_pid.Ki = tune_pid.Kp/Tu; - tune_pid.Kd = tune_pid.Kp*Tu/3; + tune_pid.Kp = 0.33 * Ku; + tune_pid.Ki = tune_pid.Kp / Tu; + tune_pid.Kd = tune_pid.Kp * Tu / 3; SERIAL_ECHOLNPGM(" Some overshoot"); SERIAL_ECHOLNPAIR(" Kp: ", tune_pid.Kp, " Ki: ", tune_pid.Ki, " Kd: ", tune_pid.Kd, " No overshoot"); - tune_pid.Kp = 0.2*Ku; - tune_pid.Ki = 2*tune_pid.Kp/Tu; - tune_pid.Kd = tune_pid.Kp*Tu/3; + tune_pid.Kp = 0.2 * Ku; + tune_pid.Ki = 2 * tune_pid.Kp / Tu; + tune_pid.Kd = tune_pid.Kp * Tu / 3; SERIAL_ECHOPAIR(" Kp: ", tune_pid.Kp, " Ki: ", tune_pid.Ki, " Kd: ", tune_pid.Kd); */ } @@ -492,7 +500,7 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0 // Report heater states every 2 seconds if (ELAPSED(ms, next_temp_ms)) { #if HAS_TEMP_SENSOR - print_heater_states(heater >= 0 ? heater : active_extruder); + print_heater_states(isbed ? active_extruder : heater); SERIAL_EOL(); #endif next_temp_ms = ms + 2000UL; @@ -503,9 +511,9 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0 #if WATCH_BED && WATCH_HOTENDS true #elif WATCH_HOTENDS - heater >= 0 + !isbed #else - heater < 0 + isbed #endif ) { if (!heated) { // If not yet reached target... @@ -565,7 +573,7 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0 // Use the result? (As with "M303 U1") if (set_result) { #if HAS_PID_FOR_BOTH - if (heater < 0) _SET_BED_PID(); else _SET_EXTRUDER_PID(); + if (isbed) _SET_BED_PID(); else _SET_EXTRUDER_PID(); #elif ENABLED(PIDTEMP) _SET_EXTRUDER_PID(); #else @@ -774,6 +782,8 @@ void Temperature::_temp_error(const int8_t heater, PGM_P const serial_msg, PGM_P } else disable_all_heaters(); // paranoia + #else + UNUSED(killed); #endif } @@ -799,9 +809,7 @@ float Temperature::get_pid_output(const int8_t e) { static float temp_iState[HOTENDS] = { 0 }, temp_dState[HOTENDS] = { 0 }; static bool pid_reset[HOTENDS] = { false }; - float pid_error = temp_hotend[HOTEND_INDEX].target - temp_hotend[HOTEND_INDEX].current; - work_pid[HOTEND_INDEX].Kd = PID_K2 * PID_PARAM(Kd, HOTEND_INDEX) * (temp_hotend[HOTEND_INDEX].current - temp_dState[HOTEND_INDEX]) + float(PID_K1) * work_pid[HOTEND_INDEX].Kd; - temp_dState[HOTEND_INDEX] = temp_hotend[HOTEND_INDEX].current; + const float pid_error = temp_hotend[HOTEND_INDEX].target - temp_hotend[HOTEND_INDEX].current; if (temp_hotend[HOTEND_INDEX].target == 0 || pid_error < -(PID_FUNCTIONAL_RANGE) @@ -819,13 +827,17 @@ float Temperature::get_pid_output(const int8_t e) { else { if (pid_reset[HOTEND_INDEX]) { temp_iState[HOTEND_INDEX] = 0.0; + work_pid[HOTEND_INDEX].Kd = 0.0; pid_reset[HOTEND_INDEX] = false; } - temp_iState[HOTEND_INDEX] += pid_error; + + work_pid[HOTEND_INDEX].Kd = work_pid[HOTEND_INDEX].Kd + PID_K2 * (PID_PARAM(Kd, HOTEND_INDEX) * (temp_dState[HOTEND_INDEX] - temp_hotend[HOTEND_INDEX].current) - work_pid[HOTEND_INDEX].Kd); + const float max_power_over_i_gain = (float)PID_MAX / PID_PARAM(Ki, HOTEND_INDEX); + temp_iState[HOTEND_INDEX] = constrain(temp_iState[HOTEND_INDEX] + pid_error, 0, max_power_over_i_gain); work_pid[HOTEND_INDEX].Kp = PID_PARAM(Kp, HOTEND_INDEX) * pid_error; work_pid[HOTEND_INDEX].Ki = PID_PARAM(Ki, HOTEND_INDEX) * temp_iState[HOTEND_INDEX]; - pid_output = work_pid[HOTEND_INDEX].Kp + work_pid[HOTEND_INDEX].Ki - work_pid[HOTEND_INDEX].Kd; + pid_output = work_pid[HOTEND_INDEX].Kp + work_pid[HOTEND_INDEX].Ki + work_pid[HOTEND_INDEX].Kd; #if ENABLED(PID_EXTRUSION_SCALING) work_pid[HOTEND_INDEX].Kc = 0; @@ -844,15 +856,9 @@ float Temperature::get_pid_output(const int8_t e) { } #endif // PID_EXTRUSION_SCALING - if (pid_output > PID_MAX) { - if (pid_error > 0) temp_iState[HOTEND_INDEX] -= pid_error; // conditional un-integration - pid_output = PID_MAX; - } - else if (pid_output < 0) { - if (pid_error < 0) temp_iState[HOTEND_INDEX] -= pid_error; // conditional un-integration - pid_output = 0; - } + pid_output = constrain(pid_output, 0, PID_MAX); } + temp_dState[HOTEND_INDEX] = temp_hotend[HOTEND_INDEX].current; #else // PID_OPENLOOP @@ -902,23 +908,18 @@ float Temperature::get_pid_output(const int8_t e) { static PID_t work_pid = { 0 }; static float temp_iState = 0, temp_dState = 0; - float pid_error = temp_bed.target - temp_bed.current; - temp_iState += pid_error; + const float max_power_over_i_gain = (float)MAX_BED_POWER / temp_bed.pid.Ki, + pid_error = temp_bed.target - temp_bed.current; + + temp_iState = constrain(temp_iState + pid_error, 0, max_power_over_i_gain); + work_pid.Kp = temp_bed.pid.Kp * pid_error; work_pid.Ki = temp_bed.pid.Ki * temp_iState; - work_pid.Kd = PID_K2 * temp_bed.pid.Kd * (temp_bed.current - temp_dState) + PID_K1 * work_pid.Kd; + work_pid.Kd = work_pid.Kd + PID_K2 * (temp_bed.pid.Kd * (temp_dState - temp_bed.current) - work_pid.Kd); temp_dState = temp_bed.current; - float pid_output = work_pid.Kp + work_pid.Ki - work_pid.Kd; - if (pid_output > MAX_BED_POWER) { - if (pid_error > 0) temp_iState -= pid_error; // conditional un-integration - pid_output = MAX_BED_POWER; - } - else if (pid_output < 0) { - if (pid_error < 0) temp_iState -= pid_error; // conditional un-integration - pid_output = 0; - } + const float pid_output = constrain(work_pid.Kp + work_pid.Ki + work_pid.Kd, 0, MAX_BED_POWER); #else // PID_OPENLOOP @@ -991,9 +992,6 @@ void Temperature::manage_heater() { #endif #if HAS_THERMAL_PROTECTION - #ifndef THERMAL_PROTECTION_GRACE_PERIOD - #define THERMAL_PROTECTION_GRACE_PERIOD 0 // No grace period needed on well-behaved boards - #endif #if THERMAL_PROTECTION_GRACE_PERIOD > 0 static millis_t grace_period = ms + THERMAL_PROTECTION_GRACE_PERIOD; if (ELAPSED(ms, grace_period)) grace_period = 0UL; @@ -1230,10 +1228,10 @@ void Temperature::manage_heater() { #if ENABLED(HEATER_5_USER_THERMISTOR) { true, 0, 0, HOTEND5_PULLUP_RESISTOR_OHMS, HOTEND5_RESISTANCE_25C_OHMS, 0, 0, HOTEND5_BETA, 0 }, #endif - #if ENABLED(BED_USER_THERMISTOR) + #if ENABLED(HEATER_BED_USER_THERMISTOR) { true, 0, 0, BED_PULLUP_RESISTOR_OHMS, BED_RESISTANCE_25C_OHMS, 0, 0, BED_BETA, 0 }, #endif - #if ENABLED(CHAMBER_USER_THERMISTOR) + #if ENABLED(HEATER_CHAMBER_USER_THERMISTOR) { true, 0, 0, CHAMBER_PULLUP_RESISTOR_OHMS, CHAMBER_RESISTANCE_25C_OHMS, 0, 0, CHAMBER_BETA, 0 } #endif }; @@ -1275,10 +1273,10 @@ void Temperature::manage_heater() { #if ENABLED(HEATER_5_USER_THERMISTOR) t_index == CTI_HOTEND_5 ? PSTR("HOTEND 5") : #endif - #if ENABLED(BED_USER_THERMISTOR) + #if ENABLED(HEATER_BED_USER_THERMISTOR) t_index == CTI_BED ? PSTR("BED") : #endif - #if ENABLED(CHAMBER_USER_THERMISTOR) + #if ENABLED(HEATER_CHAMBER_USER_THERMISTOR) t_index == CTI_CHAMBER ? PSTR("CHAMBER") : #endif nullptr @@ -1428,7 +1426,7 @@ float Temperature::analog_to_celsius_hotend(const int raw, const uint8_t e) { // Derived from RepRap FiveD extruder::getTemperature() // For bed temperature measurement. float Temperature::analog_to_celsius_bed(const int raw) { - #if ENABLED(BED_USER_THERMISTOR) + #if ENABLED(HEATER_BED_USER_THERMISTOR) return user_thermistor_to_deg_c(CTI_BED, raw); #elif ENABLED(HEATER_BED_USES_THERMISTOR) SCAN_THERMISTOR_TABLE(BED_TEMPTABLE, BED_TEMPTABLE_LEN); @@ -1446,7 +1444,7 @@ float Temperature::analog_to_celsius_hotend(const int raw, const uint8_t e) { // Derived from RepRap FiveD extruder::getTemperature() // For chamber temperature measurement. float Temperature::analog_to_celsius_chamber(const int raw) { - #if ENABLED(CHAMBER_USER_THERMISTOR) + #if ENABLED(HEATER_CHAMBER_USER_THERMISTOR) return user_thermistor_to_deg_c(CTI_CHAMBER, raw); #elif ENABLED(HEATER_CHAMBER_USES_THERMISTOR) SCAN_THERMISTOR_TABLE(CHAMBER_TEMPTABLE, CHAMBER_TEMPTABLE_LEN); @@ -2166,6 +2164,15 @@ void Temperature::set_current_temp_raw() { #endif void Temperature::readings_ready() { + + #if THERMAL_PROTECTION_GRACE_PERIOD > 0 + const millis_t ms = millis(); + static millis_t grace_period = ms + THERMAL_PROTECTION_GRACE_PERIOD; // NOTE: millis() == 0 on reset + if (ELAPSED(ms, grace_period)) grace_period = 0; + #else + static constexpr millis_t grace_period = 0; + #endif + // Update the raw values if they've been read. Else we could be updating them during reading. if (!temp_meas_ready) set_current_temp_raw(); @@ -2207,6 +2214,9 @@ void Temperature::readings_ready() { #endif // HOTENDS > 1 }; + // Give ADC temperature readings time to settle at boot-up before testing + if (grace_period) return; + for (uint8_t e = 0; e < COUNT(temp_dir); e++) { const int16_t tdir = temp_dir[e], rawtemp = temp_hotend[e].raw * tdir; const bool heater_on = (temp_hotend[e].target > 0) diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index fa5013bc56..ddcdd3909c 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -233,10 +233,10 @@ typedef struct { int16_t raw_min, raw_max, mintemp, maxtemp; } temp_range_t; #if ENABLED(HEATER_5_USER_THERMISTOR) CTI_HOTEND_5, #endif - #if ENABLED(BED_USER_THERMISTOR) + #if ENABLED(HEATER_BED_USER_THERMISTOR) CTI_BED, #endif - #if ENABLED(CHAMBER_USER_THERMISTOR) + #if ENABLED(HEATER_CHAMBER_USER_THERMISTOR) CTI_CHAMBER, #endif USER_THERMISTORS diff --git a/Marlin/src/module/thermistor/thermistor_18.h b/Marlin/src/module/thermistor/thermistor_18.h new file mode 100644 index 0000000000..c515ac9728 --- /dev/null +++ b/Marlin/src/module/thermistor/thermistor_18.h @@ -0,0 +1,58 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 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 . + * + */ + +// ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327 - version (measured/tested/approved) +const short temptable_18[][2] PROGMEM = { + { OV( 1), 713 }, + { OV( 17), 284 }, + { OV( 20), 275 }, + { OV( 23), 267 }, + { OV( 27), 257 }, + { OV( 31), 250 }, + { OV( 37), 240 }, + { OV( 43), 232 }, + { OV( 51), 222 }, + { OV( 61), 213 }, + { OV( 73), 204 }, + { OV( 87), 195 }, + { OV( 106), 185 }, + { OV( 128), 175 }, + { OV( 155), 166 }, + { OV( 189), 156 }, + { OV( 230), 146 }, + { OV( 278), 137 }, + { OV( 336), 127 }, + { OV( 402), 117 }, + { OV( 476), 107 }, + { OV( 554), 97 }, + { OV( 635), 87 }, + { OV( 713), 78 }, + { OV( 784), 68 }, + { OV( 846), 58 }, + { OV( 897), 49 }, + { OV( 937), 39 }, + { OV( 966), 30 }, + { OV( 986), 20 }, + { OV(1000), 10 }, + { OV(1010), 0 }, + { OV(1024),-273 } // for safety +}; diff --git a/Marlin/src/module/thermistor/thermistors.h b/Marlin/src/module/thermistor/thermistors.h index 00def3ae40..1dd3a91a0f 100644 --- a/Marlin/src/module/thermistor/thermistors.h +++ b/Marlin/src/module/thermistor/thermistors.h @@ -83,6 +83,9 @@ #if ANY_THERMISTOR_IS(15) // JGAurora A5 thermistor calibration #include "thermistor_15.h" #endif +#if ANY_THERMISTOR_IS(18) // ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327 + #include "thermistor_18.h" +#endif #if ANY_THERMISTOR_IS(20) // PT100 with INA826 amp on Ultimaker v2.0 electronics #include "thermistor_20.h" #endif diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 04854f2aab..ceb01bfbbc 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -702,7 +702,11 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n if (tmp_extruder >= EXTRUDERS) return invalid_extruder_error(tmp_extruder); - if (!no_move && (!all_axes_homed())) { + if (!no_move && (!all_axes_homed() + #if ENABLED(DUAL_X_CARRIAGE) + || dual_x_carriage_mode == DXC_FULL_CONTROL_MODE + #endif + )) { no_move = true; if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("No move on toolchange"); } @@ -712,11 +716,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n #endif #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - const bool should_swap = !no_move && toolchange_settings.swap_length - #if ENABLED(DUAL_X_CARRIAGE) - && dual_x_carriage_mode != DXC_FULL_CONTROL_MODE - #endif - ; + const bool should_swap = !no_move && toolchange_settings.swap_length; #if ENABLED(PREVENT_COLD_EXTRUSION) const bool too_cold = !DEBUGGING(DRYRUN) && (thermalManager.targetTooColdToExtrude(active_extruder) || thermalManager.targetTooColdToExtrude(tmp_extruder)); #else @@ -750,17 +750,22 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n const float old_feedrate_mm_s = fr_mm_s > 0.0 ? fr_mm_s : feedrate_mm_s; feedrate_mm_s = fr_mm_s > 0.0 ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S; - #if HAS_SOFTWARE_ENDSTOPS && ENABLED(DUAL_X_CARRIAGE) - update_software_endstops(X_AXIS, active_extruder, tmp_extruder); + #if HAS_SOFTWARE_ENDSTOPS + #if HAS_HOTEND_OFFSET + #define _EXT_ARGS , active_extruder, tmp_extruder + #else + #define _EXT_ARGS + #endif + update_software_endstops(X_AXIS _EXT_ARGS); + #if DISABLED(DUAL_X_CARRIAGE) + update_software_endstops(Y_AXIS _EXT_ARGS); + update_software_endstops(Z_AXIS _EXT_ARGS); + #endif #endif set_destination_from_current(); - if (!no_move - #if ENABLED(DUAL_X_CARRIAGE) - && dual_x_carriage_mode != DXC_FULL_CONTROL_MODE - #endif - ) { + if (!no_move) { #if DISABLED(SWITCHING_NOZZLE) // Do a small lift to avoid the workpiece in the move back (below) current_position[Z_AXIS] += toolchange_settings.z_raise; @@ -880,24 +885,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n #endif // Move back to the original (or tweaked) position - if( - #if ENABLED(TOOLCHANGE_RETURN_NEXT_MOVE) - true || - #endif - #if ENABLED(DUAL_X_CARRIAGE) - dual_x_carriage_mode == DXC_FULL_CONTROL_MODE || - #endif - false ) { - SERIAL_ECHOLN("TLCHNG_OFFSETS"); - //current_position[Z_AXIS] -= toolchange_settings.z_raise; //return z-raise - destination[X_AXIS] = current_position[X_AXIS]; - destination[Y_AXIS] = current_position[Y_AXIS]; - //planner.buffer_line(current_position, feedrate_mm_s, active_extruder); //apply offsets - } - else{ - SERIAL_ECHOLN("TLCHNG_RETURNPOS"); - } - do_blocking_move_to(destination); //return to stored position + do_blocking_move_to(destination); #if ENABLED(DUAL_X_CARRIAGE) active_extruder_parked = false; diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index 1c346b237d..6786d8b0be 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -156,10 +156,14 @@ #include "pins_TRIGORILLA_13.h" // ATmega2560 env:megaatmega2560 #elif MB(TRIGORILLA_14) #include "pins_TRIGORILLA_14.h" // ATmega2560 env:megaatmega2560 +#elif MB(TRIGORILLA_14_11) + #include "pins_TRIGORILLA_14.h" // ATmega2560 env:megaatmega2560 #elif MB(RAMPS_ENDER_4) #include "pins_RAMPS_ENDER_4.h" // ATmega2560 env:megaatmega2560 #elif MB(RAMPS_CREALITY) #include "pins_RAMPS_CREALITY.h" // ATmega2560 env:megaatmega2560 +#elif MB(RAMPS_DAGOMA) + #include "pins_RAMPS_DAGOMA.h" // ATmega2560 env:megaatmega2560 #elif MB(FYSETC_F6_13) #include "pins_FYSETC_F6_13.h" // ATmega2560 env:fysetc_f6_13 #elif MB(DUPLICATOR_I3_PLUS) @@ -168,6 +172,8 @@ #include "pins_VORON.h" // ATmega2560 env:megaatmega2560 #elif MB(TRONXY_V3_1_0) #include "pins_TRONXY_V3_1_0.h" // ATmega2560 env:megaatmega2560 +#elif MB(Z_BOLT_X_SERIES) + #include "pins_Z_BOLT_X_SERIES.h" // ATmega2560 env:megaatmega2560 // // Other ATmega1280, ATmega2560 @@ -412,6 +418,8 @@ #include "pins_STM32F1R.h" // STM32F1 env:STM32F1 #elif MB(STM3R_MINI) #include "pins_STM3R_MINI.h" // STM32F1 env:STM32F1 +#elif MB(BIGTREE_SKR_MINI_V1_1) + #include "pins_BIGTREE_SKR_MINI_V1_1.h" // STM32F1 env:BIGTREE_SKR_MINI #elif MB(MALYAN_M200) #include "pins_MALYAN_M200.h" // STM32F1 env:malyanm200 #elif MB(CHITU3D) @@ -422,6 +430,8 @@ #include "pins_MORPHEUS.h" // STM32F1 env:STM32F1 #elif MB(MKS_ROBIN) #include "pins_MKS_ROBIN.h" // STM32F1 env:mks_robin +#elif MB(JGAURORA_A5S_A1) + #include "pins_JGAURORA_A5S_A1.h" // STM32F1 env:JGAURORA_A5S_A1 // // STM32 ARM Cortex-M4F diff --git a/Marlin/src/pins/pinsDebug_list.h b/Marlin/src/pins/pinsDebug_list.h index c03bd1db36..1880104f2d 100644 --- a/Marlin/src/pins/pinsDebug_list.h +++ b/Marlin/src/pins/pinsDebug_list.h @@ -172,6 +172,12 @@ #if PIN_EXISTS(CONTROLLER_FAN) REPORT_NAME_DIGITAL(__LINE__, CONTROLLER_FAN_PIN) #endif +#if PIN_EXISTS(COOLANT_FLOOD) + REPORT_NAME_DIGITAL(__LINE__, COOLANT_FLOOD_PIN) +#endif +#if PIN_EXISTS(COOLANT_MIST) + REPORT_NAME_DIGITAL(__LINE__, COOLANT_MIST_PIN) +#endif #if PIN_EXISTS(CUTOFF_RESET) REPORT_NAME_DIGITAL(__LINE__, CUTOFF_RESET_PIN) #endif diff --git a/Marlin/src/pins/pins_AZTEEG_X3.h b/Marlin/src/pins/pins_AZTEEG_X3.h index fe5cb627a9..e7076cba9b 100644 --- a/Marlin/src/pins/pins_AZTEEG_X3.h +++ b/Marlin/src/pins/pins_AZTEEG_X3.h @@ -37,16 +37,14 @@ #endif #define BOARD_NAME "Azteeg X3" -#include "pins_RAMPS_13.h" - // // Servos // -#undef SERVO0_PIN -#undef SERVO1_PIN #define SERVO0_PIN 44 // SERVO1 port #define SERVO1_PIN 55 // SERVO2 port +#include "pins_RAMPS_13.h" + // // LCD / Controller // diff --git a/Marlin/src/pins/pins_AZTEEG_X3_PRO.h b/Marlin/src/pins/pins_AZTEEG_X3_PRO.h index 55ee39f84f..bae70258e9 100644 --- a/Marlin/src/pins/pins_AZTEEG_X3_PRO.h +++ b/Marlin/src/pins/pins_AZTEEG_X3_PRO.h @@ -37,14 +37,33 @@ // // RAMPS pins overrides // -#if ENABLED(CASE_LIGHT_ENABLE) && !PIN_EXISTS(CASE_LIGHT) - #define CASE_LIGHT_PIN 44 -#endif + +// +// Servos +// +// Tested this pin with bed leveling on a Delta with 1 servo. +// Physical wire attachment on EXT1: GND, 5V, D47. +// +#define SERVO0_PIN 47 + +// +// Limit Switches +// +#define X_STOP_PIN 3 +#define Y_STOP_PIN 14 +#define Z_STOP_PIN 18 #ifndef FAN_PIN #define FAN_PIN 6 #endif +#if ENABLED(CASE_LIGHT_ENABLE) && !PIN_EXISTS(CASE_LIGHT) + #define CASE_LIGHT_PIN 44 +#endif + +// +// Import RAMPS 1.4 pins +// #include "pins_RAMPS.h" // DIGIPOT slave addresses @@ -55,37 +74,6 @@ #define DIGIPOT_I2C_ADDRESS_B 0x2E // unshifted slave address for second DIGIPOT 0x2E (0x5C <- 0x2E << 1) #endif -// -// Servos -// -// Tested this pin with bed leveling on a Delta with 1 servo. -// Physical wire attachment on EXT1: GND, 5V, D47. -// -#undef SERVO0_PIN -#define SERVO0_PIN 47 - -// -// Limit Switches -// -// Swap the MIN and MAX endstop pins because the X3 Pro comes with only -// MIN endstop pin headers soldered onto the board. -// -#if ENABLED(DELTA) - #undef X_MIN_PIN - #undef X_MAX_PIN - #undef Y_MIN_PIN - #undef Y_MAX_PIN - #undef Z_MIN_PIN - #undef Z_MAX_PIN - - #define X_MIN_PIN 2 - #define X_MAX_PIN 3 - #define Y_MIN_PIN 15 - #define Y_MAX_PIN 14 - #define Z_MIN_PIN 19 - #define Z_MAX_PIN 18 -#endif - // // Z Probe (when not Z_MIN_PIN) // diff --git a/Marlin/src/pins/pins_BIGTREE_SKR_MINI_V1_1.h b/Marlin/src/pins/pins_BIGTREE_SKR_MINI_V1_1.h new file mode 100644 index 0000000000..2063719a0d --- /dev/null +++ b/Marlin/src/pins/pins_BIGTREE_SKR_MINI_V1_1.h @@ -0,0 +1,181 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +#ifndef TARGET_STM32F1 + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "BIGTREE SKR mini V1.1" +#endif + +//#define DISABLE_DEBUG +#define DISABLE_JTAG + +// Ignore temp readings during develpment. +//#define BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE + +// +// Limit Switches +// +#define X_MIN_PIN PC2 +#define X_MAX_PIN PA2 +#define Y_MIN_PIN PC1 +#define Y_MAX_PIN PA1 +#define Z_MIN_PIN PC0 +#define Z_MAX_PIN PC3 + +// +// Steppers +// + +/** + * TODO: Currently using same Enable pin for all steppers. + */ + +#define X_STEP_PIN PC6 +#define X_DIR_PIN PC7 +#define X_ENABLE_PIN PB15 + +#define Y_STEP_PIN PB13 +#define Y_DIR_PIN PB14 +#define Y_ENABLE_PIN PB12 + +#define Z_STEP_PIN PB10 +#define Z_DIR_PIN PB11 +#define Z_ENABLE_PIN PB2 + +#define E0_STEP_PIN PC5 +#define E0_DIR_PIN PB0 +#define E0_ENABLE_PIN PC4 + +#if ENABLED(TMC_USE_SW_SPI) + #define TMC_SW_SCK PB3 + #define TMC_SW_MISO PB4 + #define TMC_SW_MOSI PB5 +#endif + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA8 +#define FAN_PIN PC8 +#define HEATER_BED_PIN PC9 + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PB1 // Analog Input +#define TEMP_0_PIN PA0 // Analog Input + +// +// LCD Pins +// + +/** + * _____ _____ + * NC | · · | GND 5V | · · | GND + * RESET | · · | PB9 (SD_DETECT) (LCD_D7) PC14 | · · | PC15 (LCD_D6) + * (MOSI) PB5 | · · | PB8 (BTN_EN2) (LCD_D5) PB7 | · · | PC13 (LCD_D4) + * (SD_SS) PA15 | · · | PD2 (BTN_EN1) (LCD_RS) PC12 | · · | PB6 (LCD_EN) + * (SCK) PB3 | · · | PB4 (MISO) (BTN_ENC) PC11 | · · | PC10 (BEEPER) + * ----- ----- + * EXP2 EXP1 + */ + +#if ENABLED(ULTRA_LCD) + #define BEEPER_PIN PC10 + #define BTN_ENC PC11 + #define LCD_PINS_RS PC12 + + #define BTN_EN1 PD2 + #define BTN_EN2 PB8 + + #define LCD_PINS_ENABLE PB6 + + #if ENABLED(FYSETC_MINI_12864) + + #define LCD_BACKLIGHT_PIN -1 + #define LCD_RESET_PIN PC13 + #define DOGLCD_A0 PC12 + #define DOGLCD_CS PB6 + #define DOGLCD_SCK PB3 + #define DOGLCD_MOSI PB5 + + #define FORCE_SOFT_SPI // SPI MODE3 + + #define LED_PIN PB7 // red pwm + //#define LED_PIN PC15 // green + //#define LED_PIN PC14 // blue + + //#if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) + // #ifndef RGB_LED_R_PIN + // #define RGB_LED_R_PIN PB7 + // #endif + // #ifndef RGB_LED_G_PIN + // #define RGB_LED_G_PIN PC15 + // #endif + // #ifndef RGB_LED_B_PIN + // #define RGB_LED_B_PIN PC14 + // #endif + //#elif ENABLED(FYSETC_MINI_12864_2_1) + // #define NEOPIXEL_PIN PB7 + //#endif + + #else // !FYSETC_MINI_12864 + + #define LCD_PINS_D4 PC13 + #if ENABLED(ULTIPANEL) + #define LCD_PINS_D5 PB7 + #define LCD_PINS_D6 PC15 + #define LCD_PINS_D7 PC14 + #endif + + #endif // !FYSETC_MINI_12864 + +#endif // ULTRA_LCD + +// +// SD Card +// + +// By default the onboard SD is enabled. +// To disable it and use an external SD (connected to LCD) +// enable STM32_SD_LCD. + +//#define STM32_SD_LCD + +#if ENABLED(STM32_SD_LCD) + #define ENABLE_SPI3 + #define SD_DETECT_PIN PB9 + #define SCK_PIN PB3 + #define MISO_PIN PB4 + #define MOSI_PIN PB5 + #define SS_PIN PA15 +#else + #define ENABLE_SPI1 + #define SD_DETECT_PIN PA3 + #define SCK_PIN PA5 + #define MISO_PIN PA6 + #define MOSI_PIN PA7 + #define SS_PIN PA4 +#endif diff --git a/Marlin/src/pins/pins_BIGTREE_SKR_V1.3.h b/Marlin/src/pins/pins_BIGTREE_SKR_V1.3.h index 730610214d..7509eddbba 100644 --- a/Marlin/src/pins/pins_BIGTREE_SKR_V1.3.h +++ b/Marlin/src/pins/pins_BIGTREE_SKR_V1.3.h @@ -107,9 +107,9 @@ #define TMC_SW_SCK P0_04 #endif -#if HAS_DRIVER(TMC2208) +#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) /** - * TMC2208 stepper drivers + * TMC2208/TMC2209 stepper drivers * * Hardware serial communication ports. * If undefined software serial is used according to the pins below diff --git a/Marlin/src/pins/pins_BQ_ZUM_MEGA_3D.h b/Marlin/src/pins/pins_BQ_ZUM_MEGA_3D.h index c09e946f5d..93862c2856 100644 --- a/Marlin/src/pins/pins_BQ_ZUM_MEGA_3D.h +++ b/Marlin/src/pins/pins_BQ_ZUM_MEGA_3D.h @@ -53,14 +53,16 @@ #define SPINDLE_LASER_PWM_PIN 44 // MUST BE HARDWARE PWM #define SPINDLE_DIR_PIN 42 -#include "pins_RAMPS_13.h" - // // Limit Switches // -#undef X_MAX_PIN #define X_MAX_PIN 79 // 2 +// +// Import RAMPS 1.3 pins +// +#include "pins_RAMPS_13.h" + // // Z Probe (when not Z_MIN_PIN) // diff --git a/Marlin/src/pins/pins_EINSTART-S.h b/Marlin/src/pins/pins_EINSTART-S.h index c078a2d9c6..1bce75d22b 100644 --- a/Marlin/src/pins/pins_EINSTART-S.h +++ b/Marlin/src/pins/pins_EINSTART-S.h @@ -42,28 +42,28 @@ // // Limit Switches // -#define X_STOP_PIN 44 // 2560 PIN 40 -#define Y_STOP_PIN 43 // 2560 PIN 41 -#define Z_STOP_PIN 42 // 2560 PIN 42 +#define X_STOP_PIN 44 +#define Y_STOP_PIN 43 +#define Z_STOP_PIN 42 // // Steppers // -#define X_STEP_PIN 76 // 2560 PIN 68 -#define X_DIR_PIN 75 // 2560 PIN 67 -#define X_ENABLE_PIN 73 // 2560 PIN 66 +#define X_STEP_PIN 76 +#define X_DIR_PIN 75 +#define X_ENABLE_PIN 73 -#define Y_STEP_PIN 31 // 2560 PIN 59 -#define Y_DIR_PIN 32 // 2560 PIN 58 -#define Y_ENABLE_PIN 72 // 2560 PIN 65 +#define Y_STEP_PIN 31 +#define Y_DIR_PIN 32 +#define Y_ENABLE_PIN 72 -#define Z_STEP_PIN 34 // 2560 PIN 56 -#define Z_DIR_PIN 35 // 2560 PIN 55 -#define Z_ENABLE_PIN 33 // 2560 PIN 57 +#define Z_STEP_PIN 34 +#define Z_DIR_PIN 35 +#define Z_ENABLE_PIN 33 -#define E0_STEP_PIN 36 // 2560 PIN 54 -#define E0_DIR_PIN 37 // 2560 PIN 53 -#define E0_ENABLE_PIN 30 // 2560 PIN 60 +#define E0_STEP_PIN 36 +#define E0_DIR_PIN 37 +#define E0_ENABLE_PIN 30 // // Temperature Sensors @@ -74,16 +74,16 @@ // // Heaters / Fans // -#define HEATER_0_PIN 83 // 2560 PIN 49 -#define HEATER_BED_PIN 38 // 2560 PIN 50 +#define HEATER_0_PIN 83 +#define HEATER_BED_PIN 38 -#define FAN_PIN 82 // 2560 PIN 48 +#define FAN_PIN 82 // // Misc. Functions // -#define SDSS 53 // 2560 PIN 19 -#define LED_PIN 4 // 2560 PIN 1 +#define SDSS 53 +#define LED_PIN 4 ////////////////////////// // LCDs and Controllers // @@ -97,24 +97,24 @@ // u8glib constructor // U8GLIB_SH1106_128X64 u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, LCD_PINS_DC, LCD_PINS_RS); -#define LCD_PINS_DC 78 // 2560 PIN 4 -#define LCD_PINS_RS 79 // 2560 PIN 8 +#define LCD_PINS_DC 78 +#define LCD_PINS_RS 79 // DOGM SPI LCD Support -#define DOGLCD_CS 3 // 2560 PIN 7 -#define DOGLCD_MOSI 2 // 2560 PIN 6 -#define DOGLCD_SCK 5 // 2560 PIN 5 -#define DOGLCD_A0 2 // 2560 PIN 6 +#define DOGLCD_CS 3 +#define DOGLCD_MOSI 2 +#define DOGLCD_SCK 5 +#define DOGLCD_A0 2 // // LCD Display input pins // -#define BTN_UP 25 // 2560 PIN 75 -#define BTN_DWN 26 // 2560 PIN 74 -#define BTN_LFT 27 // 2560 PIN 73 -#define BTN_RT 28 // 2560 PIN 72 +#define BTN_UP 25 +#define BTN_DWN 26 +#define BTN_LFT 27 +#define BTN_RT 28 // 'OK' button -#define BTN_ENC 29 // 2560 PIN 71 +#define BTN_ENC 29 // Set Kill to right arrow, same as RIGID_PANEL -#define KILL_PIN 28 // 2560 PIN 72 +#define KILL_PIN 28 diff --git a/Marlin/src/pins/pins_ESP32.h b/Marlin/src/pins/pins_ESP32.h index dad1e0d818..cbe9554454 100644 --- a/Marlin/src/pins/pins_ESP32.h +++ b/Marlin/src/pins/pins_ESP32.h @@ -30,18 +30,24 @@ #define BOARD_NAME "Espressif ESP32" +// +// I2S (steppers & other output-only pins) +// +#define I2S_STEPPER_STREAM +#define I2S_WS 25 +#define I2S_BCK 26 +#define I2S_DATA 27 + // // Limit Switches // -#define X_MIN_PIN 34 -#define Y_MIN_PIN 35 -#define Z_MIN_PIN 15 +#define X_MIN_PIN 34 +#define Y_MIN_PIN 35 +#define Z_MIN_PIN 15 // // Steppers // -#define I2S_STEPPER_STREAM - #define X_STEP_PIN 128 #define X_DIR_PIN 129 #define X_ENABLE_PIN 130 diff --git a/Marlin/src/pins/pins_FYSETC_F6_13.h b/Marlin/src/pins/pins_FYSETC_F6_13.h index 800abbc892..0ad70ce061 100644 --- a/Marlin/src/pins/pins_FYSETC_F6_13.h +++ b/Marlin/src/pins/pins_FYSETC_F6_13.h @@ -116,7 +116,7 @@ // the jumper next to the limit switch socket when using sensorless homing. // -#if HAS_DRIVER(TMC2208) +#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) // Software serial #define X_SERIAL_RX_PIN 71 #define X_SERIAL_TX_PIN 72 diff --git a/Marlin/src/pins/pins_GT2560_V3.h b/Marlin/src/pins/pins_GT2560_V3.h index 9ea31965c2..672cade579 100644 --- a/Marlin/src/pins/pins_GT2560_V3.h +++ b/Marlin/src/pins/pins_GT2560_V3.h @@ -40,12 +40,30 @@ // // Limit Switches // -#define X_MIN_PIN 24 -#define X_MAX_PIN 22 -#define Y_MIN_PIN 28 -#define Y_MAX_PIN 26 -#define Z_MIN_PIN 30 -#define Z_MAX_PIN 32 +#ifndef X_STOP_PIN + #ifndef X_MIN_PIN + #define X_MIN_PIN 24 + #endif + #ifndef X_MAX_PIN + #define X_MAX_PIN 22 + #endif +#endif +#ifndef Y_STOP_PIN + #ifndef Y_MIN_PIN + #define Y_MIN_PIN 28 + #endif + #ifndef Y_MAX_PIN + #define Y_MAX_PIN 26 + #endif +#endif +#ifndef Z_STOP_PIN + #ifndef Z_MIN_PIN + #define Z_MIN_PIN 30 + #endif + #ifndef Z_MAX_PIN + #define Z_MAX_PIN 32 + #endif +#endif // // Z Probe (when not Z_MIN_PIN) diff --git a/Marlin/src/pins/pins_GT2560_V3_MC2.h b/Marlin/src/pins/pins_GT2560_V3_MC2.h index 42691f4161..ab2b648f29 100644 --- a/Marlin/src/pins/pins_GT2560_V3_MC2.h +++ b/Marlin/src/pins/pins_GT2560_V3_MC2.h @@ -26,16 +26,9 @@ #define BOARD_NAME "GT2560 V3.0 (MC2)" -#include "pins_GT2560_V3.h" - -#undef X_MIN_PIN #define X_MIN_PIN 22 - -#undef X_MAX_PIN #define X_MAX_PIN 24 - -#undef Y_MIN_PIN #define Y_MIN_PIN 26 - -#undef Y_MAX_PIN #define Y_MAX_PIN 28 + +#include "pins_GT2560_V3.h" diff --git a/Marlin/src/pins/pins_JGAURORA_A5S_A1.h b/Marlin/src/pins/pins_JGAURORA_A5S_A1.h new file mode 100644 index 0000000000..014dda0590 --- /dev/null +++ b/Marlin/src/pins/pins_JGAURORA_A5S_A1.h @@ -0,0 +1,125 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + + /** + * 2017 Victor Perez Marlin for stm32f1 test + * 2018 Modified by Pablo Crespo for Morpheus Board (https://github.com/pscrespo/Morpheus-STM32) + * 2019 Modified by Roberto Mariani & Samuel Pinches for JGAurora A5S & A1 Board. + */ + +/** + * JGAurora A5S A1 Board pin assignments + */ + +#ifndef __STM32F1__ + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#define BOARD_NAME "JGAurora A5S A1 board" + +// #define STM32_XL_DENSITY // required, but should be set by platformio flags, not here! (why? not sure.) + +//#define MCU_STM32F103ZE // not yet required + +// // I2C EEPROM with 64K of space - AT24C64 +// #define I2C_EEPROM +// #define E2END 0x7FFF + +// Enable EEPROM Emulation for this board + +//#define FLASH_EEPROM_EMULATION 1 +//#define E2END 0xFFF //((uint32)(EEPROM_START_ADDRESS + EEPROM_PAGE_SIZE + EEPROM_PAGE_SIZE)) // not 0xFFF +//#define EEPROM_CHITCHAT +//#define DEBUG_EEPROM_READWRITE + +// +// Limit Switches +// +#define X_STOP_PIN PC6 +#define Y_STOP_PIN PG8 +#define Z_STOP_PIN PG7 + +// +// Steppers +// +#define X_STEP_PIN PD6 +#define X_DIR_PIN PD3 +#define X_ENABLE_PIN PG9 + +#define Y_STEP_PIN PG12 +#define Y_DIR_PIN PG11 +#define Y_ENABLE_PIN PG13 + +#define Z_STEP_PIN PG15 +#define Z_DIR_PIN PG14 +#define Z_ENABLE_PIN PB8 + +#define E0_STEP_PIN PE2 +#define E0_DIR_PIN PB9 +#define E0_ENABLE_PIN PE3 + +#define E1_STEP_PIN PE5 +#define E1_DIR_PIN PE4 +#define E1_ENABLE_PIN PE6 + +// +// Temperature Sensors +// +#define TEMP_0_PIN PC2 +#define TEMP_BED_PIN PC1 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA2 +#define HEATER_BED_PIN PA3 + +#define FAN_PIN PA1 + +#define PS_ON_PIN PA0 +#define FIL_RUNOUT_PIN PC7 + +// +// LCD +// +#define LCD_BACKLIGHT_PIN PF11 +#define FSMC_CS_PIN PD7 +#define FSMC_RS_PIN PG0 + +// +// SD Card +// +#define SD_DETECT_PIN PF10 + +// +// Misc. +// +#define BEEPER_PIN PC3 // use PB7 to shut up if desired +#define LED_PIN PC13 + +// Touch support +#define BTN_ENC PA11 // Real pin is needed to enable encoder's push button functionality used by touch screen. PA11 gives stable value. + +#define TOUCH_CS PA4 +//#define TOUCH_INTERRUPT PC4 // Not yet implemented + +#define NO_PAUSE_AFTER_PRINT diff --git a/Marlin/src/pins/pins_MELZI_CREALITY.h b/Marlin/src/pins/pins_MELZI_CREALITY.h index 9ab40187e6..0799d73e29 100644 --- a/Marlin/src/pins/pins_MELZI_CREALITY.h +++ b/Marlin/src/pins/pins_MELZI_CREALITY.h @@ -45,13 +45,12 @@ #undef LCD_PINS_D5 #undef LCD_PINS_D6 #undef LCD_PINS_D7 -#undef FIL_RUNOUT_PIN +#undef FIL_RUNOUT_PIN // Uses Beeper/LED Pin Pulled to GND #define LCD_SDSS 31 // Smart Controller SD card reader (rather than the Melzi) #define LCD_PINS_RS 28 // ST9720 CS #define LCD_PINS_ENABLE 17 // ST9720 DAT #define LCD_PINS_D4 30 // ST9720 CLK -#define FIL_RUNOUT_PIN -1 // Uses Beeper/LED Pin Pulled to GND #if DISABLED(SPEAKER) && ENABLED(BLTOUCH) #define SERVO0_PIN 27 diff --git a/Marlin/src/pins/pins_MIGHTYBOARD_REVE.h b/Marlin/src/pins/pins_MIGHTYBOARD_REVE.h index 5a4fa42354..fdc91bdff8 100644 --- a/Marlin/src/pins/pins_MIGHTYBOARD_REVE.h +++ b/Marlin/src/pins/pins_MIGHTYBOARD_REVE.h @@ -68,6 +68,16 @@ #define Z_MIN_PROBE_PIN 42 #endif +// +// Filament Runout Pins +// +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN 49 +#endif +#ifndef FIL_RUNOUT2_PIN + #define FIL_RUNOUT2_PIN 47 +#endif + // // Steppers // @@ -186,143 +196,102 @@ #endif #endif -// -// Extruder Auto Fan Pins -// -#define ORIG_E0_AUTO_FAN_PIN EX1_FAN_PIN -#define ORIG_E1_AUTO_FAN_PIN EX2_FAN_PIN - // // Misc. Functions // #define LED_PIN 13 // B7 #define CUTOFF_RESET_PIN 16 // H1 #define CUTOFF_TEST_PIN 17 // H0 -#define CASE_LIGHT_PIN 44 // L5 MUST BE HARDWARE PWM // // LCD / Controller // -#ifdef REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER +#if ENABLED(ULTRA_LCD) - #define LCD_PINS_RS 33 // C4: LCD-STROBE - #define LCD_PINS_ENABLE 72 // J2: LEFT - #define LCD_PINS_D4 35 // C2: LCD-CLK - #define LCD_PINS_D5 32 // C5: RLED - #define LCD_PINS_D6 34 // C3: LCD-DATA - #define LCD_PINS_D7 31 // C6: GLED + #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) - #define BTN_EN2 75 // J4, UP - #define BTN_EN1 73 // J3, DOWN - //STOP button connected as KILL_PIN - #define KILL_PIN 14 // J1, RIGHT - //KILL - not connected + #define LCD_PINS_RS 33 // C4: LCD-STROBE + #define LCD_PINS_ENABLE 72 // J2: LEFT + #define LCD_PINS_D4 35 // C2: LCD-CLK + #define LCD_PINS_D5 32 // C5: RLED + #define LCD_PINS_D6 34 // C3: LCD-DATA + #define LCD_PINS_D7 31 // C6: GLED - #define BEEPER_PIN 8 // H5, SD_WP + #define BTN_EN2 75 // J4, UP + #define BTN_EN1 73 // J3, DOWN + //STOP button connected as KILL_PIN + #define KILL_PIN 14 // J1, RIGHT + //KILL - not connected + + #define BEEPER_PIN 8 // H5, SD_WP + + //on board leds + #define STAT_LED_RED_LED SERVO0_PIN // C1 (1280-EX1, DEBUG2) + #define STAT_LED_BLUE_PIN SERVO1_PIN // C0 (1280-EX2, DEBUG3) + + #else + // Replicator uses a 3-wire SR controller with HD44780 + #define SR_DATA_PIN 34 // C3 + #define SR_CLK_PIN 35 // C2 + #define SR_STROBE_PIN 33 // C4 + + #define BTN_UP 75 // J4 + #define BTN_DWN 73 // J3 + #define BTN_LFT 72 // J2 + #define BTN_RT 14 // J1 + + // Disable encoder + #undef BTN_EN1 + #undef BTN_EN2 + + #define BEEPER_PIN 4 // G5 + + #define STAT_LED_RED_PIN 32 // C5 + #define STAT_LED_BLUE_PIN 31 // C6 (Actually green) + + #endif #define BTN_CENTER 15 // J0 #define BTN_ENC BTN_CENTER - //on board leds - #define STAT_LED_RED_LED SERVO0_PIN // C1 (1280-EX1, DEBUG2) - #define STAT_LED_BLUE_PIN SERVO1_PIN // C0 (1280-EX2, DEBUG3) - -#else - // Replicator uses a 3-wire SR controller with HD44780 - // For now, pretend it's the SAV - // - //#define FF_INTERFACEBOARD - - #define SR_DATA_PIN 34 // C3 - #define SR_CLK_PIN 35 // C2 - #define SR_STROBE_PIN 33 // C4 - - #define BTN_UP 75 // J4 - #define BTN_DWN 73 // J3 - #define BTN_LFT 72 // J2 - #define BTN_RT 14 // J1 - #define BTN_CENTER 15 // J0 - #define BTN_ENC BTN_CENTER - - // Disable encoder - #undef BTN_EN1 - #undef BTN_EN2 - - #define BEEPER_PIN 4 // G5 - - #define STAT_LED_RED_PIN 32 // C5 - #define STAT_LED_BLUE_PIN 31 // C6 (Actually green) - -#endif +#endif // ULTRA_LCD // // SD Card // #define SDSS 53 // B0 #define SD_DETECT_PIN 9 // H6 -#define MAX_PIN THERMO_SCK_PIN // -// M3/M4/M5 - Spindle/Laser Control +//TMC 2208 // -#define SPINDLE_LASER_ENA_PIN 66 // K4 Pin should have a pullup! -#define SPINDLE_LASER_PWM_PIN 8 // H5 MUST BE HARDWARE PWM -#define SPINDLE_DIR_PIN 67 // K5 +#if HAS_DRIVER(TMC2208) + /** + * TMC2208 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + #define X_HARDWARE_SERIAL Serial2 + #define Y_HARDWARE_SERIAL Serial1 + /** + * Software serial + */ -// Check if all pins are defined in mega/pins_arduino.h -//#include -static_assert(NUM_DIGITAL_PINS > MAX_PIN, "add missing pins to [arduino dir]/hardware/arduino/avr/variants/mega/pins_arduino.h based on fastio.h" - "to digital_pin_to_port_PGM, digital_pin_to_bit_mask_PGM, digital_pin_to_timer_PGM, NUM_DIGITAL_PINS, see below"); + #define X_SERIAL_TX_PIN 16 + #define X_SERIAL_RX_PIN 17 -/* in [arduino dir]/hardware/arduino/avr/variants/mega/pins_arduino.h -change: -#define NUM_DIGITAL_PINS 70 -to: -#define NUM_DIGITAL_PINS 80 + #define Y_SERIAL_TX_PIN 18 + #define Y_SERIAL_RX_PIN 19 -to digital_pin_to_port_PGM add at the end: -const uint8_t PROGMEM digital_pin_to_port_PGM[] = { -.... - PG , // PG 4 ** 70 ** - PG , // PG 3 ** 71 ** - PJ , // PJ 2 ** 72 ** - PJ , // PJ 3 ** 73 ** - PJ , // PJ 7 ** 74 ** - PJ , // PJ 4 ** 75 ** - PJ , // PJ 5 ** 76 ** - PJ , // PJ 6 ** 77 ** - PE , // PE 2 ** 78 ** - PE , // PE 6 ** 79 ** -}; + #define Z_SERIAL_TX_PIN 41 + #define Z_SERIAL_RX_PIN 66 -to digital_pin_to_bit_mask_PGM add at the end: -const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { -.... - _BV( 4 ) , // PG 4 ** 70 ** - _BV( 3 ) , // PG 3 ** 71 ** - _BV( 2 ) , // PJ 2 ** 72 ** - _BV( 3 ) , // PJ 3 ** 73 ** - _BV( 7 ) , // PJ 7 ** 74 ** - _BV( 4 ) , // PJ 4 ** 75 ** - _BV( 5 ) , // PJ 5 ** 76 ** - _BV( 6 ) , // PJ 6 ** 77 ** - _BV( 2 ) , // PE 2 ** 78 ** - _BV( 6 ) , // PE 6 ** 79 ** -}; + #define E0_SERIAL_TX_PIN 40 + #define E0_SERIAL_RX_PIN 67 -to digital_pin_to_timer_PGM add at the end: -const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { -.... - NOT_ON_TIMER , // PG 4 ** 70 ** - NOT_ON_TIMER , // PG 3 ** 71 ** - NOT_ON_TIMER , // PJ 2 ** 72 ** - NOT_ON_TIMER , // PJ 3 ** 73 ** - NOT_ON_TIMER , // PJ 7 ** 74 ** - NOT_ON_TIMER , // PJ 4 ** 75 ** - NOT_ON_TIMER , // PJ 5 ** 76 ** - NOT_ON_TIMER , // PJ 6 ** 77 ** - NOT_ON_TIMER , // PE 2 ** 78 ** - NOT_ON_TIMER , // PE 6 ** 79 ** -}; -*/ + #define E1_SERIAL_TX_PIN 37 + #define E1_SERIAL_RX_PIN 68 + +#endif diff --git a/Marlin/src/pins/pins_MKS_SBASE.h b/Marlin/src/pins/pins_MKS_SBASE.h index dd333745c2..f9fb944982 100644 --- a/Marlin/src/pins/pins_MKS_SBASE.h +++ b/Marlin/src/pins/pins_MKS_SBASE.h @@ -288,7 +288,7 @@ /** * Example for trinamic drivers using the J8 connector on MKs Sbase. - * 2130s need 1 pin for each driver. 2208s need 2 pins for serial control. + * 2130s need 1 pin for each driver. 2208/2209s need 2 pins for serial control. * This board does not have enough pins to use hardware serial. */ @@ -316,7 +316,7 @@ #endif #endif -#if MB(MKS_SBASE) && HAS_DRIVER(TMC2208) +#if MB(MKS_SBASE) && (HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)) // The shortage of pins becomes apparent. // Worst case you may have to give up the LCD // RX pins need to be interrupt capable diff --git a/Marlin/src/pins/pins_MKS_SGEN.h b/Marlin/src/pins/pins_MKS_SGEN.h index e5de7de8e1..8a4fb3526f 100644 --- a/Marlin/src/pins/pins_MKS_SGEN.h +++ b/Marlin/src/pins/pins_MKS_SGEN.h @@ -42,7 +42,7 @@ //#define BTN_EN1 P1_23 // EXP2.5 //#define BTN_EN2 P1_22 // EXP2.3 -#if HAS_DRIVER(TMC2208) +#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) // The shortage of pins becomes apparent. // In the worst case you may have to give up the LCD. // RX pins must be interrupt-capable. diff --git a/Marlin/src/pins/pins_RAMBO.h b/Marlin/src/pins/pins_RAMBO.h index b6890d9537..0186abd169 100644 --- a/Marlin/src/pins/pins_RAMBO.h +++ b/Marlin/src/pins/pins_RAMBO.h @@ -152,6 +152,12 @@ #define SPINDLE_LASER_ENA_PIN 31 // Pin should have a pullup! #define SPINDLE_DIR_PIN 32 +// +// M7/M8/M9 - Coolant Control +// +#define COOLANT_MIST_PIN 22 +#define COOLANT_FLOOD_PIN 44 + // // Průša i3 MK2 Multiplexer Support // diff --git a/Marlin/src/pins/pins_RAMPS.h b/Marlin/src/pins/pins_RAMPS.h index 88249ada31..68b38202a8 100644 --- a/Marlin/src/pins/pins_RAMPS.h +++ b/Marlin/src/pins/pins_RAMPS.h @@ -70,8 +70,12 @@ #define SERVO0_PIN 11 #endif #endif -#define SERVO1_PIN 6 -#define SERVO2_PIN 5 +#ifndef SERVO1_PIN + #define SERVO1_PIN 6 +#endif +#ifndef SERVO2_PIN + #define SERVO2_PIN 5 +#endif #ifndef SERVO3_PIN #define SERVO3_PIN 4 #endif @@ -79,14 +83,30 @@ // // Limit Switches // -#define X_MIN_PIN 3 -#ifndef X_MAX_PIN - #define X_MAX_PIN 2 +#ifndef X_STOP_PIN + #ifndef X_MIN_PIN + #define X_MIN_PIN 3 + #endif + #ifndef X_MAX_PIN + #define X_MAX_PIN 2 + #endif +#endif +#ifndef Y_STOP_PIN + #ifndef Y_MIN_PIN + #define Y_MIN_PIN 14 + #endif + #ifndef Y_MAX_PIN + #define Y_MAX_PIN 15 + #endif +#endif +#ifndef Z_STOP_PIN + #ifndef Z_MIN_PIN + #define Z_MIN_PIN 18 + #endif + #ifndef Z_MAX_PIN + #define Z_MAX_PIN 19 + #endif #endif -#define Y_MIN_PIN 14 -#define Y_MAX_PIN 15 -#define Z_MIN_PIN 18 -#define Z_MAX_PIN 19 // // Z Probe (when not Z_MIN_PIN) @@ -273,9 +293,9 @@ #endif #endif -#if HAS_DRIVER(TMC2208) +#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) /** - * TMC2208 stepper drivers + * TMC2208/TMC2209 stepper drivers * * Hardware serial communication ports. * If undefined software serial is used according to the pins below diff --git a/Marlin/src/pins/pins_RAMPS_DAGOMA.h b/Marlin/src/pins/pins_RAMPS_DAGOMA.h new file mode 100644 index 0000000000..4c251e3841 --- /dev/null +++ b/Marlin/src/pins/pins_RAMPS_DAGOMA.h @@ -0,0 +1,39 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 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 . + * + */ + +#if HOTENDS > 2 || E_STEPPERS > 2 + #error "Dagoma3D F5 RAMPS supports only 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_NAME "Dagoma3D F5 RAMPS" + +#define X_STOP_PIN 2 +#define Y_STOP_PIN 3 +#define Z_STOP_PIN 15 +#define FIL_RUNOUT_PIN 39 + +#define ORIG_E0_AUTO_FAN_PIN 7 + +// +// Import RAMPS 1.4 pins +// +#include "pins_RAMPS.h" diff --git a/Marlin/src/pins/pins_RAMPS_FD_V1.h b/Marlin/src/pins/pins_RAMPS_FD_V1.h index e64b9cfd2f..3f87364763 100644 --- a/Marlin/src/pins/pins_RAMPS_FD_V1.h +++ b/Marlin/src/pins/pins_RAMPS_FD_V1.h @@ -204,9 +204,9 @@ #endif // ULTRA_LCD -#if HAS_DRIVER(TMC2208) +#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) /** - * TMC2208 stepper drivers + * TMC2208/TMC2209 stepper drivers * * Hardware serial communication ports. * If undefined software serial is used according to the pins below diff --git a/Marlin/src/pins/pins_RAMPS_LINUX.h b/Marlin/src/pins/pins_RAMPS_LINUX.h index 7db43fbab3..c7771c690b 100644 --- a/Marlin/src/pins/pins_RAMPS_LINUX.h +++ b/Marlin/src/pins/pins_RAMPS_LINUX.h @@ -268,9 +268,9 @@ #endif #endif -#if ENABLED(HAVE_TMC2208) +#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) /** - * TMC2208 stepper drivers + * TMC2208/TMC2209 stepper drivers * * Hardware serial communication ports. * If undefined software serial is used according to the pins below diff --git a/Marlin/src/pins/pins_RAMPS_RE_ARM.h b/Marlin/src/pins/pins_RAMPS_RE_ARM.h index a40239c49e..74296512eb 100644 --- a/Marlin/src/pins/pins_RAMPS_RE_ARM.h +++ b/Marlin/src/pins/pins_RAMPS_RE_ARM.h @@ -106,9 +106,9 @@ #define TMC_SW_SCK P1_09 // ETH #endif -#if HAS_DRIVER(TMC2208) +#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) /** - * TMC2208 stepper drivers + * TMC2208/TMC2209 stepper drivers * * Hardware serial communication ports. * If undefined software serial is used according to the pins below diff --git a/Marlin/src/pins/pins_TRIGORILLA_14.h b/Marlin/src/pins/pins_TRIGORILLA_14.h index 7d231b32da..cc47c3254d 100644 --- a/Marlin/src/pins/pins_TRIGORILLA_14.h +++ b/Marlin/src/pins/pins_TRIGORILLA_14.h @@ -26,6 +26,16 @@ #define BOARD_NAME "Anycubic RAMPS 1.4" +// +// Servos +// +#if MB(TRIGORILLA_14_11) + #define SERVO0_PIN 5 + #define SERVO1_PIN 4 + #define SERVO2_PIN 11 + #define SERVO3_PIN 6 +#endif + // Labeled pins #define TRIGORILLA_HEATER_BED_PIN 8 #define TRIGORILLA_HEATER_0_PIN 10 diff --git a/Marlin/src/pins/pins_TRONXY_V3_1_0.h b/Marlin/src/pins/pins_TRONXY_V3_1_0.h index 91fabb329b..8892065c1b 100644 --- a/Marlin/src/pins/pins_TRONXY_V3_1_0.h +++ b/Marlin/src/pins/pins_TRONXY_V3_1_0.h @@ -34,14 +34,16 @@ #define BOARD_NAME "TRONXY-V3-1.0" -#include "pins_RAMPS.h" - // // Servos // -#undef SERVO1_PIN #define SERVO1_PIN 12 // 2560 PIN 25/PB6 +// +// Import RAMPS 1.4 pins +// +#include "pins_RAMPS.h" + /** * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ * diff --git a/Marlin/src/pins/pins_Z_BOLT_X_SERIES.h b/Marlin/src/pins/pins_Z_BOLT_X_SERIES.h new file mode 100644 index 0000000000..b8d4fdee38 --- /dev/null +++ b/Marlin/src/pins/pins_Z_BOLT_X_SERIES.h @@ -0,0 +1,257 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 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 . + * + */ + +/** + * Z-Bolt X Series board – based on Arduino Mega2560 + */ + +#if HOTENDS > 4 || E_STEPPERS > 4 + #error "Z-Bolt X Series board supports up to 4 hotends / E-steppers." +#endif + +#define BOARD_NAME "Z-Bolt X Series" + +#if ENABLED(TARGET_LPC1768) + #error "Oops! Set MOTHERBOARD to an LPC1768-based board when building for LPC1768." +#elif defined(__STM32F1__) + #error "Oops! Set MOTHERBOARD to an STM32F1-based board when building for STM32F1." +#endif + +#if DISABLED(IS_RAMPS_SMART, IS_RAMPS_DUO, IS_RAMPS4DUE, TARGET_LPC1768) + #if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'" + #endif +#endif + +// +// Servos +// +#ifndef SERVO0_PIN + #define SERVO0_PIN 11 +#endif +#ifndef SERVO3_PIN + #define SERVO3_PIN 4 +#endif + +// +// Limit Switches +// +#define X_MIN_PIN 3 +#ifndef X_MAX_PIN + #define X_MAX_PIN 2 +#endif +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 32 +#endif + +// +// Steppers +// +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 +#ifndef X_CS_PIN + #define X_CS_PIN -1 +#endif + +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 +#ifndef Y_CS_PIN + #define Y_CS_PIN -1 +#endif + +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 +#ifndef Z_CS_PIN + #define Z_CS_PIN -1 +#endif + +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 +#ifndef E0_CS_PIN + #define E0_CS_PIN -1 +#endif + +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 +#ifndef E1_CS_PIN + #define E1_CS_PIN -1 +#endif + +// Red +#define E2_STEP_PIN 42 +#define E2_DIR_PIN 40 +#define E2_ENABLE_PIN 65 +#ifndef E2_CS_PIN + #define E2_CS_PIN -1 +#endif + +// Black +#define E3_STEP_PIN 44 +#define E3_DIR_PIN 64 +#define E3_ENABLE_PIN 66 +#ifndef E3_CS_PIN + #define E3_CS_PIN -1 +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN 13 // Analog Input +#define TEMP_1_PIN 15 // Analog Input +#define TEMP_2_PIN 5 // Analog Input (BLACK) +#define TEMP_3_PIN 9 // Analog Input (RED) +#define TEMP_BED_PIN 14 // Analog Input + +// +// Heaters / Fans +// +#define HEATER_0_PIN 10 +#define HEATER_1_PIN 7 +#define HEATER_2_PIN 6 +#define HEATER_3_PIN 5 +#define HEATER_BED_PIN 8 + +#define FAN_PIN 9 + +// +// Misc. Functions +// +#define SDSS 53 +#define LED_PIN 13 + +#ifndef FILWIDTH_PIN + #define FILWIDTH_PIN 5 // Analog Input on AUX2 +#endif + +// Оn the servos connector +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN 4 +#endif + +#ifndef PS_ON_PIN + #define PS_ON_PIN 12 +#endif + +#define AUX2_PINS_FREE !( BOTH(ULTRA_LCD, NEWPANEL) && ANY(PANEL_ONE, VIKI2, miniVIKI, MINIPANEL, REPRAPWORLD_KEYPAD) ) + +#if ENABLED(CASE_LIGHT_ENABLE) && !defined(CASE_LIGHT_PIN) && !defined(SPINDLE_LASER_ENA_PIN) + #if NUM_SERVOS <= 1 // try to use servo connector first + #define CASE_LIGHT_PIN 6 // MUST BE HARDWARE PWM + #elif AUX2_PINS_FREE + #define CASE_LIGHT_PIN 44 // MUST BE HARDWARE PWM + #endif +#endif + +// +// M3/M4/M5 - Spindle/Laser Control +// +#if ENABLED(SPINDLE_LASER_ENABLE) && !PIN_EXISTS(SPINDLE_LASER_ENA) + #if !defined(NUM_SERVOS) || NUM_SERVOS == 0 // try to use servo connector first + #define SPINDLE_LASER_ENA_PIN 4 // Pin should have a pullup/pulldown! + #define SPINDLE_LASER_PWM_PIN 6 // MUST BE HARDWARE PWM + #define SPINDLE_DIR_PIN 5 + #elif AUX2_PINS_FREE + #define SPINDLE_LASER_ENA_PIN 40 // Pin should have a pullup/pulldown! + #define SPINDLE_LASER_PWM_PIN 44 // MUST BE HARDWARE PWM + #define SPINDLE_DIR_PIN 65 + #endif +#endif + +#undef AUX2_PINS_FREE + +// +// TMC software SPI +// +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI 66 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO 44 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK 64 + #endif +#endif + +#if HAS_DRIVER(TMC2208) + /** + * TMC2208 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL Serial1 + //#define X2_HARDWARE_SERIAL Serial1 + //#define Y_HARDWARE_SERIAL Serial1 + //#define Y2_HARDWARE_SERIAL Serial1 + //#define Z_HARDWARE_SERIAL Serial1 + //#define Z2_HARDWARE_SERIAL Serial1 + //#define E0_HARDWARE_SERIAL Serial1 + //#define E1_HARDWARE_SERIAL Serial1 + //#define E2_HARDWARE_SERIAL Serial1 + //#define E3_HARDWARE_SERIAL Serial1 + //#define E4_HARDWARE_SERIAL Serial1 + + // + // Software serial + // + + #define X_SERIAL_TX_PIN 40 + #define X_SERIAL_RX_PIN 63 + #define X2_SERIAL_TX_PIN -1 + #define X2_SERIAL_RX_PIN -1 + + #define Y_SERIAL_TX_PIN 59 + #define Y_SERIAL_RX_PIN 64 + #define Y2_SERIAL_TX_PIN -1 + #define Y2_SERIAL_RX_PIN -1 + + #define Z_SERIAL_TX_PIN 42 + #define Z_SERIAL_RX_PIN 65 + #define Z2_SERIAL_TX_PIN -1 + #define Z2_SERIAL_RX_PIN -1 + + #define E0_SERIAL_TX_PIN 44 + #define E0_SERIAL_RX_PIN 66 + #define E1_SERIAL_TX_PIN -1 + #define E1_SERIAL_RX_PIN -1 + #define E2_SERIAL_TX_PIN -1 + #define E2_SERIAL_RX_PIN -1 + #define E3_SERIAL_TX_PIN -1 + #define E3_SERIAL_RX_PIN -1 + #define E4_SERIAL_TX_PIN -1 + #define E4_SERIAL_RX_PIN -1 +#endif diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 51702fa229..433f9c1ee6 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -81,10 +81,10 @@ uint8_t CardReader::workDirDepth; char **CardReader::sortshort, **CardReader::sortnames; #else char CardReader::sortshort[SDSORT_LIMIT][FILENAME_LENGTH]; - char CardReader::sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN]; + char CardReader::sortnames[SDSORT_LIMIT][SORTED_LONGNAME_STORAGE]; #endif #elif DISABLED(SDSORT_USES_STACK) - char CardReader::sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN]; + char CardReader::sortnames[SDSORT_LIMIT][SORTED_LONGNAME_STORAGE]; #endif #if HAS_FOLDER_SORTING @@ -367,8 +367,8 @@ void CardReader::openAndPrintFile(const char *name) { char cmd[4 + strlen(name) + 1]; // Room for "M23 ", filename, and null sprintf_P(cmd, PSTR("M23 %s"), name); for (char *c = &cmd[4]; *c; c++) *c = tolower(*c); - enqueue_and_echo_command_now(cmd); - enqueue_and_echo_commands_P(PSTR("M24")); + queue.enqueue_one_now(cmd); + queue.enqueue_now_P(PSTR("M24")); } void CardReader::startFileprint() { @@ -760,11 +760,13 @@ void CardReader::setroot() { #endif #else // Copy filenames into the static array - #if SORTED_LONGNAME_MAXLEN != LONG_FILENAME_LENGTH - #define SET_SORTNAME(I) do{ strncpy(sortnames[I], longest_filename(), SORTED_LONGNAME_MAXLEN); \ - sortnames[I][SORTED_LONGNAME_MAXLEN] = '\0'; }while(0) + #define _SET_SORTNAME(I) strncpy(sortnames[I], longest_filename(), SORTED_LONGNAME_MAXLEN) + #if SORTED_LONGNAME_MAXLEN == LONG_FILENAME_LENGTH + // Short name sorting always use LONG_FILENAME_LENGTH with no trailing nul + #define SET_SORTNAME(I) _SET_SORTNAME(I) #else - #define SET_SORTNAME(I) strncpy(sortnames[I], longest_filename(), SORTED_LONGNAME_MAXLEN) + // Copy multiple name blocks. Add a nul for the longest case. + #define SET_SORTNAME(I) do{ _SET_SORTNAME(I); sortnames[I][SORTED_LONGNAME_MAXLEN] = '\0'; }while(0) #endif #if ENABLED(SDSORT_CACHE_NAMES) #define SET_SORTSHORT(I) strcpy(sortshort[I], filename) @@ -798,7 +800,7 @@ void CardReader::setroot() { // Never sort more than the max allowed // If you use folders to organize, 20 may be enough - if (fileCnt > SDSORT_LIMIT) fileCnt = SDSORT_LIMIT; + NOMORE(fileCnt, uint16_t(SDSORT_LIMIT)); // Sort order is always needed. May be static or dynamic. #if ENABLED(SDSORT_DYNAMIC_RAM) @@ -816,7 +818,7 @@ void CardReader::setroot() { sortnames = new char*[fileCnt]; #endif #elif ENABLED(SDSORT_USES_STACK) - char sortnames[fileCnt][SORTED_LONGNAME_MAXLEN]; + char sortnames[fileCnt][SORTED_LONGNAME_STORAGE]; #endif // Folder sorting needs 1 bit per entry for flags. @@ -999,7 +1001,7 @@ void CardReader::printingHasFinished() { #endif print_job_timer.stop(); - if (print_job_timer.duration() > 60) enqueue_and_echo_commands_P(PSTR("M31")); + if (print_job_timer.duration() > 60) queue.inject_P(PSTR("M31")); #if ENABLED(SDCARD_SORT_ALPHA) presort(); diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index 5bdbffaf20..623ca4dc7f 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -175,9 +175,11 @@ private: #endif #if BOTH(SDSORT_USES_RAM, SDSORT_CACHE_NAMES) && DISABLED(SDSORT_DYNAMIC_RAM) - #define SORTED_LONGNAME_MAXLEN ((SDSORT_CACHE_VFATS) * (FILENAME_LENGTH) + 1) + #define SORTED_LONGNAME_MAXLEN (SDSORT_CACHE_VFATS) * (FILENAME_LENGTH) + #define SORTED_LONGNAME_STORAGE (SORTED_LONGNAME_MAXLEN + 1) #else #define SORTED_LONGNAME_MAXLEN LONG_FILENAME_LENGTH + #define SORTED_LONGNAME_STORAGE SORTED_LONGNAME_MAXLEN #endif // Cache filenames to speed up SD menus. @@ -189,10 +191,11 @@ private: static char **sortshort, **sortnames; #else static char sortshort[SDSORT_LIMIT][FILENAME_LENGTH]; - static char sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN]; #endif - #elif DISABLED(SDSORT_USES_STACK) - static char sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN]; + #endif + + #if (ENABLED(SDSORT_CACHE_NAMES) && DISABLED(SDSORT_DYNAMIC_RAM)) || NONE(SDSORT_CACHE_NAMES, SDSORT_USES_STACK) + static char sortnames[SDSORT_LIMIT][SORTED_LONGNAME_STORAGE]; #endif // Folder sorting uses an isDir array when caching items. diff --git a/Marlin/src/sd/usb_flashdrive/lib/Usb.cpp b/Marlin/src/sd/usb_flashdrive/lib/Usb.cpp index 4ca0b2dde3..b0a6d2943d 100644 --- a/Marlin/src/sd/usb_flashdrive/lib/Usb.cpp +++ b/Marlin/src/sd/usb_flashdrive/lib/Usb.cpp @@ -46,7 +46,7 @@ void USB::init() { } uint8_t USB::getUsbTaskState(void) { - return ( usb_task_state); + return usb_task_state; } void USB::setUsbTaskState(uint8_t state) {