From ecca81beba03c0f15d682dafeab290ea136a1a9e Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Thu, 6 May 2021 19:34:15 -0500 Subject: [PATCH 01/67] Reformat features.ini --- ini/features.ini | 414 +++++++++++++++++++++++------------------------ 1 file changed, 207 insertions(+), 207 deletions(-) diff --git a/ini/features.ini b/ini/features.ini index db9dff9366..871741dca8 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -10,211 +10,211 @@ ################################# [features] -YHCB2004 = red-scorp/LiquidCrystal_AIP31068@^1.0.4, red-scorp/SoftSPIB@^1.1.1 -HAS_TFT_LVGL_UI = lvgl=https://github.com/makerbase-mks/LVGL-6.1.1-MKS/archive/master.zip - src_filter=+ - extra_scripts=download_mks_assets.py -POSTMORTEM_DEBUGGING = src_filter=+ + - build_flags=-funwind-tables -MKS_WIFI_MODULE = QRCode=https://github.com/makerbase-mks/QRCode/archive/master.zip -HAS_TRINAMIC_CONFIG = TMCStepper@~0.7.1 - src_filter=+ + + + + -HAS_STEALTHCHOP = src_filter=+ -SR_LCD_3W_NL = SailfishLCD=https://github.com/mikeshub/SailfishLCD/archive/master.zip -HAS_MOTOR_CURRENT_I2C = SlowSoftI2CMaster - src_filter=+ -HAS_TMC26X = TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip - src_filter=+ -HAS_L64XX = Arduino-L6470@0.8.0 - src_filter=+ + + + -NEOPIXEL_LED = Adafruit NeoPixel@1.5.0 - src_filter=+ -TEMP_.+_IS_MAX31865 = Adafruit MAX31865 library@~1.1.0 -USES_LIQUIDCRYSTAL = fmalpartida/LiquidCrystal@1.5.0 -USES_LIQUIDCRYSTAL_I2C = marcoschwartz/LiquidCrystal_I2C@1.1.4 -USES_LIQUIDTWI2 = LiquidTWI2@1.2.7 -HAS_WIRED_LCD = src_filter=+ -HAS_MARLINUI_HD44780 = src_filter=+ -HAS_MARLINUI_U8GLIB = U8glib-HAL@~0.4.4 - src_filter=+ -HAS_(FSMC|SPI|LTDC)_TFT = src_filter=+ + + -HAS_FSMC_TFT = src_filter=+ + -HAS_SPI_TFT = src_filter=+ + -I2C_EEPROM = src_filter=+ -SPI_EEPROM = src_filter=+ -HAS_GRAPHICAL_TFT = src_filter=+ -DWIN_CREALITY_LCD = src_filter=+ -IS_TFTGLCD_PANEL = src_filter=+ -HAS_TOUCH_BUTTONS = src_filter=+ -HAS_LCD_MENU = src_filter=+ -HAS_GAMES = src_filter=+ -MARLIN_BRICKOUT = src_filter=+ -MARLIN_INVADERS = src_filter=+ -MARLIN_MAZE = src_filter=+ -MARLIN_SNAKE = src_filter=+ -HAS_MENU_BACKLASH = src_filter=+ -HAS_MENU_BED_CORNERS = src_filter=+ -LCD_BED_LEVELING = src_filter=+ -HAS_MENU_CANCELOBJECT = src_filter=+ -HAS_MENU_DELTA_CALIBRATE = src_filter=+ -HAS_MENU_FILAMENT = src_filter=+ -LCD_INFO_MENU = src_filter=+ -HAS_MENU_JOB_RECOVERY = src_filter=+ -HAS_MULTI_LANGUAGE = src_filter=+ -HAS_MENU_LED = src_filter=+ -HAS_MENU_MEDIA = src_filter=+ -HAS_MENU_MIXER = src_filter=+ -HAS_MENU_MMU2 = src_filter=+ -HAS_MENU_PASSWORD = src_filter=+ -HAS_MENU_POWER_MONITOR = src_filter=+ -HAS_MENU_CUTTER = src_filter=+ -HAS_MENU_TEMPERATURE = src_filter=+ -HAS_MENU_TMC = src_filter=+ -HAS_MENU_TOUCH_SCREEN = src_filter=+ -HAS_MENU_TRAMMING = src_filter=+ -HAS_MENU_UBL = src_filter=+ -ANYCUBIC_LCD_CHIRON = src_filter=+ -ANYCUBIC_LCD_I3MEGA = src_filter=+ -HAS_DGUS_LCD = src_filter=+ -DGUS_LCD_UI_FYSETC = src_filter=+ -DGUS_LCD_UI_HIPRECY = src_filter=+ -DGUS_LCD_UI_MKS = src_filter=+ -DGUS_LCD_UI_ORIGIN = src_filter=+ -EXTUI_EXAMPLE = src_filter=+ -TOUCH_UI_FTDI_EVE = src_filter=+ -MALYAN_LCD = src_filter=+ -NEXTION_TFT = src_filter=+ -USE_UHS2_USB = src_filter=+ -USE_UHS3_USB = src_filter=+ -USB_FLASH_DRIVE_SUPPORT = src_filter=+ -AUTO_BED_LEVELING_BILINEAR = src_filter=+ +YHCB2004 = red-scorp/LiquidCrystal_AIP31068@^1.0.4, red-scorp/SoftSPIB@^1.1.1 +HAS_TFT_LVGL_UI = lvgl=https://github.com/makerbase-mks/LVGL-6.1.1-MKS/archive/master.zip + src_filter=+ + extra_scripts=download_mks_assets.py +POSTMORTEM_DEBUGGING = src_filter=+ + + build_flags=-funwind-tables +MKS_WIFI_MODULE = QRCode=https://github.com/makerbase-mks/QRCode/archive/master.zip +HAS_TRINAMIC_CONFIG = TMCStepper@~0.7.1 + src_filter=+ + + + + +HAS_STEALTHCHOP = src_filter=+ +SR_LCD_3W_NL = SailfishLCD=https://github.com/mikeshub/SailfishLCD/archive/master.zip +HAS_MOTOR_CURRENT_I2C = SlowSoftI2CMaster + src_filter=+ +HAS_TMC26X = TMC26XStepper=https://github.com/trinamic/TMC26XStepper/archive/master.zip + src_filter=+ +HAS_L64XX = Arduino-L6470@0.8.0 + src_filter=+ + + + +NEOPIXEL_LED = Adafruit NeoPixel@1.5.0 + src_filter=+ +TEMP_.+_IS_MAX31865 = Adafruit MAX31865 library@~1.1.0 +USES_LIQUIDCRYSTAL = fmalpartida/LiquidCrystal@1.5.0 +USES_LIQUIDCRYSTAL_I2C = marcoschwartz/LiquidCrystal_I2C@1.1.4 +USES_LIQUIDTWI2 = LiquidTWI2@1.2.7 +HAS_WIRED_LCD = src_filter=+ +HAS_MARLINUI_HD44780 = src_filter=+ +HAS_MARLINUI_U8GLIB = U8glib-HAL@~0.4.4 + src_filter=+ +HAS_(FSMC|SPI|LTDC)_TFT = src_filter=+ + + +HAS_FSMC_TFT = src_filter=+ + +HAS_SPI_TFT = src_filter=+ + +I2C_EEPROM = src_filter=+ +SPI_EEPROM = src_filter=+ +HAS_GRAPHICAL_TFT = src_filter=+ +DWIN_CREALITY_LCD = src_filter=+ +IS_TFTGLCD_PANEL = src_filter=+ +HAS_TOUCH_BUTTONS = src_filter=+ +HAS_LCD_MENU = src_filter=+ +HAS_GAMES = src_filter=+ +MARLIN_BRICKOUT = src_filter=+ +MARLIN_INVADERS = src_filter=+ +MARLIN_MAZE = src_filter=+ +MARLIN_SNAKE = src_filter=+ +HAS_MENU_BACKLASH = src_filter=+ +HAS_MENU_BED_CORNERS = src_filter=+ +LCD_BED_LEVELING = src_filter=+ +HAS_MENU_CANCELOBJECT = src_filter=+ +HAS_MENU_DELTA_CALIBRATE = src_filter=+ +HAS_MENU_FILAMENT = src_filter=+ +LCD_INFO_MENU = src_filter=+ +HAS_MENU_JOB_RECOVERY = src_filter=+ +HAS_MULTI_LANGUAGE = src_filter=+ +HAS_MENU_LED = src_filter=+ +HAS_MENU_MEDIA = src_filter=+ +HAS_MENU_MIXER = src_filter=+ +HAS_MENU_MMU2 = src_filter=+ +HAS_MENU_PASSWORD = src_filter=+ +HAS_MENU_POWER_MONITOR = src_filter=+ +HAS_MENU_CUTTER = src_filter=+ +HAS_MENU_TEMPERATURE = src_filter=+ +HAS_MENU_TMC = src_filter=+ +HAS_MENU_TOUCH_SCREEN = src_filter=+ +HAS_MENU_TRAMMING = src_filter=+ +HAS_MENU_UBL = src_filter=+ +ANYCUBIC_LCD_CHIRON = src_filter=+ +ANYCUBIC_LCD_I3MEGA = src_filter=+ +HAS_DGUS_LCD = src_filter=+ +DGUS_LCD_UI_FYSETC = src_filter=+ +DGUS_LCD_UI_HIPRECY = src_filter=+ +DGUS_LCD_UI_MKS = src_filter=+ +DGUS_LCD_UI_ORIGIN = src_filter=+ +EXTUI_EXAMPLE = src_filter=+ +TOUCH_UI_FTDI_EVE = src_filter=+ +MALYAN_LCD = src_filter=+ +NEXTION_TFT = src_filter=+ +USE_UHS2_USB = src_filter=+ +USE_UHS3_USB = src_filter=+ +USB_FLASH_DRIVE_SUPPORT = src_filter=+ +AUTO_BED_LEVELING_BILINEAR = src_filter=+ AUTO_BED_LEVELING_(3POINT|(BI)?LINEAR) = src_filter=+ -MESH_BED_LEVELING = src_filter=+ + -AUTO_BED_LEVELING_UBL = src_filter=+ + -UBL_HILBERT_CURVE = src_filter=+ -BACKLASH_COMPENSATION = src_filter=+ -BARICUDA = src_filter=+ + -BINARY_FILE_TRANSFER = src_filter=+ + -BLTOUCH = src_filter=+ -CANCEL_OBJECTS = src_filter=+ + -CASE_LIGHT_ENABLE = src_filter=+ + -EXTERNAL_CLOSED_LOOP_CONTROLLER = src_filter=+ + -USE_CONTROLLER_FAN = src_filter=+ -HAS_MOTOR_CURRENT_DAC = src_filter=+ -DIRECT_STEPPING = src_filter=+ + -EMERGENCY_PARSER = src_filter=+ - -I2C_POSITION_ENCODERS = src_filter=+ -IIC_BL24CXX_EEPROM = src_filter=+ -HAS_SPI_FLASH = src_filter=+ -HAS_ETHERNET = src_filter=+ + -HAS_FANMUX = src_filter=+ -FILAMENT_WIDTH_SENSOR = src_filter=+ + -FWRETRACT = src_filter=+ + -HOST_ACTION_COMMANDS = src_filter=+ -HOTEND_IDLE_TIMEOUT = src_filter=+ -JOYSTICK = src_filter=+ -BLINKM = src_filter=+ -HAS_COLOR_LEDS = src_filter=+ + -PCA9533 = src_filter=+ -PCA9632 = src_filter=+ -PRINTER_EVENT_LEDS = src_filter=+ -TEMP_STAT_LEDS = src_filter=+ -MAX7219_DEBUG = src_filter=+ + -HAS_MEATPACK = src_filter=+ -MIXING_EXTRUDER = src_filter=+ + -HAS_PRUSA_MMU1 = src_filter=+ -HAS_PRUSA_MMU2 = src_filter=+ + -PASSWORD_FEATURE = src_filter=+ + -ADVANCED_PAUSE_FEATURE = src_filter=+ + + -AUTO_POWER_CONTROL = src_filter=+ -HAS_POWER_MONITOR = src_filter=+ + -POWER_LOSS_RECOVERY = src_filter=+ + -PROBE_TEMP_COMPENSATION = src_filter=+ + -HAS_FILAMENT_SENSOR = src_filter=+ + -(EXT|MANUAL)_SOLENOID.* = src_filter=+ + -MK2_MULTIPLEXER = src_filter=+ -HAS_CUTTER = src_filter=+ + -HAS_DRIVER_SAFE_POWER_PROTECT = src_filter=+ -EXPERIMENTAL_I2CBUS = src_filter=+ + -MECHANICAL_GANTRY_CAL.+ = src_filter=+ -Z_MULTI_ENDSTOPS = src_filter=+ -Z_STEPPER_AUTO_ALIGN = src_filter=+ + -G26_MESH_VALIDATION = src_filter=+ -ASSISTED_TRAMMING = src_filter=+ + -HAS_MESH = src_filter=+ -HAS_LEVELING = src_filter=+ + -DELTA_AUTO_CALIBRATION = src_filter=+ -CALIBRATION_GCODE = src_filter=+ -Z_MIN_PROBE_REPEATABILITY_TEST = src_filter=+ -M100_FREE_MEMORY_WATCHER = src_filter=+ -BACKLASH_GCODE = src_filter=+ -IS_KINEMATIC = src_filter=+ -HAS_EXTRA_ENDSTOPS = src_filter=+ -SKEW_CORRECTION_GCODE = src_filter=+ -DIRECT_PIN_CONTROL = src_filter=+ + -PINS_DEBUGGING = src_filter=+ -NO_VOLUMETRICS = src_filter=- -HAS_MULTI_EXTRUDER = src_filter=+ -HAS_HOTEND_OFFSET = src_filter=+ -EDITABLE_SERVO_ANGLES = src_filter=+ -PIDTEMP = src_filter=+ -PREVENT_COLD_EXTRUSION = src_filter=+ -PIDTEMPBED = src_filter=+ -HAS_USER_THERMISTORS = src_filter=+ -SD_ABORT_ON_ENDSTOP_HIT = src_filter=+ -BAUD_RATE_GCODE = src_filter=+ -HAS_SMART_EFF_MOD = src_filter=+ -COOLANT_CONTROL = src_filter=+ -AIR_EVACUATION = src_filter=+ -HAS_SOFTWARE_ENDSTOPS = src_filter=+ -HAS_DUPLICATION_MODE = src_filter=+ -LIN_ADVANCE = src_filter=+ -PHOTO_GCODE = src_filter=+ -CONTROLLER_FAN_EDITABLE = src_filter=+ -GCODE_MACROS = src_filter=+ -GRADIENT_MIX = src_filter=+ -HAS_SAVED_POSITIONS = src_filter=+ + -PARK_HEAD_ON_PAUSE = src_filter=+ -FILAMENT_LOAD_UNLOAD_GCODES = src_filter=+ -CNC_WORKSPACE_PLANES = src_filter=+ -CNC_COORDINATE_SYSTEMS = src_filter=+ -HAS_M206_COMMAND = src_filter=+ -EXPECTED_PRINTER_CHECK = src_filter=+ -HOST_KEEPALIVE_FEATURE = src_filter=+ -REPETIER_GCODE_M360 = src_filter=+ -HAS_GCODE_M876 = src_filter=+ -HAS_RESUME_CONTINUE = src_filter=+ -HAS_LCD_CONTRAST = src_filter=+ -LCD_SET_PROGRESS_MANUALLY = src_filter=+ -TOUCH_SCREEN_CALIBRATION = src_filter=+ -ARC_SUPPORT = src_filter=+ -GCODE_MOTION_MODES = src_filter=+ -BABYSTEPPING = src_filter=+ + -Z_PROBE_SLED = src_filter=+ -G38_PROBE_TARGET = src_filter=+ -MAGNETIC_PARKING_EXTRUDER = src_filter=+ -SDSUPPORT = src_filter=+ + + + + + + -HAS_MEDIA_SUBCALLS = src_filter=+ -GCODE_REPEAT_MARKERS = src_filter=+ + -HAS_EXTRUDERS = src_filter=+ + -HAS_COOLER = src_filter=+ + -AUTO_REPORT_TEMPERATURES = src_filter=+ -INCH_MODE_SUPPORT = src_filter=+ -TEMPERATURE_UNITS_SUPPORT = src_filter=+ -NEED_HEX_PRINT = src_filter=+ -NEED_LSF = src_filter=+ -NOZZLE_PARK_FEATURE = src_filter=+ + -NOZZLE_CLEAN_FEATURE = src_filter=+ + -DELTA = src_filter=+ + -BEZIER_CURVE_SUPPORT = src_filter=+ + -PRINTCOUNTER = src_filter=+ -HAS_BED_PROBE = src_filter=+ + + + -IS_SCARA = src_filter=+ -HAS_SERVOS = src_filter=+ + -MORGAN_SCARA = src_filter=+ -HAS_MICROSTEPS = src_filter=+ -(ESP3D_)?WIFISUPPORT = AsyncTCP, ESP Async WebServer - ESP3DLib=https://github.com/luc-github/ESP3DLib/archive/master.zip - arduinoWebSockets=links2004/WebSockets@2.3.4 - luc-github/ESP32SSDP@^1.1.1 - lib_ignore=ESPAsyncTCP +MESH_BED_LEVELING = src_filter=+ + +AUTO_BED_LEVELING_UBL = src_filter=+ + +UBL_HILBERT_CURVE = src_filter=+ +BACKLASH_COMPENSATION = src_filter=+ +BARICUDA = src_filter=+ + +BINARY_FILE_TRANSFER = src_filter=+ + +BLTOUCH = src_filter=+ +CANCEL_OBJECTS = src_filter=+ + +CASE_LIGHT_ENABLE = src_filter=+ + +EXTERNAL_CLOSED_LOOP_CONTROLLER = src_filter=+ + +USE_CONTROLLER_FAN = src_filter=+ +HAS_MOTOR_CURRENT_DAC = src_filter=+ +DIRECT_STEPPING = src_filter=+ + +EMERGENCY_PARSER = src_filter=+ - +I2C_POSITION_ENCODERS = src_filter=+ +IIC_BL24CXX_EEPROM = src_filter=+ +HAS_SPI_FLASH = src_filter=+ +HAS_ETHERNET = src_filter=+ + +HAS_FANMUX = src_filter=+ +FILAMENT_WIDTH_SENSOR = src_filter=+ + +FWRETRACT = src_filter=+ + +HOST_ACTION_COMMANDS = src_filter=+ +HOTEND_IDLE_TIMEOUT = src_filter=+ +JOYSTICK = src_filter=+ +BLINKM = src_filter=+ +HAS_COLOR_LEDS = src_filter=+ + +PCA9533 = src_filter=+ +PCA9632 = src_filter=+ +PRINTER_EVENT_LEDS = src_filter=+ +TEMP_STAT_LEDS = src_filter=+ +MAX7219_DEBUG = src_filter=+ + +HAS_MEATPACK = src_filter=+ +MIXING_EXTRUDER = src_filter=+ + +HAS_PRUSA_MMU1 = src_filter=+ +HAS_PRUSA_MMU2 = src_filter=+ + +PASSWORD_FEATURE = src_filter=+ + +ADVANCED_PAUSE_FEATURE = src_filter=+ + + +AUTO_POWER_CONTROL = src_filter=+ +HAS_POWER_MONITOR = src_filter=+ + +POWER_LOSS_RECOVERY = src_filter=+ + +PROBE_TEMP_COMPENSATION = src_filter=+ + +HAS_FILAMENT_SENSOR = src_filter=+ + +(EXT|MANUAL)_SOLENOID.* = src_filter=+ + +MK2_MULTIPLEXER = src_filter=+ +HAS_CUTTER = src_filter=+ + +HAS_DRIVER_SAFE_POWER_PROTECT = src_filter=+ +EXPERIMENTAL_I2CBUS = src_filter=+ + +MECHANICAL_GANTRY_CAL.+ = src_filter=+ +Z_MULTI_ENDSTOPS = src_filter=+ +Z_STEPPER_AUTO_ALIGN = src_filter=+ + +G26_MESH_VALIDATION = src_filter=+ +ASSISTED_TRAMMING = src_filter=+ + +HAS_MESH = src_filter=+ +HAS_LEVELING = src_filter=+ + +DELTA_AUTO_CALIBRATION = src_filter=+ +CALIBRATION_GCODE = src_filter=+ +Z_MIN_PROBE_REPEATABILITY_TEST = src_filter=+ +M100_FREE_MEMORY_WATCHER = src_filter=+ +BACKLASH_GCODE = src_filter=+ +IS_KINEMATIC = src_filter=+ +HAS_EXTRA_ENDSTOPS = src_filter=+ +SKEW_CORRECTION_GCODE = src_filter=+ +DIRECT_PIN_CONTROL = src_filter=+ + +PINS_DEBUGGING = src_filter=+ +NO_VOLUMETRICS = src_filter=- +HAS_MULTI_EXTRUDER = src_filter=+ +HAS_HOTEND_OFFSET = src_filter=+ +EDITABLE_SERVO_ANGLES = src_filter=+ +PIDTEMP = src_filter=+ +PREVENT_COLD_EXTRUSION = src_filter=+ +PIDTEMPBED = src_filter=+ +HAS_USER_THERMISTORS = src_filter=+ +SD_ABORT_ON_ENDSTOP_HIT = src_filter=+ +BAUD_RATE_GCODE = src_filter=+ +HAS_SMART_EFF_MOD = src_filter=+ +COOLANT_CONTROL = src_filter=+ +AIR_EVACUATION = src_filter=+ +HAS_SOFTWARE_ENDSTOPS = src_filter=+ +HAS_DUPLICATION_MODE = src_filter=+ +LIN_ADVANCE = src_filter=+ +PHOTO_GCODE = src_filter=+ +CONTROLLER_FAN_EDITABLE = src_filter=+ +GCODE_MACROS = src_filter=+ +GRADIENT_MIX = src_filter=+ +HAS_SAVED_POSITIONS = src_filter=+ + +PARK_HEAD_ON_PAUSE = src_filter=+ +FILAMENT_LOAD_UNLOAD_GCODES = src_filter=+ +CNC_WORKSPACE_PLANES = src_filter=+ +CNC_COORDINATE_SYSTEMS = src_filter=+ +HAS_M206_COMMAND = src_filter=+ +EXPECTED_PRINTER_CHECK = src_filter=+ +HOST_KEEPALIVE_FEATURE = src_filter=+ +REPETIER_GCODE_M360 = src_filter=+ +HAS_GCODE_M876 = src_filter=+ +HAS_RESUME_CONTINUE = src_filter=+ +HAS_LCD_CONTRAST = src_filter=+ +LCD_SET_PROGRESS_MANUALLY = src_filter=+ +TOUCH_SCREEN_CALIBRATION = src_filter=+ +ARC_SUPPORT = src_filter=+ +GCODE_MOTION_MODES = src_filter=+ +BABYSTEPPING = src_filter=+ + +Z_PROBE_SLED = src_filter=+ +G38_PROBE_TARGET = src_filter=+ +MAGNETIC_PARKING_EXTRUDER = src_filter=+ +SDSUPPORT = src_filter=+ + + + + + + +HAS_MEDIA_SUBCALLS = src_filter=+ +GCODE_REPEAT_MARKERS = src_filter=+ + +HAS_EXTRUDERS = src_filter=+ + +HAS_COOLER = src_filter=+ + +AUTO_REPORT_TEMPERATURES = src_filter=+ +INCH_MODE_SUPPORT = src_filter=+ +TEMPERATURE_UNITS_SUPPORT = src_filter=+ +NEED_HEX_PRINT = src_filter=+ +NEED_LSF = src_filter=+ +NOZZLE_PARK_FEATURE = src_filter=+ + +NOZZLE_CLEAN_FEATURE = src_filter=+ + +DELTA = src_filter=+ + +BEZIER_CURVE_SUPPORT = src_filter=+ + +PRINTCOUNTER = src_filter=+ +HAS_BED_PROBE = src_filter=+ + + + +IS_SCARA = src_filter=+ +HAS_SERVOS = src_filter=+ + +MORGAN_SCARA = src_filter=+ +HAS_MICROSTEPS = src_filter=+ +(ESP3D_)?WIFISUPPORT = AsyncTCP, ESP Async WebServer + ESP3DLib=https://github.com/luc-github/ESP3DLib/archive/master.zip + arduinoWebSockets=links2004/WebSockets@2.3.4 + luc-github/ESP32SSDP@^1.1.1 + lib_ignore=ESPAsyncTCP From 32bf44764483e40eddf0cd0361e3356166f70445 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Fri, 7 May 2021 00:58:41 +0000 Subject: [PATCH 02/67] [cron] Bump distribution date (2021-05-07) --- Marlin/src/inc/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index da65fcac5b..2ab6071ac1 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2021-05-06" + #define STRING_DISTRIBUTION_DATE "2021-05-07" #endif /** From be6fbc76a1ab1618421315958480f6a1d6093533 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Thu, 6 May 2021 22:39:34 -0500 Subject: [PATCH 03/67] Serial and pins debug cleanup - Rename some AVR / DUE / ESP32 serial types - Reduce two #error to one static_assert - Update AVR/DUE error messages --- Marlin/src/HAL/AVR/HAL.h | 8 +- Marlin/src/HAL/AVR/MarlinSerial.cpp | 8 +- Marlin/src/HAL/AVR/MarlinSerial.h | 16 ++-- Marlin/src/HAL/DUE/HAL.h | 11 +-- Marlin/src/HAL/DUE/MarlinSerial.cpp | 2 +- Marlin/src/HAL/DUE/MarlinSerial.h | 4 +- Marlin/src/HAL/DUE/MarlinSerialUSB.cpp | 10 +-- Marlin/src/HAL/DUE/MarlinSerialUSB.h | 12 ++- Marlin/src/HAL/ESP32/WebSocketSerial.cpp | 2 +- Marlin/src/HAL/ESP32/WebSocketSerial.h | 4 +- Marlin/src/HAL/LPC1768/MarlinSerial.cpp | 8 +- Marlin/src/HAL/SAMD51/HAL.h | 2 - Marlin/src/HAL/STM32/HAL.h | 6 +- Marlin/src/HAL/STM32F1/HAL.h | 32 ++----- Marlin/src/HAL/TEENSY31_32/HAL.h | 2 + Marlin/src/core/serial.h | 14 ++- Marlin/src/inc/Conditionals_post.h | 1 - Marlin/src/pins/pinsDebug.h | 105 ++++------------------- 18 files changed, 76 insertions(+), 171 deletions(-) diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h index 7adf1aad49..64e4f764dc 100644 --- a/Marlin/src/HAL/AVR/HAL.h +++ b/Marlin/src/HAL/AVR/HAL.h @@ -93,13 +93,13 @@ typedef int8_t pin_t; #define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0) #else #if !WITHIN(SERIAL_PORT, -1, 3) - #error "SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." + #error "SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." #endif #define MYSERIAL1 customizedSerial1 #ifdef SERIAL_PORT_2 #if !WITHIN(SERIAL_PORT_2, -1, 3) - #error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB." + #error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial." #endif #define MYSERIAL2 customizedSerial2 #endif @@ -107,14 +107,14 @@ typedef int8_t pin_t; #ifdef MMU2_SERIAL_PORT #if !WITHIN(MMU2_SERIAL_PORT, -1, 3) - #error "MMU2_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." + #error "MMU2_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." #endif #define MMU2_SERIAL mmuSerial #endif #ifdef LCD_SERIAL_PORT #if !WITHIN(LCD_SERIAL_PORT, -1, 3) - #error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." + #error "LCD_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." #endif #define LCD_SERIAL lcdSerial #if HAS_DGUS_LCD diff --git a/Marlin/src/HAL/AVR/MarlinSerial.cpp b/Marlin/src/HAL/AVR/MarlinSerial.cpp index 8f82b7b418..82cdcfbe83 100644 --- a/Marlin/src/HAL/AVR/MarlinSerial.cpp +++ b/Marlin/src/HAL/AVR/MarlinSerial.cpp @@ -567,7 +567,7 @@ ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _UDRE_vect)) { // Because of the template definition above, it's required to instantiate the template to have all methods generated template class MarlinSerial< MarlinSerialCfg >; -MSerialT customizedSerial1(MSerialT::HasEmergencyParser); +MSerialT1 customizedSerial1(MSerialT1::HasEmergencyParser); #ifdef SERIAL_PORT_2 @@ -596,7 +596,7 @@ MSerialT customizedSerial1(MSerialT::HasEmergencyParser); } template class MarlinSerial< MMU2SerialCfg >; - MSerialT3 mmuSerial(MSerialT3::HasEmergencyParser); + MSerialMMU2 mmuSerial(MSerialMMU2::HasEmergencyParser); #endif // MMU2_SERIAL_PORT @@ -611,7 +611,7 @@ MSerialT customizedSerial1(MSerialT::HasEmergencyParser); } template class MarlinSerial< LCDSerialCfg >; - MSerialT4 lcdSerial(MSerialT4::HasEmergencyParser); + MSerialLCD lcdSerial(MSerialLCD::HasEmergencyParser); #if HAS_DGUS_LCD template @@ -630,7 +630,7 @@ MSerialT customizedSerial1(MSerialT::HasEmergencyParser); // For AT90USB targets use the UART for BT interfacing #if defined(USBCON) && ENABLED(BLUETOOTH) - MSerialT5 bluetoothSerial(false); + MSerialBT bluetoothSerial(false); #endif #endif // __AVR__ diff --git a/Marlin/src/HAL/AVR/MarlinSerial.h b/Marlin/src/HAL/AVR/MarlinSerial.h index 355ecd41fd..26066d7208 100644 --- a/Marlin/src/HAL/AVR/MarlinSerial.h +++ b/Marlin/src/HAL/AVR/MarlinSerial.h @@ -238,8 +238,8 @@ static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED); }; - typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT; - extern MSerialT customizedSerial1; + typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT1; + extern MSerialT1 customizedSerial1; #ifdef SERIAL_PORT_2 typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT2; @@ -262,8 +262,8 @@ static constexpr bool RX_OVERRUNS = false; }; - typedef Serial1Class< MarlinSerial< MMU2SerialCfg > > MSerialT3; - extern MSerialT3 mmuSerial; + typedef Serial1Class< MarlinSerial< MMU2SerialCfg > > MSerialMMU2; + extern MSerialMMU2 mmuSerial; #endif #ifdef LCD_SERIAL_PORT @@ -281,12 +281,12 @@ static constexpr bool RX_OVERRUNS = BOTH(HAS_DGUS_LCD, SERIAL_STATS_RX_BUFFER_OVERRUNS); }; - typedef Serial1Class< MarlinSerial< LCDSerialCfg > > MSerialT4; - extern MSerialT4 lcdSerial; + typedef Serial1Class< MarlinSerial< LCDSerialCfg > > MSerialLCD; + extern MSerialLCD lcdSerial; #endif // Use the UART for Bluetooth in AT90USB configurations #if defined(USBCON) && ENABLED(BLUETOOTH) - typedef Serial1Class MSerialT5; - extern MSerialT5 bluetoothSerial; + typedef Serial1Class MSerialBT; + extern MSerialBT bluetoothSerial; #endif diff --git a/Marlin/src/HAL/DUE/HAL.h b/Marlin/src/HAL/DUE/HAL.h index 1bc3bf7410..2fb927948c 100644 --- a/Marlin/src/HAL/DUE/HAL.h +++ b/Marlin/src/HAL/DUE/HAL.h @@ -50,13 +50,12 @@ extern DefaultSerial4 MSerial3; #define _MSERIAL(X) MSerial##X #define MSERIAL(X) _MSERIAL(X) -// Define MYSERIAL1/2 before MarlinSerial includes! #if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER) #define MYSERIAL1 customizedSerial1 #elif WITHIN(SERIAL_PORT, 0, 3) #define MYSERIAL1 MSERIAL(SERIAL_PORT) #else - #error "The required SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." + #error "The required SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." #endif #ifdef SERIAL_PORT_2 @@ -65,7 +64,7 @@ extern DefaultSerial4 MSerial3; #elif WITHIN(SERIAL_PORT_2, 0, 3) #define MYSERIAL2 MSERIAL(SERIAL_PORT_2) #else - #error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB." + #error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial." #endif #endif @@ -78,12 +77,10 @@ extern DefaultSerial4 MSerial3; #endif #ifdef LCD_SERIAL_PORT - #if LCD_SERIAL_PORT == -1 - #define LCD_SERIAL lcdSerial - #elif WITHIN(LCD_SERIAL_PORT, 0, 3) + #if WITHIN(LCD_SERIAL_PORT, 0, 3) #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) #else - #error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." + #error "LCD_SERIAL_PORT must be from 0 to 3." #endif #endif diff --git a/Marlin/src/HAL/DUE/MarlinSerial.cpp b/Marlin/src/HAL/DUE/MarlinSerial.cpp index 5b333fbeb5..29d9ab0797 100644 --- a/Marlin/src/HAL/DUE/MarlinSerial.cpp +++ b/Marlin/src/HAL/DUE/MarlinSerial.cpp @@ -478,7 +478,7 @@ void MarlinSerial::flushTX() { // If not using the USB port as serial port #if defined(SERIAL_PORT) && SERIAL_PORT >= 0 template class MarlinSerial< MarlinSerialCfg >; - MSerialT customizedSerial1(MarlinSerialCfg::EMERGENCYPARSER); + MSerialT1 customizedSerial1(MarlinSerialCfg::EMERGENCYPARSER); #endif #if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0 diff --git a/Marlin/src/HAL/DUE/MarlinSerial.h b/Marlin/src/HAL/DUE/MarlinSerial.h index 0fb15cf8ad..496e54c151 100644 --- a/Marlin/src/HAL/DUE/MarlinSerial.h +++ b/Marlin/src/HAL/DUE/MarlinSerial.h @@ -141,8 +141,8 @@ struct MarlinSerialCfg { }; #if defined(SERIAL_PORT) && SERIAL_PORT >= 0 - typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT; - extern MSerialT customizedSerial1; + typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT1; + extern MSerialT1 customizedSerial1; #endif #if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0 diff --git a/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp b/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp index fca677c798..fb5f013255 100644 --- a/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp +++ b/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp @@ -19,13 +19,13 @@ * along with this program. If not, see . * */ +#ifdef ARDUINO_ARCH_SAM /** * MarlinSerial_Due.cpp - Hardware serial library for Arduino DUE * Copyright (c) 2017 Eduardo José Tagle. All right reserved * Based on MarlinSerial for AVR, copyright (c) 2006 Nicholas Zambetti. All right reserved. */ -#ifdef ARDUINO_ARCH_SAM #include "../../inc/MarlinConfig.h" @@ -65,7 +65,7 @@ int MarlinSerialUSB::peek() { pending_char = udi_cdc_getc(); - TERN_(EMERGENCY_PARSER, emergency_parser.update(static_cast(this)->emergency_state, (char)pending_char)); + TERN_(EMERGENCY_PARSER, emergency_parser.update(static_cast(this)->emergency_state, (char)pending_char)); return pending_char; } @@ -87,7 +87,7 @@ int MarlinSerialUSB::read() { int c = udi_cdc_getc(); - TERN_(EMERGENCY_PARSER, emergency_parser.update(static_cast(this)->emergency_state, (char)c)); + TERN_(EMERGENCY_PARSER, emergency_parser.update(static_cast(this)->emergency_state, (char)c)); return c; } @@ -129,10 +129,10 @@ size_t MarlinSerialUSB::write(const uint8_t c) { // Preinstantiate #if SERIAL_PORT == -1 - MSerialT customizedSerial1(TERN0(EMERGENCY_PARSER, true)); + MSerialT1 customizedSerial1(TERN0(EMERGENCY_PARSER, true)); #endif #if SERIAL_PORT_2 == -1 - MSerialT customizedSerial2(TERN0(EMERGENCY_PARSER, true)); + MSerialT2 customizedSerial2(TERN0(EMERGENCY_PARSER, true)); #endif #endif // HAS_USB_SERIAL diff --git a/Marlin/src/HAL/DUE/MarlinSerialUSB.h b/Marlin/src/HAL/DUE/MarlinSerialUSB.h index 4c299dced5..d19fc60eb6 100644 --- a/Marlin/src/HAL/DUE/MarlinSerialUSB.h +++ b/Marlin/src/HAL/DUE/MarlinSerialUSB.h @@ -27,11 +27,9 @@ */ #include "../../inc/MarlinConfig.h" -#if HAS_USB_SERIAL - -#include #include "../../core/serial_hook.h" +#include struct MarlinSerialUSB { void begin(const long); @@ -50,14 +48,14 @@ struct MarlinSerialUSB { FORCE_INLINE int rxMaxEnqueued() { return 0; } #endif }; -typedef Serial1Class MSerialT; #if SERIAL_PORT == -1 - extern MSerialT customizedSerial1; + typedef Serial1Class MSerialT1; + extern MSerialT1 customizedSerial1; #endif #if SERIAL_PORT_2 == -1 - extern MSerialT customizedSerial2; + typedef Serial1Class MSerialT2; + extern MSerialT2 customizedSerial2; #endif -#endif // HAS_USB_SERIAL diff --git a/Marlin/src/HAL/ESP32/WebSocketSerial.cpp b/Marlin/src/HAL/ESP32/WebSocketSerial.cpp index 96769f261f..eb5b9d6039 100644 --- a/Marlin/src/HAL/ESP32/WebSocketSerial.cpp +++ b/Marlin/src/HAL/ESP32/WebSocketSerial.cpp @@ -29,7 +29,7 @@ #include "wifi.h" #include -MSerialT webSocketSerial(false); +MSerialWebSocketT webSocketSerial(false); AsyncWebSocket ws("/ws"); // TODO Move inside the class. // RingBuffer impl diff --git a/Marlin/src/HAL/ESP32/WebSocketSerial.h b/Marlin/src/HAL/ESP32/WebSocketSerial.h index 574f7b10f0..6b3e419d10 100644 --- a/Marlin/src/HAL/ESP32/WebSocketSerial.h +++ b/Marlin/src/HAL/ESP32/WebSocketSerial.h @@ -81,5 +81,5 @@ public: #endif }; -typedef Serial1Class MSerialT; -extern MSerialT webSocketSerial; +typedef Serial1Class MSerialWebSocketT; +extern MSerialWebSocketT webSocketSerial; diff --git a/Marlin/src/HAL/LPC1768/MarlinSerial.cpp b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp index f35328d22f..f2aecf54a0 100644 --- a/Marlin/src/HAL/LPC1768/MarlinSerial.cpp +++ b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp @@ -26,9 +26,9 @@ #include "../../inc/MarlinConfig.h" #if USING_HW_SERIAL0 - MarlinSerial _MSerial(LPC_UART0); - MSerialT MSerial0(true, _MSerial); - extern "C" void UART0_IRQHandler() { _MSerial.IRQHandler(); } + MarlinSerial _MSerial0(LPC_UART0); + MSerialT MSerial0(true, _MSerial0); + extern "C" void UART0_IRQHandler() { _MSerial0.IRQHandler(); } #endif #if USING_HW_SERIAL1 MarlinSerial _MSerial1((LPC_UART_TypeDef *) LPC_UART1); @@ -52,7 +52,7 @@ // Need to figure out which serial port we are and react in consequence (Marlin does not have CONTAINER_OF macro) if (false) {} #if USING_HW_SERIAL0 - else if (this == &_MSerial) emergency_parser.update(MSerial0.emergency_state, c); + else if (this == &_MSerial0) emergency_parser.update(MSerial0.emergency_state, c); #endif #if USING_HW_SERIAL1 else if (this == &_MSerial1) emergency_parser.update(MSerial1.emergency_state, c); diff --git a/Marlin/src/HAL/SAMD51/HAL.h b/Marlin/src/HAL/SAMD51/HAL.h index 85ac5dd00c..491c3f82c4 100644 --- a/Marlin/src/HAL/SAMD51/HAL.h +++ b/Marlin/src/HAL/SAMD51/HAL.h @@ -43,8 +43,6 @@ extern DefaultSerial4 MSerial3; extern DefaultSerial5 MSerial4; - // MYSERIAL1 required before MarlinSerial includes! - #define __MSERIAL(X) MSerial##X #define _MSERIAL(X) __MSERIAL(X) #define MSERIAL(X) _MSERIAL(INCREMENT(X)) diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h index 469d08e435..8ac9e6bd80 100644 --- a/Marlin/src/HAL/STM32/HAL.h +++ b/Marlin/src/HAL/STM32/HAL.h @@ -37,6 +37,9 @@ #include +// +// Serial Ports +// #ifdef USBCON #include #include "../../core/serial_hook.h" @@ -44,9 +47,6 @@ extern DefaultSerial1 MSerial0; #endif -// ------------------------ -// Defines -// ------------------------ #define _MSERIAL(X) MSerial##X #define MSERIAL(X) _MSERIAL(X) diff --git a/Marlin/src/HAL/STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h index af4d27f43e..8b306f48fa 100644 --- a/Marlin/src/HAL/STM32F1/HAL.h +++ b/Marlin/src/HAL/STM32F1/HAL.h @@ -36,7 +36,6 @@ #include "fastio.h" #include "watchdog.h" - #include #include @@ -63,11 +62,10 @@ #ifdef SERIAL_USB typedef ForwardSerial1Class< USBSerial > DefaultSerial1; extern DefaultSerial1 MSerial0; - - #if !HAS_SD_HOST_DRIVE - #define UsbSerial MSerial0 - #else + #if HAS_SD_HOST_DRIVE #define UsbSerial MarlinCompositeSerial + #else + #define UsbSerial MSerial0 #endif #endif @@ -86,11 +84,7 @@ #define MYSERIAL1 MSERIAL(SERIAL_PORT) #else #define MYSERIAL1 MSERIAL(1) // dummy port - #if NUM_UARTS == 5 - #error "SERIAL_PORT must be from 1 to 5. You can also use -1 if the board supports Native USB." - #else - #error "SERIAL_PORT must be from 1 to 3. You can also use -1 if the board supports Native USB." - #endif + static_assert(false, "SERIAL_PORT must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.") #endif #ifdef SERIAL_PORT_2 @@ -100,11 +94,7 @@ #define MYSERIAL2 MSERIAL(SERIAL_PORT_2) #else #define MYSERIAL2 MSERIAL(1) // dummy port - #if NUM_UARTS == 5 - #error "SERIAL_PORT_2 must be from 1 to 5. You can also use -1 if the board supports Native USB." - #else - #error "SERIAL_PORT_2 must be from 1 to 3. You can also use -1 if the board supports Native USB." - #endif + static_assert(false, "SERIAL_PORT_2 must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.") #endif #endif @@ -115,11 +105,7 @@ #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT) #else #define MMU2_SERIAL MSERIAL(1) // dummy port - #if NUM_UARTS == 5 - #error "MMU2_SERIAL_PORT must be from 1 to 5. You can also use -1 if the board supports Native USB." - #else - #error "MMU2_SERIAL_PORT must be from 1 to 3. You can also use -1 if the board supports Native USB." - #endif + static_assert(false, "MMU2_SERIAL_PORT must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.") #endif #endif @@ -130,11 +116,7 @@ #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) #else #define LCD_SERIAL MSERIAL(1) // dummy port - #if NUM_UARTS == 5 - #error "LCD_SERIAL_PORT must be from 1 to 5. You can also use -1 if the board supports Native USB." - #else - #error "LCD_SERIAL_PORT must be from 1 to 3. You can also use -1 if the board supports Native USB." - #endif + static_assert(false, "LCD_SERIAL_PORT must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.") #endif #if HAS_DGUS_LCD #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite() diff --git a/Marlin/src/HAL/TEENSY31_32/HAL.h b/Marlin/src/HAL/TEENSY31_32/HAL.h index 52904465be..8baa7936f5 100644 --- a/Marlin/src/HAL/TEENSY31_32/HAL.h +++ b/Marlin/src/HAL/TEENSY31_32/HAL.h @@ -68,6 +68,8 @@ extern USBSerialType USBSerial; #elif WITHIN(SERIAL_PORT, 0, 3) DECLARE_SERIAL(SERIAL_PORT); #define MYSERIAL1 MSERIAL(SERIAL_PORT) +#else + #error "The required SERIAL_PORT must be from 0 to 3, or -1 for Native USB." #endif #define HAL_SERVO_LIB libServo diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h index 842a2b02c5..2628b3d2e5 100644 --- a/Marlin/src/core/serial.h +++ b/Marlin/src/core/serial.h @@ -87,16 +87,12 @@ extern uint8_t marlin_debug_flags; // If we have a catchall, use that directly #ifdef SERIAL_CATCHALL #define _SERIAL_LEAF_2 SERIAL_CATCHALL + #elif HAS_ETHERNET + typedef ConditionalSerial SerialLeafT2; // We need to create an instance here + extern SerialLeafT2 msSerial2; + #define _SERIAL_LEAF_2 msSerial2 #else - #if HAS_ETHERNET - // We need to create an instance here - typedef ConditionalSerial SerialLeafT2; - extern SerialLeafT2 msSerial2; - #define _SERIAL_LEAF_2 msSerial2 - #else - // Don't create a useless instance here, directly use the existing instance - #define _SERIAL_LEAF_2 MYSERIAL2 - #endif + #define _SERIAL_LEAF_2 MYSERIAL2 // Don't create a useless instance here, directly use the existing instance #endif // Hook Meatpack if it's enabled on the second leaf diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 67a6ce86e1..d5bb3e68db 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -1949,7 +1949,6 @@ #undef _SERIAL_ID #undef _TMC_UART_IS #undef TMC_UART_IS -#undef CONF_SERIAL_IS #undef ANY_SERIAL_IS // diff --git a/Marlin/src/pins/pinsDebug.h b/Marlin/src/pins/pinsDebug.h index 72e31b7b25..0c55232969 100644 --- a/Marlin/src/pins/pinsDebug.h +++ b/Marlin/src/pins/pinsDebug.h @@ -45,34 +45,22 @@ // manually add pins that have names that are macros which don't play well with these macros #if ANY(AVR_ATmega2560_FAMILY, AVR_ATmega1284_FAMILY, ARDUINO_ARCH_SAM, TARGET_LPC1768) - #if SERIAL_PORT == 0 + #if CONF_SERIAL_IS(0) static const char RXD_NAME_0[] PROGMEM = { "RXD0" }; static const char TXD_NAME_0[] PROGMEM = { "TXD0" }; - #elif SERIAL_PORT == 1 + #endif + #if CONF_SERIAL_IS(1) static const char RXD_NAME_1[] PROGMEM = { "RXD1" }; static const char TXD_NAME_1[] PROGMEM = { "TXD1" }; - #elif SERIAL_PORT == 2 + #endif + #if CONF_SERIAL_IS(2) static const char RXD_NAME_2[] PROGMEM = { "RXD2" }; static const char TXD_NAME_2[] PROGMEM = { "TXD2" }; - #elif SERIAL_PORT == 3 + #endif + #if CONF_SERIAL_IS(3) static const char RXD_NAME_3[] PROGMEM = { "RXD3" }; static const char TXD_NAME_3[] PROGMEM = { "TXD3" }; #endif - #ifdef SERIAL_PORT_2 - #if SERIAL_PORT_2 == 0 - static const char RXD_NAME_0[] PROGMEM = { "RXD0" }; - static const char TXD_NAME_0[] PROGMEM = { "TXD0" }; - #elif SERIAL_PORT_2 == 1 - static const char RXD_NAME_1[] PROGMEM = { "RXD1" }; - static const char TXD_NAME_1[] PROGMEM = { "TXD1" }; - #elif SERIAL_PORT_2 == 2 - static const char RXD_NAME_2[] PROGMEM = { "RXD2" }; - static const char TXD_NAME_2[] PROGMEM = { "TXD2" }; - #elif SERIAL_PORT_2 == 3 - static const char RXD_NAME_3[] PROGMEM = { "RXD3" }; - static const char TXD_NAME_3[] PROGMEM = { "TXD3" }; - #endif - #endif #endif ///////////////////////////////////////////////////////////////////////////// @@ -103,12 +91,11 @@ const PinInfo pin_array[] PROGMEM = { * Each entry takes up 6 bytes in FLASH: * 2 byte pointer to location of the name string * 2 bytes containing the pin number - * analog pin numbers were convereted to digital when the array was created + * analog pin numbers were converted to digital when the array was created * 2 bytes containing the digital/analog bool flag */ - // manually add pins ... - #if SERIAL_PORT == 0 + #if CONF_SERIAL_IS(0) #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_0, 0, true }, { TXD_NAME_0, 1, true }, @@ -119,7 +106,9 @@ const PinInfo pin_array[] PROGMEM = { { RXD_NAME_0, 3, true }, { TXD_NAME_0, 2, true }, #endif - #elif SERIAL_PORT == 1 + #endif + + #if CONF_SERIAL_IS(1) #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_1, 19, true }, { TXD_NAME_1, 18, true }, @@ -135,7 +124,9 @@ const PinInfo pin_array[] PROGMEM = { { TXD_NAME_1, 15, true }, #endif #endif - #elif SERIAL_PORT == 2 + #endif + + #if CONF_SERIAL_IS(2) #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_2, 17, true }, { TXD_NAME_2, 16, true }, @@ -148,7 +139,9 @@ const PinInfo pin_array[] PROGMEM = { { TXD_NAME_2, 10, true }, #endif #endif - #elif SERIAL_PORT == 3 + #endif + + #if CONF_SERIAL_IS(3) #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) { RXD_NAME_3, 15, true }, { TXD_NAME_3, 14, true }, @@ -166,68 +159,8 @@ const PinInfo pin_array[] PROGMEM = { #endif #endif - #ifdef SERIAL_PORT_2 - #if SERIAL_PORT_2 == 0 - #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) - { RXD_NAME_0, 0, true }, - { TXD_NAME_0, 1, true }, - #elif AVR_ATmega1284_FAMILY - { RXD_NAME_0, 8, true }, - { TXD_NAME_0, 9, true }, - #elif defined(TARGET_LPC1768) // TX P0_02 RX P0_03 - { RXD_NAME_0, 3, true }, - { TXD_NAME_0, 2, true }, - #endif - #elif SERIAL_PORT_2 == 1 - #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) - { RXD_NAME_1, 19, true }, - { TXD_NAME_1, 18, true }, - #elif AVR_ATmega1284_FAMILY - { RXD_NAME_1, 10, true }, - { TXD_NAME_1, 11, true }, - #elif defined(TARGET_LPC1768) - #ifdef LPC_PINCFG_UART1_P2_00 // TX P2_00 RX P2_01 - { RXD_NAME_1, 0x41, true }, - { TXD_NAME_1, 0x40, true }, - #else // TX P0_15 RX P0_16 - { RXD_NAME_1, 16, true }, - { TXD_NAME_1, 15, true }, - #endif - #endif - #elif SERIAL_PORT_2 == 2 - #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) - { RXD_NAME_2, 17, true }, - { TXD_NAME_2, 16, true }, - #elif defined(TARGET_LPC1768) - #ifdef LPC_PINCFG_UART2_P2_08 // TX P2_08 RX P2_09 - { RXD_NAME_2, 0x49, true }, - { TXD_NAME_2, 0x48, true }, - #else // TX P0_10 RX P0_11 - { RXD_NAME_2, 11, true }, - { TXD_NAME_2, 10, true }, - #endif - #endif - #elif SERIAL_PORT_2 == 3 - #if EITHER(AVR_ATmega2560_FAMILY, ARDUINO_ARCH_SAM) - { RXD_NAME_3, 15, true }, - { TXD_NAME_3, 14, true }, - #elif defined(TARGET_LPC1768) - #ifdef LPC_PINCFG_UART3_P0_25 // TX P0_25 RX P0_26 - { RXD_NAME_3, 0x1A, true }, - { TXD_NAME_3, 0x19, true }, - #elif defined(LPC_PINCFG_UART3_P4_28) // TX P4_28 RX P4_29 - { RXD_NAME_3, 0x9D, true }, - { TXD_NAME_3, 0x9C, true }, - #else // TX P0_00 RX P0_01 - { RXD_NAME_3, 1, true }, - { TXD_NAME_3, 0, true }, - #endif - #endif - #endif - #endif - #include "pinsDebug_list.h" - #line 231 + #line 164 }; From 02405add76e722701ab49434549e7d8bf5690162 Mon Sep 17 00:00:00 2001 From: ellensp Date: Fri, 7 May 2021 17:31:45 +1200 Subject: [PATCH 04/67] Support a third serial port (#21784) --- Marlin/Configuration.h | 7 ++ Marlin/src/HAL/AVR/HAL.h | 7 ++ Marlin/src/HAL/AVR/MarlinSerial.cpp | 16 ++++ Marlin/src/HAL/AVR/MarlinSerial.h | 5 ++ Marlin/src/HAL/DUE/HAL.h | 10 +++ Marlin/src/HAL/DUE/MarlinSerial.cpp | 5 ++ Marlin/src/HAL/DUE/MarlinSerial.h | 5 ++ Marlin/src/HAL/DUE/MarlinSerialUSB.cpp | 3 + Marlin/src/HAL/DUE/MarlinSerialUSB.h | 4 + Marlin/src/HAL/LPC1768/HAL.h | 10 +++ Marlin/src/HAL/STM32/HAL.h | 10 +++ Marlin/src/HAL/STM32F1/HAL.h | 11 +++ Marlin/src/MarlinCore.cpp | 5 ++ Marlin/src/core/serial.cpp | 12 ++- Marlin/src/core/serial.h | 21 ++++- Marlin/src/core/serial_hook.h | 109 +++++++++++++++---------- Marlin/src/inc/Conditionals_LCD.h | 8 +- Marlin/src/inc/Conditionals_post.h | 1 + Marlin/src/inc/SanityCheck.h | 8 ++ buildroot/tests/LPC1768 | 2 +- 20 files changed, 212 insertions(+), 47 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index d6a7456ccf..e1f9a4be70 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -111,6 +111,13 @@ */ //#define SERIAL_PORT_2 -1 +/** + * Select a third serial port on the board to use for communication with the host. + * Currently only supported for AVR, DUE, LPC1768/9 and STM32/STM32F1 + * :[-1, 0, 1, 2, 3, 4, 5, 6, 7] + */ +//#define SERIAL_PORT_3 1 + /** * This setting determines the communication speed of the printer. * diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h index 64e4f764dc..e24b923ef0 100644 --- a/Marlin/src/HAL/AVR/HAL.h +++ b/Marlin/src/HAL/AVR/HAL.h @@ -103,6 +103,13 @@ typedef int8_t pin_t; #endif #define MYSERIAL2 customizedSerial2 #endif + + #ifdef SERIAL_PORT_3 + #if !WITHIN(SERIAL_PORT_3, -1, 3) + #error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial." + #endif + #define MYSERIAL3 customizedSerial3 + #endif #endif #ifdef MMU2_SERIAL_PORT diff --git a/Marlin/src/HAL/AVR/MarlinSerial.cpp b/Marlin/src/HAL/AVR/MarlinSerial.cpp index 82cdcfbe83..cd8bf5e690 100644 --- a/Marlin/src/HAL/AVR/MarlinSerial.cpp +++ b/Marlin/src/HAL/AVR/MarlinSerial.cpp @@ -585,6 +585,22 @@ MSerialT1 customizedSerial1(MSerialT1::HasEmergencyParser); #endif // SERIAL_PORT_2 +#ifdef SERIAL_PORT_3 + + // Hookup ISR handlers + ISR(SERIAL_REGNAME(USART, SERIAL_PORT_3, _RX_vect)) { + MarlinSerial>::store_rxd_char(); + } + + ISR(SERIAL_REGNAME(USART, SERIAL_PORT_3, _UDRE_vect)) { + MarlinSerial>::_tx_udr_empty_irq(); + } + + template class MarlinSerial< MarlinSerialCfg >; + MSerialT3 customizedSerial3(MSerialT3::HasEmergencyParser); + +#endif // SERIAL_PORT_3 + #ifdef MMU2_SERIAL_PORT ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _RX_vect)) { diff --git a/Marlin/src/HAL/AVR/MarlinSerial.h b/Marlin/src/HAL/AVR/MarlinSerial.h index 26066d7208..0565c7b9db 100644 --- a/Marlin/src/HAL/AVR/MarlinSerial.h +++ b/Marlin/src/HAL/AVR/MarlinSerial.h @@ -246,6 +246,11 @@ extern MSerialT2 customizedSerial2; #endif + #ifdef SERIAL_PORT_3 + typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT3; + extern MSerialT3 customizedSerial3; + #endif + #endif // !USBCON #ifdef MMU2_SERIAL_PORT diff --git a/Marlin/src/HAL/DUE/HAL.h b/Marlin/src/HAL/DUE/HAL.h index 2fb927948c..92e26bcf43 100644 --- a/Marlin/src/HAL/DUE/HAL.h +++ b/Marlin/src/HAL/DUE/HAL.h @@ -68,6 +68,16 @@ extern DefaultSerial4 MSerial3; #endif #endif +#ifdef SERIAL_PORT_3 + #if SERIAL_PORT_3 == -1 || ENABLED(EMERGENCY_PARSER) + #define MYSERIAL3 customizedSerial3 + #elif WITHIN(SERIAL_PORT_3, 0, 3) + #define MYSERIAL3 MSERIAL(SERIAL_PORT_3) + #else + #error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial." + #endif +#endif + #ifdef MMU2_SERIAL_PORT #if WITHIN(MMU2_SERIAL_PORT, 0, 3) #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT) diff --git a/Marlin/src/HAL/DUE/MarlinSerial.cpp b/Marlin/src/HAL/DUE/MarlinSerial.cpp index 29d9ab0797..fe62ff5607 100644 --- a/Marlin/src/HAL/DUE/MarlinSerial.cpp +++ b/Marlin/src/HAL/DUE/MarlinSerial.cpp @@ -486,4 +486,9 @@ void MarlinSerial::flushTX() { MSerialT2 customizedSerial2(MarlinSerialCfg::EMERGENCYPARSER); #endif +#if defined(SERIAL_PORT_3) && SERIAL_PORT_3 >= 0 + template class MarlinSerial< MarlinSerialCfg >; + MSerialT3 customizedSerial3(MarlinSerialCfg::EMERGENCYPARSER); +#endif + #endif // ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/DUE/MarlinSerial.h b/Marlin/src/HAL/DUE/MarlinSerial.h index 496e54c151..4a62e2834f 100644 --- a/Marlin/src/HAL/DUE/MarlinSerial.h +++ b/Marlin/src/HAL/DUE/MarlinSerial.h @@ -149,3 +149,8 @@ struct MarlinSerialCfg { typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT2; extern MSerialT2 customizedSerial2; #endif + +#if defined(SERIAL_PORT_3) && SERIAL_PORT_3 >= 0 + typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT3; + extern MSerialT3 customizedSerial3; +#endif diff --git a/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp b/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp index fb5f013255..67c597da80 100644 --- a/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp +++ b/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp @@ -134,6 +134,9 @@ size_t MarlinSerialUSB::write(const uint8_t c) { #if SERIAL_PORT_2 == -1 MSerialT2 customizedSerial2(TERN0(EMERGENCY_PARSER, true)); #endif +#if SERIAL_PORT_3 == -1 + MSerialT3 customizedSerial3(TERN0(EMERGENCY_PARSER, true)); +#endif #endif // HAS_USB_SERIAL #endif // ARDUINO_ARCH_SAM diff --git a/Marlin/src/HAL/DUE/MarlinSerialUSB.h b/Marlin/src/HAL/DUE/MarlinSerialUSB.h index d19fc60eb6..6da1ef8c08 100644 --- a/Marlin/src/HAL/DUE/MarlinSerialUSB.h +++ b/Marlin/src/HAL/DUE/MarlinSerialUSB.h @@ -59,3 +59,7 @@ struct MarlinSerialUSB { extern MSerialT2 customizedSerial2; #endif +#if SERIAL_PORT_3 == -1 + typedef Serial1Class MSerialT3; + extern MSerialT3 customizedSerial3; +#endif diff --git a/Marlin/src/HAL/LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h index bcfa6c412f..85e8933920 100644 --- a/Marlin/src/HAL/LPC1768/HAL.h +++ b/Marlin/src/HAL/LPC1768/HAL.h @@ -84,6 +84,16 @@ extern DefaultSerial1 USBSerial; #endif #endif +#ifdef SERIAL_PORT_3 + #if SERIAL_PORT_3 == -1 + #define MYSERIAL3 USBSerial + #elif WITHIN(SERIAL_PORT_3, 0, 3) + #define MYSERIAL3 MSERIAL(SERIAL_PORT_3) + #else + #error "SERIAL_PORT_3 must be from 0 to 3. You can also use -1 if the board supports Native USB." + #endif +#endif + #ifdef MMU2_SERIAL_PORT #if MMU2_SERIAL_PORT == -1 #define MMU2_SERIAL USBSerial diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h index 8ac9e6bd80..2441c46eab 100644 --- a/Marlin/src/HAL/STM32/HAL.h +++ b/Marlin/src/HAL/STM32/HAL.h @@ -68,6 +68,16 @@ #endif #endif +#ifdef SERIAL_PORT_3 + #if SERIAL_PORT_3 == -1 + #define MYSERIAL3 MSerial0 + #elif WITHIN(SERIAL_PORT_3, 1, 6) + #define MYSERIAL3 MSERIAL(SERIAL_PORT_3) + #else + #error "SERIAL_PORT_3 must be from 1 to 6. You can also use -1 if the board supports Native USB." + #endif +#endif + #ifdef MMU2_SERIAL_PORT #if MMU2_SERIAL_PORT == -1 #define MMU2_SERIAL MSerial0 diff --git a/Marlin/src/HAL/STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h index 8b306f48fa..b3d8dc9d0b 100644 --- a/Marlin/src/HAL/STM32F1/HAL.h +++ b/Marlin/src/HAL/STM32F1/HAL.h @@ -98,6 +98,17 @@ #endif #endif +#ifdef SERIAL_PORT_3 + #if SERIAL_PORT_3 == -1 + #define MYSERIAL3 UsbSerial + #elif WITHIN(SERIAL_PORT_3, 1, NUM_UARTS) + #define MYSERIAL3 MSERIAL(SERIAL_PORT_3) + #else + #define MYSERIAL3 MSERIAL(1) // dummy port + static_assert(false, "SERIAL_PORT_3 must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.") + #endif +#endif + #ifdef MMU2_SERIAL_PORT #if MMU2_SERIAL_PORT == -1 #define MMU2_SERIAL UsbSerial diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 053256b743..2794b80695 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -1075,6 +1075,11 @@ void setup() { MYSERIAL2.begin(BAUDRATE); serial_connect_timeout = millis() + 1000UL; while (!MYSERIAL2.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } + #ifdef SERIAL_PORT_3 + MYSERIAL3.begin(BAUDRATE); + serial_connect_timeout = millis() + 1000UL; + while (!MYSERIAL3.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } + #endif #endif SERIAL_ECHOLNPGM("start"); diff --git a/Marlin/src/core/serial.cpp b/Marlin/src/core/serial.cpp index 8af367c801..28442594ce 100644 --- a/Marlin/src/core/serial.cpp +++ b/Marlin/src/core/serial.cpp @@ -44,6 +44,9 @@ PGMSTR(SP_X_LBL, " X:"); PGMSTR(SP_Y_LBL, " Y:"); PGMSTR(SP_Z_LBL, " Z:"); PGMST #if ENABLED(MEATPACK_ON_SERIAL_PORT_2) SerialLeafT2 mpSerial2(false, _SERIAL_LEAF_2); #endif +#if ENABLED(MEATPACK_ON_SERIAL_PORT_3) + SerialLeafT3 mpSerial3(false, _SERIAL_LEAF_3); +#endif // Step 2: For multiserial, handle the second serial port as well #if HAS_MULTI_SERIAL @@ -52,7 +55,14 @@ PGMSTR(SP_X_LBL, " X:"); PGMSTR(SP_Y_LBL, " Y:"); PGMSTR(SP_Z_LBL, " Z:"); PGMST SerialLeafT2 msSerial2(ethernet.have_telnet_client, MYSERIAL2, false); #endif - SerialOutputT multiSerial(SERIAL_LEAF_1, SERIAL_LEAF_2); + #define __S_LEAF(N) ,SERIAL_LEAF_##N + #define _S_LEAF(N) __S_LEAF(N) + + SerialOutputT multiSerial( SERIAL_LEAF_1 REPEAT_S(2, INCREMENT(NUM_SERIAL), _S_LEAF) ); + + #undef __S_LEAF + #undef _S_LEAF + #endif void serialprintPGM(PGM_P str) { diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h index 2628b3d2e5..4565a7fc87 100644 --- a/Marlin/src/core/serial.h +++ b/Marlin/src/core/serial.h @@ -95,6 +95,9 @@ extern uint8_t marlin_debug_flags; #define _SERIAL_LEAF_2 MYSERIAL2 // Don't create a useless instance here, directly use the existing instance #endif + // Nothing complicated here + #define _SERIAL_LEAF_3 MYSERIAL3 + // Hook Meatpack if it's enabled on the second leaf #if ENABLED(MEATPACK_ON_SERIAL_PORT_2) typedef MeatpackSerial SerialLeafT2; @@ -104,7 +107,23 @@ extern uint8_t marlin_debug_flags; #define SERIAL_LEAF_2 _SERIAL_LEAF_2 #endif - typedef MultiSerial SerialOutputT; + // Hook Meatpack if it's enabled on the third leaf + #if ENABLED(MEATPACK_ON_SERIAL_PORT_3) + typedef MeatpackSerial SerialLeafT3; + extern SerialLeafT3 mpSerial3; + #define SERIAL_LEAF_3 mpSerial3 + #else + #define SERIAL_LEAF_3 _SERIAL_LEAF_3 + #endif + + #define __S_MULTI(N) decltype(SERIAL_LEAF_##N), + #define _S_MULTI(N) __S_MULTI(N) + + typedef MultiSerial< REPEAT_S(1, INCREMENT(NUM_SERIAL), _S_MULTI) 0> SerialOutputT; + + #undef __S_MULTI + #undef _S_MULTI + extern SerialOutputT multiSerial; #define SERIAL_IMPL multiSerial #else diff --git a/Marlin/src/core/serial_hook.h b/Marlin/src/core/serial_hook.h index 45cdcd35ed..d56cb55a66 100644 --- a/Marlin/src/core/serial_hook.h +++ b/Marlin/src/core/serial_hook.h @@ -195,54 +195,71 @@ struct RuntimeSerial : public SerialBase< RuntimeSerial >, public Seria RuntimeSerial(const bool e, Args... args) : BaseClassT(e), SerialT(args...), writeHook(0), eofHook(0), userPointer(0) {} }; -// A class that duplicates its output conditionally to 2 serial interfaces -template -struct MultiSerial : public SerialBase< MultiSerial > { - typedef SerialBase< MultiSerial > BaseClassT; +#define _S_CLASS(N) class Serial##N##T, +#define _S_NAME(N) Serial##N##T, + +template < REPEAT(NUM_SERIAL, _S_CLASS) const uint8_t offset=0, const uint8_t step=1 > +struct MultiSerial : public SerialBase< MultiSerial< REPEAT(NUM_SERIAL, _S_NAME) offset, step > > { + typedef SerialBase< MultiSerial< REPEAT(NUM_SERIAL, _S_NAME) offset, step > > BaseClassT; + + #undef _S_CLASS + #undef _S_NAME SerialMask portMask; - Serial0T & serial0; - Serial1T & serial1; - static constexpr uint8_t Usage = ((1 << step) - 1); // A bit mask containing as many bits as step - static constexpr uint8_t FirstOutput = (Usage << offset); - static constexpr uint8_t SecondOutput = (Usage << (offset + step)); - static constexpr uint8_t Both = FirstOutput | SecondOutput; + #define _S_DECLARE(N) Serial##N##T & serial##N; + REPEAT(NUM_SERIAL, _S_DECLARE); + #undef _S_DECLARE + + static constexpr uint8_t Usage = _BV(step) - 1; // A bit mask containing 'step' bits + + #define _OUT_PORT(N) (Usage << (offset + (step * N))), + static constexpr uint8_t output[] = { REPEAT(NUM_SERIAL, _OUT_PORT) }; + #undef _OUT_PORT + + #define _OUT_MASK(N) | output[N] + static constexpr uint8_t ALL = 0 REPEAT(NUM_SERIAL, _OUT_MASK); + #undef _OUT_MASK NO_INLINE void write(uint8_t c) { - if (portMask.enabled(FirstOutput)) serial0.write(c); - if (portMask.enabled(SecondOutput)) serial1.write(c); + #define _S_WRITE(N) if (portMask.enabled(output[N])) serial##N.write(c); + REPEAT(NUM_SERIAL, _S_WRITE); + #undef _S_WRITE } NO_INLINE void msgDone() { - if (portMask.enabled(FirstOutput)) serial0.msgDone(); - if (portMask.enabled(SecondOutput)) serial1.msgDone(); + #define _S_DONE(N) if (portMask.enabled(output[N])) serial##N.msgDone(); + REPEAT(NUM_SERIAL, _S_DONE); + #undef _S_DONE } int available(serial_index_t index) { - if (index.within(0 + offset, step + offset - 1)) - return serial0.available(index); - else if (index.within(step + offset, 2 * step + offset - 1)) - return serial1.available(index); + uint8_t pos = offset; + #define _S_AVAILABLE(N) if (index.within(pos, pos + step - 1)) return serial##N.available(index); else pos += step; + REPEAT(NUM_SERIAL, _S_AVAILABLE); + #undef _S_AVAILABLE return false; } int read(serial_index_t index) { - if (index.within(0 + offset, step + offset - 1)) - return serial0.read(index); - else if (index.within(step + offset, 2 * step + offset - 1)) - return serial1.read(index); + uint8_t pos = offset; + #define _S_READ(N) if (index.within(pos, pos + step - 1)) return serial##N.read(index); else pos += step; + REPEAT(NUM_SERIAL, _S_READ); + #undef _S_READ return -1; } void begin(const long br) { - if (portMask.enabled(FirstOutput)) serial0.begin(br); - if (portMask.enabled(SecondOutput)) serial1.begin(br); + #define _S_BEGIN(N) if (portMask.enabled(output[N])) serial##N.begin(br); + REPEAT(NUM_SERIAL, _S_BEGIN); + #undef _S_BEGIN } void end() { - if (portMask.enabled(FirstOutput)) serial0.end(); - if (portMask.enabled(SecondOutput)) serial1.end(); + #define _S_END(N) if (portMask.enabled(output[N])) serial##N.end(); + REPEAT(NUM_SERIAL, _S_END); + #undef _S_END } bool connected() { bool ret = true; - if (portMask.enabled(FirstOutput)) ret = CALL_IF_EXISTS(bool, &serial0, connected); - if (portMask.enabled(SecondOutput)) ret = ret && CALL_IF_EXISTS(bool, &serial1, connected); + #define _S_CONNECTED(N) if (portMask.enabled(output[N]) && !CALL_IF_EXISTS(bool, &serial##N, connected)) ret = false; + REPEAT(NUM_SERIAL, _S_CONNECTED); + #undef _S_CONNECTED return ret; } @@ -250,27 +267,32 @@ struct MultiSerial : public SerialBase< MultiSerial= 3 + #define Serial3Class ConditionalSerial + #endif #endif diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index d767000501..afec2c2b44 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -955,15 +955,19 @@ // Serial Port Info // #ifdef SERIAL_PORT_2 - #define NUM_SERIAL 2 #define HAS_MULTI_SERIAL 1 + #ifdef SERIAL_PORT_3 + #define NUM_SERIAL 3 + #else + #define NUM_SERIAL 2 + #endif #elif defined(SERIAL_PORT) #define NUM_SERIAL 1 #else #define NUM_SERIAL 0 #undef BAUD_RATE_GCODE #endif -#if SERIAL_PORT == -1 || SERIAL_PORT_2 == -1 +#if SERIAL_PORT == -1 || SERIAL_PORT_2 == -1 || SERIAL_PORT_3 == -1 #define HAS_USB_SERIAL 1 #endif #if SERIAL_PORT_2 == -2 diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index d5bb3e68db..c237e6edd9 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -1859,6 +1859,7 @@ // Flag the indexed hardware serial ports in use #define CONF_SERIAL_IS(N) ( (defined(SERIAL_PORT) && SERIAL_PORT == N) \ || (defined(SERIAL_PORT_2) && SERIAL_PORT_2 == N) \ + || (defined(SERIAL_PORT_3) && SERIAL_PORT_3 == N) \ || (defined(MMU2_SERIAL_PORT) && MMU2_SERIAL_PORT == N) \ || (defined(LCD_SERIAL_PORT) && LCD_SERIAL_PORT == N) ) diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 6959e07f12..2cc90e0e8b 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -607,6 +607,14 @@ #error "SERIAL_PORT must be defined." #elif defined(SERIAL_PORT_2) && SERIAL_PORT_2 == SERIAL_PORT #error "SERIAL_PORT_2 cannot be the same as SERIAL_PORT." +#elif defined(SERIAL_PORT_3) + #ifndef SERIAL_PORT_2 + #error "Use SERIAL_PORT_2 before using SERIAL_PORT_3" + #elif SERIAL_PORT_3 == SERIAL_PORT + #error "SERIAL_PORT_3 cannot be the same as SERIAL_PORT." + #elif SERIAL_PORT_3 == SERIAL_PORT_2 + #error "SERIAL_PORT_3 cannot be the same as SERIAL_PORT_2." + #endif #endif #if !(defined(__AVR__) && defined(USBCON)) #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024 diff --git a/buildroot/tests/LPC1768 b/buildroot/tests/LPC1768 index 6b9f6aaac3..92fda54483 100755 --- a/buildroot/tests/LPC1768 +++ b/buildroot/tests/LPC1768 @@ -14,7 +14,7 @@ set -e #exec_test $1 $2 "Default Configuration" "$3" restore_configs -opt_set MOTHERBOARD BOARD_RAMPS_14_RE_ARM_EFB NEOPIXEL_PIN P1_16 +opt_set MOTHERBOARD BOARD_RAMPS_14_RE_ARM_EFB NEOPIXEL_PIN P1_16 SERIAL_PORT_3 3 opt_enable VIKI2 SDSUPPORT SDCARD_READONLY SERIAL_PORT_2 NEOPIXEL_LED exec_test $1 $2 "ReARM EFB VIKI2, SDSUPPORT, 2 Serial ports (USB CDC + UART0), NeoPixel" "$3" From 4428affc20eb5ab99a4c0855919f26e5dad1fa1f Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 May 2021 00:55:39 -0500 Subject: [PATCH 05/67] Let M421 C select any point Fixing #21147 --- Marlin/src/feature/bedlevel/ubl/ubl.h | 2 +- Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp | 4 ++-- Marlin/src/gcode/bedlevel/ubl/M421.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.h b/Marlin/src/feature/bedlevel/ubl/ubl.h index 0a758a57e9..562f15f74b 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.h +++ b/Marlin/src/feature/bedlevel/ubl/ubl.h @@ -32,7 +32,7 @@ #define UBL_OK false #define UBL_ERR true -enum MeshPointType : char { INVALID, REAL, SET_IN_BITMAP }; +enum MeshPointType : char { INVALID, REAL, SET_IN_BITMAP, CLOSEST }; // External references diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp index 361f3f1285..6130123f7a 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp @@ -1282,7 +1282,7 @@ mesh_index_pair unified_bed_leveling::find_furthest_invalid_mesh_point() { static bool test_func(uint8_t i, uint8_t j, void *data) { find_closest_t *d = (find_closest_t*)data; - if ( (d->type == (isnan(ubl.z_values[i][j]) ? INVALID : REAL)) + if ( d->type == CLOSEST || d->type == (isnan(ubl.z_values[i][j]) ? INVALID : REAL) || (d->type == SET_IN_BITMAP && !d->done_flags->marked(i, j)) ) { // Found a Mesh Point of the specified type! @@ -1326,7 +1326,7 @@ mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const Mesh float best_so_far = 99999.99f; GRID_LOOP(i, j) { - if ( (type == (isnan(z_values[i][j]) ? INVALID : REAL)) + if ( type == CLOSEST || type == (isnan(z_values[i][j]) ? INVALID : REAL) || (type == SET_IN_BITMAP && !done_flags->marked(i, j)) ) { // Found a Mesh Point of the specified type! diff --git a/Marlin/src/gcode/bedlevel/ubl/M421.cpp b/Marlin/src/gcode/bedlevel/ubl/M421.cpp index 600c1fc8ba..45c203aaca 100644 --- a/Marlin/src/gcode/bedlevel/ubl/M421.cpp +++ b/Marlin/src/gcode/bedlevel/ubl/M421.cpp @@ -54,7 +54,7 @@ void GcodeSuite::M421() { hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q'); - if (hasC) ij = ubl.find_closest_mesh_point_of_type(REAL, current_position); + if (hasC) ij = ubl.find_closest_mesh_point_of_type(CLOSEST, current_position); if (int(hasC) + int(hasI && hasJ) != 1 || !(hasZ || hasQ || hasN)) SERIAL_ERROR_MSG(STR_ERR_M421_PARAMETERS); From 8fd4bfc0e7fbc27cbd218a68435ca2f20726f111 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Sat, 8 May 2021 00:57:21 +0000 Subject: [PATCH 06/67] [cron] Bump distribution date (2021-05-08) --- Marlin/src/inc/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 2ab6071ac1..572722416f 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2021-05-07" + #define STRING_DISTRIBUTION_DATE "2021-05-08" #endif /** From 9f7177c67dc7979ae69c0068ae9a1ece9bc7102c Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 May 2021 22:36:36 -0500 Subject: [PATCH 07/67] Misc Power Loss cleanup --- Marlin/src/feature/powerloss.cpp | 27 ++++++++++++--------------- Marlin/src/feature/powerloss.h | 5 +++++ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 10488af709..3736cac453 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -66,9 +66,6 @@ PrintJobRecovery recovery; #ifndef POWER_LOSS_PURGE_LEN #define POWER_LOSS_PURGE_LEN 0 #endif -#ifndef POWER_LOSS_ZRAISE - #define POWER_LOSS_ZRAISE 2 // Move on loss with backup power, or on resume without it -#endif #if DISABLED(BACKUP_POWER_SUPPLY) #undef POWER_LOSS_RETRACT_LEN // No retract at outage without backup power @@ -256,7 +253,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=0*/ // Raise the Z axis now if (zraise) { char cmd[20], str_1[16]; - sprintf_P(cmd, PSTR("G0 Z%s"), dtostrf(zraise, 1, 3, str_1)); + sprintf_P(cmd, PSTR("G0Z%s"), dtostrf(zraise, 1, 3, str_1)); gcode.process_subcommands_now(cmd); } #else @@ -348,7 +345,7 @@ void PrintJobRecovery::resume() { const celsius_t bt = info.target_temperature_bed; if (bt) { // Restore the bed temperature - sprintf_P(cmd, PSTR("M190 S%i"), bt); + sprintf_P(cmd, PSTR("M190S%i"), bt); gcode.process_subcommands_now(cmd); } #endif @@ -359,10 +356,10 @@ void PrintJobRecovery::resume() { const celsius_t et = info.target_temperature[e]; if (et) { #if HAS_MULTI_HOTEND - sprintf_P(cmd, PSTR("T%i S"), e); + sprintf_P(cmd, PSTR("T%iS"), e); gcode.process_subcommands_now(cmd); #endif - sprintf_P(cmd, PSTR("M109 S%i"), et); + sprintf_P(cmd, PSTR("M109S%i"), et); gcode.process_subcommands_now(cmd); } } @@ -370,7 +367,7 @@ void PrintJobRecovery::resume() { // // Home the axes that can safely be homed, and - // establish the current position as best we can + // establish the current position as best we can. // #if Z_HOME_DIR > 0 @@ -380,7 +377,7 @@ void PrintJobRecovery::resume() { "G28R0" // Home all axes (no raise) )); - #else // "G92.9 E0 ..." + #else // If a Z raise occurred at outage restore Z, otherwise raise Z now sprintf_P(cmd, PSTR("G92.9 E0 " TERN(BACKUP_POWER_SUPPLY, "Z%s", "Z0\nG1Z%s")), dtostrf(info.zraise, 1, 3, str_1)); @@ -475,7 +472,7 @@ void PrintJobRecovery::resume() { // Un-retract if there was a retract at outage #if ENABLED(BACKUP_POWER_SUPPLY) && POWER_LOSS_RETRACT_LEN > 0 - gcode.process_subcommands_now_P(PSTR("G1 E" STRINGIFY(POWER_LOSS_RETRACT_LEN) " F3000")); + gcode.process_subcommands_now_P(PSTR("G1E" STRINGIFY(POWER_LOSS_RETRACT_LEN) "F3000")); #endif // Additional purge on resume if configured @@ -488,8 +485,8 @@ void PrintJobRecovery::resume() { gcode.process_subcommands_now_P(PSTR("G12")); #endif - // Move back to the saved XY - sprintf_P(cmd, PSTR("G1 X%s Y%s F3000"), + // Move back over to the saved XY + sprintf_P(cmd, PSTR("G1X%sY%sF3000"), dtostrf(info.current_position.x, 1, 3, str_1), dtostrf(info.current_position.y, 1, 3, str_2) ); @@ -506,11 +503,11 @@ void PrintJobRecovery::resume() { gcode.process_subcommands_now(cmd); // Restore the feedrate - sprintf_P(cmd, PSTR("G1 F%d"), info.feedrate); + sprintf_P(cmd, PSTR("G1F%d"), info.feedrate); gcode.process_subcommands_now(cmd); // Restore E position with G92.9 - sprintf_P(cmd, PSTR("G92.9 E%s"), dtostrf(info.current_position.e, 1, 3, str_1)); + sprintf_P(cmd, PSTR("G92.9E%s"), dtostrf(info.current_position.e, 1, 3, str_1)); gcode.process_subcommands_now(cmd); TERN_(GCODE_REPEAT_MARKERS, repeat = info.stored_repeat); @@ -535,7 +532,7 @@ void PrintJobRecovery::resume() { char *fn = info.sd_filename; sprintf_P(cmd, M23_STR, fn); gcode.process_subcommands_now(cmd); - sprintf_P(cmd, PSTR("M24 S%ld T%ld"), resume_sdpos, info.print_job_elapsed); + sprintf_P(cmd, PSTR("M24S%ldT%ld"), resume_sdpos, info.print_job_elapsed); gcode.process_subcommands_now(cmd); TERN_(DEBUG_POWER_LOSS_RECOVERY, marlin_debug_flags = old_flags); diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index 0777466cc1..03e467432c 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -42,6 +42,10 @@ #define POWER_LOSS_STATE HIGH #endif +#ifndef POWER_LOSS_ZRAISE + #define POWER_LOSS_ZRAISE 2 +#endif + //#define DEBUG_POWER_LOSS_RECOVERY //#define SAVE_EACH_CMD_MODE //#define SAVE_INFO_INTERVAL_MS 0 @@ -52,6 +56,7 @@ typedef struct { // Machine state xyze_pos_t current_position; uint16_t feedrate; + float zraise; // Repeat information From 1292ff76b34c15cf6bc78259985440e13b5cb1f8 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 May 2021 22:37:31 -0500 Subject: [PATCH 08/67] Debounce for Power-Loss pin --- Marlin/src/feature/powerloss.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index 03e467432c..df3ae222a2 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -186,8 +186,14 @@ class PrintJobRecovery { #if PIN_EXISTS(POWER_LOSS) static inline void outage() { - if (enabled && READ(POWER_LOSS_PIN) == POWER_LOSS_STATE) - _outage(); + static constexpr uint8_t OUTAGE_THRESHOLD = 3; + static uint8_t outage_counter = 0; + if (enabled && READ(POWER_LOSS_PIN) == POWER_LOSS_STATE) { + outage_counter++; + if (outage_counter >= OUTAGE_THRESHOLD) _outage(); + } + else + outage_counter = 0; } #endif From 206d495ba4235a79db158fe6687e301bb055623f Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 May 2021 22:39:34 -0500 Subject: [PATCH 09/67] Misc. code cleanup --- Marlin/src/MarlinCore.cpp | 4 ++-- Marlin/src/gcode/queue.cpp | 10 +++------- Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp | 4 ++-- Marlin/src/lcd/extui/mks_ui/draw_ui.cpp | 4 +--- Marlin/src/lcd/extui/mks_ui/wifi_module.cpp | 12 ++++-------- 5 files changed, 12 insertions(+), 22 deletions(-) diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 2794b80695..78a881a1d8 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -390,8 +390,8 @@ void startOrResumeJob() { } inline void finishSDPrinting() { - if (queue.enqueue_one_P(PSTR("M1001"))) { - marlin_state = MF_RUNNING; + if (queue.enqueue_one_P(PSTR("M1001"))) { // Keep trying until it gets queued + marlin_state = MF_RUNNING; // Signal to stop trying TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine()); TERN_(DGUS_LCD_UI_MKS, ScreenHandler.SDPrintingFinished()); } diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index 319ebe8a17..47b7d1febb 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -501,13 +501,9 @@ void GCodeQueue::get_serial_commands() { char* gpos = strchr(command, 'G'); if (gpos) { switch (strtol(gpos + 1, nullptr, 10)) { - case 0: case 1: - #if ENABLED(ARC_SUPPORT) - case 2: case 3: - #endif - #if ENABLED(BEZIER_CURVE_SUPPORT) - case 5: - #endif + case 0 ... 1: + TERN_(ARC_SUPPORT, case 2 ... 3:) + TERN_(BEZIER_CURVE_SUPPORT, case 5:) PORT_REDIRECT(SERIAL_PORTMASK(p)); // Reply to the serial port that sent the command SERIAL_ECHOLNPGM(STR_ERR_STOPPED); LCD_MESSAGEPGM(MSG_STOPPED); diff --git a/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp b/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp index d31a1dcacd..c502d0ae27 100644 --- a/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp +++ b/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp @@ -1477,7 +1477,7 @@ void DGUSScreenHandler::DGUS_ExtrudeLoadInit(void) { void DGUSScreenHandler::DGUS_RunoutInit(void) { #if PIN_EXISTS(MT_DET_1) - pinMode(MT_DET_1_PIN, INPUT_PULLUP); + SET_INPUT_PULLUP(MT_DET_1_PIN); #endif runout_mks.de_count = 0; runout_mks.de_times = 10; @@ -1496,7 +1496,7 @@ void DGUSScreenHandler::DGUS_Runout_Idle(void) { GotoScreen(MKSLCD_SCREEN_PAUSE); sendinfoscreen(PSTR("NOTICE"), nullptr, PSTR("Please change filament!"), nullptr, true, true, true, true); - // SetupConfirmAction(nullptr); + //SetupConfirmAction(nullptr); GotoScreen(DGUSLCD_SCREEN_POPUP); break; diff --git a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp index c5ae77dd61..4134759b75 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp @@ -645,9 +645,7 @@ char *creat_title_text() { gcode_preview_over = false; card.closefile(); - char *cur_name; - - cur_name = strrchr(list_file.file_name[sel_id], '/'); + char *cur_name = strrchr(list_file.file_name[sel_id], '/'); SdFile file; SdFile *curDir; diff --git a/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp b/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp index 897137d013..1e3262be3b 100644 --- a/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp +++ b/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp @@ -1789,18 +1789,14 @@ void get_wifi_commands() { char* command = wifi_line_buffer; while (*command == ' ') command++; // skip any leading spaces - // Movement commands alert when stopped - if (IsStopped()) { + // Movement commands alert when stopped + if (IsStopped()) { char* gpos = strchr(command, 'G'); if (gpos) { switch (strtol(gpos + 1, nullptr, 10)) { case 0 ... 1: - #if ENABLED(ARC_SUPPORT) - case 2 ... 3: - #endif - #if ENABLED(BEZIER_CURVE_SUPPORT) - case 5: - #endif + TERN_(ARC_SUPPORT, case 2 ... 3:) + TERN_(BEZIER_CURVE_SUPPORT, case 5:) SERIAL_ECHOLNPGM(STR_ERR_STOPPED); LCD_MESSAGEPGM(MSG_STOPPED); break; From a03811f4e8bcc794c02108ec8a33edc071221187 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 May 2021 22:54:06 -0500 Subject: [PATCH 10/67] Update MF states --- Marlin/src/MarlinCore.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Marlin/src/MarlinCore.h b/Marlin/src/MarlinCore.h index d43d46bbd8..d016151c2d 100644 --- a/Marlin/src/MarlinCore.h +++ b/Marlin/src/MarlinCore.h @@ -56,18 +56,18 @@ void minkill(const bool steppers_off=false); // Global State of the firmware enum MarlinState : uint8_t { - MF_INITIALIZING = 0, - MF_RUNNING = _BV(0), - MF_PAUSED = _BV(1), - MF_WAITING = _BV(2), - MF_STOPPED = _BV(3), - MF_SD_COMPLETE = _BV(4), - MF_KILLED = _BV(7) + MF_INITIALIZING = 0, + MF_STOPPED, + MF_KILLED, + MF_RUNNING, + MF_SD_COMPLETE, + MF_PAUSED, + MF_WAITING, }; extern MarlinState marlin_state; -inline bool IsRunning() { return marlin_state == MF_RUNNING; } -inline bool IsStopped() { return marlin_state != MF_RUNNING; } +inline bool IsRunning() { return marlin_state >= MF_RUNNING; } +inline bool IsStopped() { return marlin_state == MF_STOPPED; } bool printingIsActive(); bool printingIsPaused(); From f09fa69e867d1cfb18cbad720a5c1e566cb1bab4 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 8 May 2021 01:41:40 -0500 Subject: [PATCH 11/67] Add and apply REPEAT_1 macro --- Marlin/src/core/macros.h | 1 + Marlin/src/core/serial.h | 2 +- Marlin/src/feature/runout.h | 2 +- Marlin/src/lcd/dogm/status_screen_DOGM.cpp | 6 ++++-- Marlin/src/lcd/marlinui.cpp | 4 ++-- Marlin/src/module/endstops.cpp | 2 +- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h index 6092dc4a59..b026af1187 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -581,6 +581,7 @@ // Repeat a macro passing S...N-1. #define REPEAT_S(S,N,OP) EVAL(_REPEAT(S,SUB##S(N),OP)) #define REPEAT(N,OP) REPEAT_S(0,N,OP) +#define REPEAT_1(N,OP) REPEAT_S(1,INCREMENT(N),OP) // Repeat a macro passing 0...N-1 plus additional arguments. #define REPEAT2_S(S,N,OP,V...) EVAL(_REPEAT2(S,SUB##S(N),OP,V)) diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h index 4565a7fc87..5406bb3a7d 100644 --- a/Marlin/src/core/serial.h +++ b/Marlin/src/core/serial.h @@ -119,7 +119,7 @@ extern uint8_t marlin_debug_flags; #define __S_MULTI(N) decltype(SERIAL_LEAF_##N), #define _S_MULTI(N) __S_MULTI(N) - typedef MultiSerial< REPEAT_S(1, INCREMENT(NUM_SERIAL), _S_MULTI) 0> SerialOutputT; + typedef MultiSerial< REPEAT_1(NUM_SERIAL, _S_MULTI) 0> SerialOutputT; #undef __S_MULTI #undef _S_MULTI diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index 15bf607550..93eb59c2a5 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -207,7 +207,7 @@ class FilamentSensorBase { // Return a bitmask of runout pin states static inline uint8_t poll_runout_pins() { #define _OR_RUNOUT(N) | (READ(FIL_RUNOUT##N##_PIN) ? _BV((N) - 1) : 0) - return (0 REPEAT_S(1, INCREMENT(NUM_RUNOUT_SENSORS), _OR_RUNOUT)); + return (0 REPEAT_1(NUM_RUNOUT_SENSORS, _OR_RUNOUT)); #undef _OR_RUNOUT } diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp index 68b75900ef..681e8da01d 100644 --- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp +++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp @@ -243,9 +243,11 @@ FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, co #endif #if STATUS_HOTEND_BITMAPS > 1 - static const unsigned char* const status_hotend_gfx[STATUS_HOTEND_BITMAPS] PROGMEM = ARRAY_N(STATUS_HOTEND_BITMAPS, OFF_BMP(1), OFF_BMP(2), OFF_BMP(3), OFF_BMP(4), OFF_BMP(5), OFF_BMP(6)); + #define _OFF_BMP(N) OFF_BMP(N), + #define _ON_BMP(N) ON_BMP(N), + static const unsigned char* const status_hotend_gfx[STATUS_HOTEND_BITMAPS] PROGMEM = { REPEAT_1(STATUS_HOTEND_BITMAPS, _OFF_BMP) }; #if ANIM_HOTEND - static const unsigned char* const status_hotend_on_gfx[STATUS_HOTEND_BITMAPS] PROGMEM = ARRAY_N(STATUS_HOTEND_BITMAPS, ON_BMP(1), ON_BMP(2), ON_BMP(3), ON_BMP(4), ON_BMP(5), ON_BMP(6)); + static const unsigned char* const status_hotend_on_gfx[STATUS_HOTEND_BITMAPS] PROGMEM = { REPEAT_1(STATUS_HOTEND_BITMAPS, _ON_BMP) }; #define HOTEND_BITMAP(N,S) (unsigned char*)pgm_read_ptr((S) ? &status_hotend_on_gfx[(N) % (STATUS_HOTEND_BITMAPS)] : &status_hotend_gfx[(N) % (STATUS_HOTEND_BITMAPS)]) #else #define HOTEND_BITMAP(N,S) (unsigned char*)pgm_read_ptr(&status_hotend_gfx[(N) % (STATUS_HOTEND_BITMAPS)]) diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index 1b517f7d21..f83d129b2f 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -114,8 +114,8 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; PGM_P MarlinUI::get_preheat_label(const uint8_t m) { #define _PDEF(N) static PGMSTR(preheat_##N##_label, PREHEAT_##N##_LABEL); #define _PLBL(N) preheat_##N##_label, - REPEAT_S(1, INCREMENT(PREHEAT_COUNT), _PDEF); - static PGM_P const preheat_labels[PREHEAT_COUNT] PROGMEM = { REPEAT_S(1, INCREMENT(PREHEAT_COUNT), _PLBL) }; + REPEAT_1(PREHEAT_COUNT, _PDEF); + static PGM_P const preheat_labels[PREHEAT_COUNT] PROGMEM = { REPEAT_1(PREHEAT_COUNT, _PLBL) }; return (PGM_P)pgm_read_ptr(&preheat_labels[m]); } #endif diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index e11c4605e4..14c5f13367 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -475,7 +475,7 @@ void _O2 Endstops::report_states() { uint8_t state; switch (i) { default: continue; - REPEAT_S(1, INCREMENT(NUM_RUNOUT_SENSORS), _CASE_RUNOUT) + REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_RUNOUT) } SERIAL_ECHOPGM(STR_FILAMENT_RUNOUT_SENSOR); if (i > 1) SERIAL_CHAR(' ', '0' + i); From 01741576ebea06faa4ec98623a28eab19251f111 Mon Sep 17 00:00:00 2001 From: charlespick Date: Fri, 7 May 2021 23:44:34 -0700 Subject: [PATCH 12/67] Active MMU slot indicator (#21842) --- Marlin/src/lcd/dogm/status/hotend.h | 274 ++++++++++++++++++++- Marlin/src/lcd/dogm/status_screen_DOGM.cpp | 6 +- 2 files changed, 270 insertions(+), 10 deletions(-) diff --git a/Marlin/src/lcd/dogm/status/hotend.h b/Marlin/src/lcd/dogm/status/hotend.h index 4dddc42bee..3a6e02acb6 100644 --- a/Marlin/src/lcd/dogm/status/hotend.h +++ b/Marlin/src/lcd/dogm/status/hotend.h @@ -25,16 +25,21 @@ // lcd/dogm/status/hotend.h - Status Screen Hotends bitmaps // -#define STATUS_HOTEND1_WIDTH 16 - -#define MAX_HOTEND_BITMAPS 5 -#if HOTENDS > MAX_HOTEND_BITMAPS - #define STATUS_HOTEND_BITMAPS MAX_HOTEND_BITMAPS +#if HAS_MMU + #define STATUS_HOTEND_BITMAPS EXTRUDERS + #define MAX_HOTEND_BITMAPS 8 #else #define STATUS_HOTEND_BITMAPS HOTENDS + #define MAX_HOTEND_BITMAPS 5 +#endif +#if STATUS_HOTEND_BITMAPS > MAX_HOTEND_BITMAPS + #undef STATUS_HOTEND_BITMAPS + #define STATUS_HOTEND_BITMAPS MAX_HOTEND_BITMAPS #endif -#if HOTENDS == 1 || ENABLED(STATUS_HOTEND_NUMBERLESS) +#define STATUS_HOTEND1_WIDTH 16 + +#if STATUS_HOTEND_BITMAPS == 1 || ENABLED(STATUS_HOTEND_NUMBERLESS) const unsigned char status_hotend_a_bmp[] PROGMEM = { B00011111,B11100000, @@ -70,7 +75,7 @@ #endif -#elif HOTENDS >= 2 +#elif STATUS_HOTEND_BITMAPS > 1 #ifdef STATUS_HOTEND_ANIM @@ -483,4 +488,259 @@ #endif + #if STATUS_HOTEND_BITMAPS >= 6 + + #ifdef STATUS_HOTEND_ANIM + + const unsigned char status_hotend6_a_bmp[] PROGMEM = { + B00011111,B11100000, + B00111111,B11110000, + #if LCD_FIRST_TOOL == 0 + B00111000,B01110000, + B00111011,B11110000, + B00011000,B11100000, + B00011111,B01100000, + B00111111,B01110000, + B00111011,B01110000, + B00111100,B11110000, + #else + B00111100,B01110000, + B00111011,B11110000, + B00011011,B11100000, + B00011000,B11100000, + B00111011,B01110000, + B00111011,B01110000, + B00111100,B11110000, + #endif + B00001111,B11000000, + B00000111,B10000000, + B00000011,B00000000 + }; + + const unsigned char status_hotend6_b_bmp[] PROGMEM = { + B00011111,B11100000, + B00100000,B00010000, + #if LCD_FIRST_TOOL == 0 + B00100111,B10010000, + B00100100,B00010000, + B00010111,B00100000, + B00010000,B10100000, + B00100000,B10010000, + B00100100,B10010000, + B00110011,B00110000, + #else + B00100011,B10010000, + B00100100,B00010000, + B00010100,B00100000, + B00010111,B00100000, + B00100100,B10010000, + B00100100,B10010000, + B00110011,B00110000, + #endif + B00001000,B01000000, + B00000100,B10000000, + B00000011,B00000000 + }; + + #else + + const unsigned char status_hotend6_a_bmp[] PROGMEM = { + B00011111,B11100000, + #if LCD_FIRST_TOOL == 0 + B00111000,B01110000, + B00111011,B11110000, + B00111000,B11110000, + B00011111,B01100000, + B00011111,B01100000, + B00111011,B01110000, + B00111100,B11110000, + #else + B00111100,B01110000, + B00111011,B11110000, + B00111011,B11110000, + B00011000,B11100000, + B00011011,B01100000, + B00111011,B01110000, + B00111100,B11110000, + #endif + B00111111,B11110000, + B00001111,B11000000, + B00000111,B10000000, + B00000011,B00000000 + }; + + #endif + + #endif + + #if STATUS_HOTEND_BITMAPS >= 7 + + #ifdef STATUS_HOTEND_ANIM + + const unsigned char status_hotend7_a_bmp[] PROGMEM = { + B00011111,B11100000, + B00111111,B11110000, + #if LCD_FIRST_TOOL == 0 + B00111100,B01110000, + B00111011,B11110000, + B00011011,B11100000, + B00011000,B11100000, + B00111011,B01110000, + B00111011,B01110000, + B00111100,B11110000, + #else + B00111000,B01110000, + B00111011,B01110000, + B00011111,B01100000, + B00011110,B11100000, + B00111110,B11110000, + B00111101,B11110000, + B00111101,B11110000, + #endif + B00001111,B11000000, + B00000111,B10000000, + B00000011,B00000000 + }; + + const unsigned char status_hotend7_b_bmp[] PROGMEM = { + B00011111,B11100000, + B00100000,B00010000, + #if LCD_FIRST_TOOL == 0 + B00100011,B10010000, + B00100100,B00010000, + B00010100,B00100000, + B00010111,B00100000, + B00100100,B10010000, + B00100100,B10010000, + B00110011,B00110000, + #else + B00100111,B10010000, + B00100100,B10010000, + B00010000,B10100000, + B00010001,B00100000, + B00100001,B00010000, + B00100010,B00010000, + B00110010,B00110000, + #endif + B00001000,B01000000, + B00000100,B10000000, + B00000011,B00000000 + }; + + #else + + const unsigned char status_hotend7_a_bmp[] PROGMEM = { + B00011111,B11100000, + #if LCD_FIRST_TOOL == 0 + B00111100,B01110000, + B00111011,B11110000, + B00111011,B11110000, + B00011000,B11100000, + B00011011,B01100000, + B00111011,B01110000, + B00111100,B11110000, + #else + B00111000,B01110000, + B00111011,B01110000, + B00111111,B01110000, + B00011110,B11100000, + B00011110,B11100000, + B00111101,B11110000, + B00111101,B11110000, + #endif + B00111111,B11110000, + B00001111,B11000000, + B00000111,B10000000, + B00000011,B00000000 + }; + + #endif + + #endif + + #if STATUS_HOTEND_BITMAPS >= 8 + + #ifdef STATUS_HOTEND_ANIM + + const unsigned char status_hotend8_a_bmp[] PROGMEM = { + B00011111,B11100000, + B00111111,B11110000, + #if LCD_FIRST_TOOL == 0 + B00111000,B01110000, + B00111011,B01110000, + B00011111,B01100000, + B00011110,B11100000, + B00111110,B11110000, + B00111101,B11110000, + B00111101,B11110000, + #else + B00111100,B11110000, + B00111011,B01110000, + B00011011,B01100000, + B00011100,B11100000, + B00111011,B01110000, + B00111011,B01110000, + B00111100,B11110000, + #endif + B00001111,B11000000, + B00000111,B10000000, + B00000011,B00000000 + }; + + const unsigned char status_hotend8_b_bmp[] PROGMEM = { + B00011111,B11100000, + B00100000,B00010000, + #if LCD_FIRST_TOOL == 0 + B00100111,B10010000, + B00100100,B10010000, + B00010000,B10100000, + B00010001,B00100000, + B00100001,B00010000, + B00100010,B00010000, + B00110010,B00110000, + #else + B00100011,B00010000, + B00100100,B10010000, + B00010100,B10100000, + B00010011,B00100000, + B00100100,B10010000, + B00100100,B10010000, + B00110011,B00110000, + #endif + B00001000,B01000000, + B00000100,B10000000, + B00000011,B00000000 + }; + + #else + + const unsigned char status_hotend8_a_bmp[] PROGMEM = { + B00011111,B11100000, + #if LCD_FIRST_TOOL == 0 + B00111000,B01110000, + B00111011,B01110000, + B00111111,B01110000, + B00011110,B11100000, + B00011110,B11100000, + B00111101,B11110000, + B00111101,B11110000, + #else + B00111100,B11110000, + B00111011,B01110000, + B00111011,B01110000, + B00011100,B11100000, + B00011011,B01100000, + B00111011,B01110000, + B00111100,B11110000, + #endif + B00111111,B11110000, + B00001111,B11000000, + B00000111,B10000000, + B00000011,B00000000 + }; + + #endif + + #endif + #endif diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp index 681e8da01d..33cb9575f1 100644 --- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp +++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp @@ -274,12 +274,12 @@ FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, co #if ENABLED(STATUS_HEAT_PERCENT) if (isHeat && tall <= BAR_TALL) { const uint8_t ph = STATUS_HEATERS_HEIGHT - 1 - tall; - u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, ph, HOTEND_BITMAP(heater_id, false)); - u8g.drawBitmapP(hx, STATUS_HEATERS_Y + ph, bw, tall + 1, HOTEND_BITMAP(heater_id, true) + ph * bw); + u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, ph, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), false)); + u8g.drawBitmapP(hx, STATUS_HEATERS_Y + ph, bw, tall + 1, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), true) + ph * bw); } else #endif - u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, STATUS_HEATERS_HEIGHT, HOTEND_BITMAP(heater_id, isHeat)); + u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, STATUS_HEATERS_HEIGHT, HOTEND_BITMAP(TERN(HAS_MMU, active_extruder, heater_id), isHeat)); #endif } // PAGE_CONTAINS From 57025b75e13f05ec53b9117c890f0e5a8db8d01e Mon Sep 17 00:00:00 2001 From: Adrian DC Date: Sat, 8 May 2021 08:46:21 +0200 Subject: [PATCH 13/67] Fix E3V2 Control Menu icon/text order (#21838) Fixes #21837 --- Marlin/src/lcd/dwin/e3v2/dwin.cpp | 36 ++++++++++++++++--------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/Marlin/src/lcd/dwin/e3v2/dwin.cpp b/Marlin/src/lcd/dwin/e3v2/dwin.cpp index dc729263db..620b267bd2 100644 --- a/Marlin/src/lcd/dwin/e3v2/dwin.cpp +++ b/Marlin/src/lcd/dwin/e3v2/dwin.cpp @@ -815,8 +815,6 @@ void Draw_Control_Menu() { if (CVISI(CONTROL_CASE_ADVSET)) { DWIN_Draw_Label(CLINE(CONTROL_CASE_ADVSET), GET_TEXT_F(MSG_ADVANCED_SETTINGS)); // Advanced Settings - Draw_More_Icon(CSCROL(CONTROL_CASE_ADVSET)); - Draw_Menu_Line(CSCROL(CONTROL_CASE_ADVSET), ICON_AdvSet); } if (CVISI(CONTROL_CASE_INFO)) Item_Control_Info(CLINE(CONTROL_CASE_INFO)); @@ -825,23 +823,26 @@ void Draw_Control_Menu() { Draw_Menu_Cursor(CSCROL(select_control.now)); // Draw icons and lines - uint8_t i = 0; - #define _TEMP_ICON(N) do{ ++i; if (CVISI(i)) Draw_Menu_Line(CSCROL(i), ICON_Temperature + (N) - 1); }while(0) + #define _TEMP_ICON(N, I, M) do { \ + if (CVISI(N)) { \ + Draw_Menu_Line(CSCROL(N), I); \ + if (M) { \ + Draw_More_Icon(CSCROL(N)); \ + } \ + } \ + } while(0) - _TEMP_ICON(CONTROL_CASE_TEMP); - if (CVISI(i)) Draw_More_Icon(CSCROL(i)); - - _TEMP_ICON(CONTROL_CASE_MOVE); - Draw_More_Icon(CSCROL(i)); + _TEMP_ICON(CONTROL_CASE_TEMP, ICON_Temperature, true); + _TEMP_ICON(CONTROL_CASE_MOVE, ICON_Motion, true); #if ENABLED(EEPROM_SETTINGS) - _TEMP_ICON(CONTROL_CASE_SAVE); - _TEMP_ICON(CONTROL_CASE_LOAD); - _TEMP_ICON(CONTROL_CASE_RESET); + _TEMP_ICON(CONTROL_CASE_SAVE, ICON_WriteEEPROM, false); + _TEMP_ICON(CONTROL_CASE_LOAD, ICON_ReadEEPROM, false); + _TEMP_ICON(CONTROL_CASE_RESET, ICON_ResumeEEPROM, false); #endif - _TEMP_ICON(CONTROL_CASE_INFO); - if (CVISI(CONTROL_CASE_INFO)) Draw_More_Icon(CSCROL(i)); + _TEMP_ICON(CONTROL_CASE_ADVSET, ICON_AdvSet, true); + _TEMP_ICON(CONTROL_CASE_INFO, ICON_Info, true); } void Draw_Tune_Menu() { @@ -2653,11 +2654,12 @@ void HMI_Control() { Scroll_Menu(DWIN_SCROLL_UP); switch (index_control) { // Last menu items - case CONTROL_CASE_ADVSET: // Advance Settings > + case CONTROL_CASE_ADVSET: // Advanced Settings > Draw_Menu_Item(MROWS, ICON_AdvSet, GET_TEXT(MSG_ADVANCED_SETTINGS), true); break; case CONTROL_CASE_INFO: // Info > - Draw_Menu_Item(MROWS, ICON_Info, GET_TEXT(MSG_INFO_SCREEN), true); + Item_Control_Info(MBASE(MROWS)); + Draw_Menu_Icon(MROWS, ICON_Info); break; default: break; } @@ -2721,7 +2723,7 @@ void HMI_Control() { HMI_AudioFeedback(); break; #endif - case CONTROL_CASE_ADVSET: // Advance Settings + case CONTROL_CASE_ADVSET: // Advanced Settings checkkey = AdvSet; select_advset.reset(); Draw_AdvSet_Menu(); From b65cdbed91782c83188706a9c340de9c503cf430 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 8 May 2021 04:35:35 -0500 Subject: [PATCH 14/67] Signal SD completion later (#21840) --- Marlin/src/MarlinCore.cpp | 18 ++---- Marlin/src/MarlinCore.h | 1 + Marlin/src/feature/pause.cpp | 2 +- Marlin/src/feature/powerloss.cpp | 2 +- Marlin/src/gcode/queue.cpp | 3 +- Marlin/src/gcode/sd/M1001.cpp | 6 ++ Marlin/src/gcode/sd/M24_M25.cpp | 2 +- Marlin/src/gcode/sd/M27.cpp | 2 +- Marlin/src/gcode/sd/M32.cpp | 2 +- Marlin/src/gcode/sd/M524.cpp | 2 +- Marlin/src/lcd/HD44780/marlinui_HD44780.cpp | 4 +- Marlin/src/lcd/dogm/status_screen_DOGM.cpp | 4 +- Marlin/src/lcd/dwin/e3v2/dwin.cpp | 4 +- .../lcd/extui/dgus/mks/DGUSScreenHandler.cpp | 7 +- Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp | 10 +-- Marlin/src/lcd/extui/mks_ui/draw_ui.cpp | 8 +-- Marlin/src/lcd/extui/mks_ui/wifi_module.cpp | 20 +++--- Marlin/src/lcd/extui/mks_ui/wifi_upload.cpp | 2 +- Marlin/src/lcd/extui/ui_api.cpp | 22 ++----- Marlin/src/lcd/marlinui.cpp | 2 +- Marlin/src/module/endstops.cpp | 2 +- Marlin/src/sd/cardreader.cpp | 64 +++++++++++-------- Marlin/src/sd/cardreader.h | 60 +++++++++++------ 23 files changed, 133 insertions(+), 116 deletions(-) diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 78a881a1d8..85ee920e72 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -331,18 +331,14 @@ void disable_all_steppers() { } /** - * A Print Job exists when the timer is running or SD printing + * A Print Job exists when the timer is running or SD is printing */ -bool printJobOngoing() { - return print_job_timer.isRunning() || IS_SD_PRINTING(); -} +bool printJobOngoing() { return print_job_timer.isRunning() || IS_SD_PRINTING(); } /** - * Printing is active when the print job timer is running + * Printing is active when a job is underway but not paused */ -bool printingIsActive() { - return !did_pause_print && (print_job_timer.isRunning() || IS_SD_PRINTING()); -} +bool printingIsActive() { return !did_pause_print && printJobOngoing(); } /** * Printing is paused according to SD or host indicators @@ -367,7 +363,7 @@ void startOrResumeJob() { inline void abortSDPrinting() { IF_DISABLED(NO_SD_AUTOSTART, card.autofile_cancel()); - card.endFilePrint(TERN_(SD_RESORT, true)); + card.abortFilePrintNow(TERN_(SD_RESORT, true)); queue.clear(); quickstop_stepper(); @@ -748,7 +744,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) { // Handle Power-Loss Recovery #if ENABLED(POWER_LOSS_RECOVERY) && PIN_EXISTS(POWER_LOSS) - if (printJobOngoing()) recovery.outage(); + if (IS_SD_PRINTING()) recovery.outage(); #endif // Run StallGuard endstop checks @@ -901,7 +897,7 @@ void stop() { thermalManager.set_fans_paused(false); // Un-pause fans for safety #endif - if (IsRunning()) { + if (!IsStopped()) { SERIAL_ERROR_MSG(STR_ERR_STOPPED); LCD_MESSAGEPGM(MSG_STOPPED); safe_delay(350); // allow enough time for messages to get out before stopping diff --git a/Marlin/src/MarlinCore.h b/Marlin/src/MarlinCore.h index d016151c2d..ce1b106bfa 100644 --- a/Marlin/src/MarlinCore.h +++ b/Marlin/src/MarlinCore.h @@ -70,6 +70,7 @@ inline bool IsRunning() { return marlin_state >= MF_RUNNING; } inline bool IsStopped() { return marlin_state == MF_STOPPED; } bool printingIsActive(); +bool printJobOngoing(); bool printingIsPaused(); void startOrResumeJob(); diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 93b4a2aa81..58e0c3df0d 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -649,7 +649,7 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_ #if ENABLED(SDSUPPORT) if (did_pause_print) { --did_pause_print; - card.startFileprint(); + card.startOrResumeFilePrinting(); // Write PLR now to update the z axis value TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true)); } diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 3736cac453..9d6e0b42f5 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -137,7 +137,7 @@ void PrintJobRecovery::load() { * Set info fields that won't change */ void PrintJobRecovery::prepare() { - card.getAbsFilename(info.sd_filename); // SD filename + card.getAbsFilenameInCWD(info.sd_filename); // SD filename cmd_sdpos = 0; } diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index 47b7d1febb..c007537398 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -550,7 +550,8 @@ void GCodeQueue::get_serial_commands() { inline void GCodeQueue::get_sdcard_commands() { static uint8_t sd_input_state = PS_NORMAL; - if (!IS_SD_PRINTING()) return; + // Get commands if there are more in the file + if (!IS_SD_FETCHING()) return; int sd_count = 0; while (!ring_buffer.full() && !card.eof()) { diff --git a/Marlin/src/gcode/sd/M1001.cpp b/Marlin/src/gcode/sd/M1001.cpp index 415fbb6fa7..418e594deb 100644 --- a/Marlin/src/gcode/sd/M1001.cpp +++ b/Marlin/src/gcode/sd/M1001.cpp @@ -25,6 +25,7 @@ #if ENABLED(SDSUPPORT) #include "../gcode.h" +#include "../../module/planner.h" #include "../../module/printcounter.h" #if DISABLED(NO_SD_AUTOSTART) @@ -64,6 +65,11 @@ * M1001: Execute actions for SD print completion */ void GcodeSuite::M1001() { + planner.synchronize(); + + // SD Printing is finished when the queue reaches M1001 + card.flag.sdprinting = card.flag.sdprintdone = false; + // If there's another auto#.g file to run... if (TERN(NO_SD_AUTOSTART, false, card.autofile_check())) return; diff --git a/Marlin/src/gcode/sd/M24_M25.cpp b/Marlin/src/gcode/sd/M24_M25.cpp index 89b166f908..f46a964af0 100644 --- a/Marlin/src/gcode/sd/M24_M25.cpp +++ b/Marlin/src/gcode/sd/M24_M25.cpp @@ -70,7 +70,7 @@ void GcodeSuite::M24() { #endif if (card.isFileOpen()) { - card.startFileprint(); // SD card will now be read for commands + card.startOrResumeFilePrinting(); // SD card will now be read for commands startOrResumeJob(); // Start (or resume) the print job timer TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); } diff --git a/Marlin/src/gcode/sd/M27.cpp b/Marlin/src/gcode/sd/M27.cpp index a76070fda8..f6e48d4ae8 100644 --- a/Marlin/src/gcode/sd/M27.cpp +++ b/Marlin/src/gcode/sd/M27.cpp @@ -35,7 +35,7 @@ void GcodeSuite::M27() { if (parser.seen('C')) { SERIAL_ECHOPGM("Current file: "); - card.printFilename(); + card.printSelectedFilename(); return; } diff --git a/Marlin/src/gcode/sd/M32.cpp b/Marlin/src/gcode/sd/M32.cpp index ea893c9232..3baa552e6e 100644 --- a/Marlin/src/gcode/sd/M32.cpp +++ b/Marlin/src/gcode/sd/M32.cpp @@ -49,7 +49,7 @@ void GcodeSuite::M32() { if (parser.seenval('S')) card.setIndex(parser.value_long()); - card.startFileprint(); + card.startOrResumeFilePrinting(); // Procedure calls count as normal print time. if (!call_procedure) startOrResumeJob(); diff --git a/Marlin/src/gcode/sd/M524.cpp b/Marlin/src/gcode/sd/M524.cpp index 089d2e2f0c..e715915565 100644 --- a/Marlin/src/gcode/sd/M524.cpp +++ b/Marlin/src/gcode/sd/M524.cpp @@ -33,7 +33,7 @@ void GcodeSuite::M524() { if (IS_SD_PRINTING()) - card.flag.abort_sd_printing = true; + card.abortFilePrintSoon(); else if (card.isMounted()) card.closefile(); diff --git a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp index 2e5f967c2f..85430c18b0 100644 --- a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp @@ -755,7 +755,7 @@ inline uint8_t draw_elapsed_or_remaining_time(uint8_t timepos, const bool blink) char buffer[14]; #if ENABLED(SHOW_REMAINING_TIME) - const bool show_remain = TERN1(ROTATE_PROGRESS_DISPLAY, blink) && (printingIsActive() || marlin_state == MF_SD_COMPLETE); + const bool show_remain = TERN1(ROTATE_PROGRESS_DISPLAY, blink) && printingIsActive(); if (show_remain) { #if ENABLED(USE_M73_REMAINING_TIME) duration_t remaining = ui.get_remaining_time(); @@ -889,7 +889,7 @@ void MarlinUI::draw_status_screen() { #else // !HAS_DUAL_MIXING - const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive() || marlin_state == MF_SD_COMPLETE); + const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive()); if (show_e_total) { #if ENABLED(LCD_SHOW_E_TOTAL) diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp index 33cb9575f1..010d9a6680 100644 --- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp +++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp @@ -41,7 +41,7 @@ #include "../../gcode/parser.h" // for units (and volumetric) #if ENABLED(LCD_SHOW_E_TOTAL) - #include "../../MarlinCore.h" // for printingIsActive(), marlin_state and MF_SD_COMPLETE + #include "../../MarlinCore.h" // for printingIsActive() #endif #if ENABLED(FILAMENT_LCD_DISPLAY) @@ -464,7 +464,7 @@ void MarlinUI::draw_status_screen() { #endif #endif - const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive() || marlin_state == MF_SD_COMPLETE); + const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive()); // At the first page, generate new display values if (first_page) { diff --git a/Marlin/src/lcd/dwin/e3v2/dwin.cpp b/Marlin/src/lcd/dwin/e3v2/dwin.cpp index 620b267bd2..76118d6814 100644 --- a/Marlin/src/lcd/dwin/e3v2/dwin.cpp +++ b/Marlin/src/lcd/dwin/e3v2/dwin.cpp @@ -1891,7 +1891,7 @@ void HMI_SDCardUpdate() { else if (checkkey == PrintProcess || checkkey == Tune || printingIsActive()) { // TODO: Move card removed abort handling // to CardReader::manage_media. - card.flag.abort_sd_printing = true; + card.abortFilePrintSoon(); wait_for_heatup = wait_for_user = false; dwin_abort_flag = true; // Reset feedrate, return to Home } @@ -2311,7 +2311,7 @@ void HMI_PauseOrStop() { checkkey = Back_Main; if (HMI_flag.home_flag) planner.synchronize(); // Wait for planner moves to finish! wait_for_heatup = wait_for_user = false; // Stop waiting for heating/user - card.flag.abort_sd_printing = true; // Let the main loop handle SD abort + card.abortFilePrintSoon(); // Let the main loop handle SD abort dwin_abort_flag = true; // Reset feedrate, return to Home #ifdef ACTION_ON_CANCEL host_action_cancel(); diff --git a/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp b/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp index c502d0ae27..c0b3b60a16 100644 --- a/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp +++ b/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp @@ -289,7 +289,7 @@ void DGUSScreenHandler::ScreenChangeHook(DGUS_VP_Variable &var, void *val_ptr) { // if robin nano is printing. when it is, dgus will enter the printing // page to continue print; // - //if (print_job_timer.isRunning() || print_job_timer.isPaused()) { + //if (printJobOngoing() || printingIsPaused()) { // if (target == MKSLCD_PAUSE_SETTING_MOVE || target == MKSLCD_PAUSE_SETTING_EX // || target == MKSLCD_SCREEN_PRINT || target == MKSLCD_SCREEN_PAUSE // ) { @@ -324,7 +324,7 @@ void DGUSScreenHandler::ScreenBackChange(DGUS_VP_Variable &var, void *val_ptr) { void DGUSScreenHandler::ZoffsetConfirm(DGUS_VP_Variable &var, void *val_ptr) { settings.save(); - if (print_job_timer.isRunning()) + if (printJobOngoing()) GotoScreen(MKSLCD_SCREEN_PRINT); else if (print_job_timer.isPaused) GotoScreen(MKSLCD_SCREEN_PAUSE); @@ -1442,8 +1442,7 @@ bool DGUSScreenHandler::loop() { } #if ENABLED(DGUS_MKS_RUNOUT_SENSOR) - if (booted && (IS_SD_PRINTING() || IS_SD_PAUSED())) - DGUS_Runout_Idle(); + if (booted && printingIsActive()) DGUS_Runout_Idle(); #endif #endif // SHOW_BOOTSCREEN diff --git a/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp b/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp index ff642be294..6d207b86a7 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp @@ -91,8 +91,8 @@ static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) { cur_name = strrchr(list_file.file_name[sel_id], '/'); SdFile file, *curDir; - card.endFilePrint(); - const char * const fname = card.diveToFile(true, curDir, cur_name); + card.abortFilePrintNow(); + const char * const fname = card.diveToFile(false, curDir, cur_name); if (!fname) return; if (file.open(curDir, fname, O_READ)) { gCfgItems.curFilesize = file.fileSize(); @@ -108,7 +108,7 @@ static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) { planner.flow_percentage[1] = 100; planner.e_factor[1] = planner.flow_percentage[1] * 0.01f; #endif - card.startFileprint(); + card.startOrResumeFilePrinting(); #if ENABLED(POWER_LOSS_RECOVERY) recovery.prepare(); #endif @@ -124,8 +124,8 @@ static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) { lv_draw_ready_print(); #if ENABLED(SDSUPPORT) - uiCfg.print_state = IDLE; - card.flag.abort_sd_printing = true; + uiCfg.print_state = IDLE; + card.abortFilePrintSoon(); #endif } else if (DIALOG_IS(TYPE_FINISH_PRINT)) { diff --git a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp index 4134759b75..76898997eb 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp @@ -638,19 +638,18 @@ char *creat_title_text() { W25QXX.SPI_FLASH_BufferWrite(bmp_public_buf, BAK_VIEW_ADDR_TFT35 + row * 400, 400); #endif row++; + card.abortFilePrintNow(); if (row >= 200) { size = 809; row = 0; gcode_preview_over = false; - card.closefile(); char *cur_name = strrchr(list_file.file_name[sel_id], '/'); SdFile file; SdFile *curDir; - card.endFilePrint(); - const char * const fname = card.diveToFile(true, curDir, cur_name); + const char * const fname = card.diveToFile(false, curDir, cur_name); if (!fname) return; if (file.open(curDir, fname, O_READ)) { gCfgItems.curFilesize = file.fileSize(); @@ -667,13 +666,12 @@ char *creat_title_text() { planner.flow_percentage[1] = 100; planner.e_factor[1] = planner.flow_percentage[1] * 0.01; #endif - card.startFileprint(); + card.startOrResumeFilePrinting(); TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); once_flag = false; } return; } - card.closefile(); #endif // SDSUPPORT } diff --git a/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp b/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp index 1e3262be3b..be693a748f 100644 --- a/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp +++ b/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp @@ -505,7 +505,7 @@ int write_to_file(char *buf, int len) { if (res == -1) { upload_file.close(); - const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath); + const char * const fname = card.diveToFile(false, upload_curDir, saveFilePath); if (upload_file.open(upload_curDir, fname, O_WRITE)) { upload_file.setpos(&pos); @@ -732,12 +732,10 @@ static void wifi_gcode_exec(uint8_t *cmd_line) { if (!gcode_preview_over) { char *cur_name = strrchr(list_file.file_name[sel_id], '/'); - card.endFilePrint(); - SdFile file; SdFile *curDir; - card.endFilePrint(); - const char * const fname = card.diveToFile(true, curDir, cur_name); + card.abortFilePrintNow(); + const char * const fname = card.diveToFile(false, curDir, cur_name); if (!fname) return; if (file.open(curDir, fname, O_READ)) { gCfgItems.curFilesize = file.fileSize(); @@ -754,7 +752,7 @@ static void wifi_gcode_exec(uint8_t *cmd_line) { planner.flow_percentage[1] = 100; planner.e_factor[1] = planner.flow_percentage[1] * 0.01f; #endif - card.startFileprint(); + card.startOrResumeFilePrinting(); TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); once_flag = false; } @@ -814,7 +812,7 @@ static void wifi_gcode_exec(uint8_t *cmd_line) { clear_cur_ui(); #if ENABLED(SDSUPPORT) uiCfg.print_state = IDLE; - card.flag.abort_sd_printing = true; + card.abortFilePrintSoon(); #endif lv_draw_ready_print(); @@ -1317,7 +1315,7 @@ static void file_first_msg_handle(uint8_t * msg, uint16_t msgLen) { card.cdroot(); upload_file.close(); - const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath); + const char * const fname = card.diveToFile(false, upload_curDir, saveFilePath); if (!upload_file.open(upload_curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) { clear_cur_ui(); @@ -1370,7 +1368,7 @@ static void file_fragment_msg_handle(uint8_t * msg, uint16_t msgLen) { int res = upload_file.write(public_buf, file_writer.write_index); if (res == -1) { upload_file.close(); - const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath); + const char * const fname = card.diveToFile(false, upload_curDir, saveFilePath); if (upload_file.open(upload_curDir, fname, O_WRITE)) { upload_file.setpos(&pos); res = upload_file.write(public_buf, file_writer.write_index); @@ -1378,7 +1376,7 @@ static void file_fragment_msg_handle(uint8_t * msg, uint16_t msgLen) { } upload_file.close(); SdFile file, *curDir; - const char * const fname = card.diveToFile(true, curDir, saveFilePath); + const char * const fname = card.diveToFile(false, curDir, saveFilePath); if (file.open(curDir, fname, O_RDWR)) { gCfgItems.curFilesize = file.fileSize(); file.close(); @@ -1744,7 +1742,7 @@ void mks_wifi_firmware_update() { if (wifi_upload(0) >= 0) { card.removeFile((char *)ESP_FIRMWARE_FILE_RENAME); SdFile file, *curDir; - const char * const fname = card.diveToFile(true, curDir, ESP_FIRMWARE_FILE); + const char * const fname = card.diveToFile(false, curDir, ESP_FIRMWARE_FILE); if (file.open(curDir, fname, O_READ)) { file.rename(curDir, (char *)ESP_FIRMWARE_FILE_RENAME); file.close(); diff --git a/Marlin/src/lcd/extui/mks_ui/wifi_upload.cpp b/Marlin/src/lcd/extui/mks_ui/wifi_upload.cpp index cb5bb762d0..4a8e473a5c 100644 --- a/Marlin/src/lcd/extui/mks_ui/wifi_upload.cpp +++ b/Marlin/src/lcd/extui/mks_ui/wifi_upload.cpp @@ -625,7 +625,7 @@ void upload_spin() { // Try to upload the given file at the given address void SendUpdateFile(const char *file, uint32_t address) { - const char * const fname = card.diveToFile(true, update_curDir, ESP_FIRMWARE_FILE); + const char * const fname = card.diveToFile(false, update_curDir, ESP_FIRMWARE_FILE); if (!update_file.open(update_curDir, fname, O_READ)) return; esp_upload.fileSize = update_file.fileSize(); diff --git a/Marlin/src/lcd/extui/ui_api.cpp b/Marlin/src/lcd/extui/ui_api.cpp index 9cc8b9962c..faa23665bb 100644 --- a/Marlin/src/lcd/extui/ui_api.cpp +++ b/Marlin/src/lcd/extui/ui_api.cpp @@ -54,6 +54,7 @@ #include "../../module/printcounter.h" #include "../../libs/duration_t.h" #include "../../HAL/shared/Delay.h" +#include "../../MarlinCore.h" #include "../../sd/cardreader.h" #if ENABLED(PRINTCOUNTER) @@ -106,9 +107,6 @@ namespace ExtUI { #if ENABLED(JOYSTICK) uint8_t jogging : 1; #endif - #if ENABLED(SDSUPPORT) - uint8_t was_sd_printing : 1; - #endif } flags; #ifdef __SAM3X8E__ @@ -1017,27 +1015,17 @@ namespace ExtUI { void setUserConfirmed() { TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); } void printFile(const char *filename) { - UNUSED(filename); - TERN_(SDSUPPORT, card.openAndPrintFile(filename)); + TERN(SDSUPPORT, card.openAndPrintFile(filename), UNUSED(filename)); } bool isPrintingFromMediaPaused() { - return TERN0(SDSUPPORT, isPrintingFromMedia() && !IS_SD_PRINTING()); + return TERN0(SDSUPPORT, isPrintingFromMedia() && printingIsPaused()); } - bool isPrintingFromMedia() { - #if ENABLED(SDSUPPORT) - // Account for when IS_SD_PRINTING() reports the end of the - // print when there is still SD card data in the planner. - flags.was_sd_printing = card.isFileOpen() || (flags.was_sd_printing && commandsInQueue()); - return flags.was_sd_printing; - #else - return false; - #endif - } + bool isPrintingFromMedia() { return IS_SD_PRINTING(); } bool isPrinting() { - return (commandsInQueue() || isPrintingFromMedia() || TERN0(SDSUPPORT, IS_SD_PRINTING())) || print_job_timer.isRunning() || print_job_timer.isPaused(); + return commandsInQueue() || isPrintingFromMedia() || printJobOngoing() || printingIsPaused(); } bool isPrintingPaused() { diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index f83d129b2f..4c33b924c4 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -1487,7 +1487,7 @@ void MarlinUI::update() { void MarlinUI::abort_print() { #if ENABLED(SDSUPPORT) wait_for_heatup = wait_for_user = false; - card.flag.abort_sd_printing = true; + card.abortFilePrintSoon(); #endif #ifdef ACTION_ON_CANCEL host_action_cancel(); diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index 14c5f13367..d7f728ad4b 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -395,7 +395,7 @@ void Endstops::event_handler() { #if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT) if (planner.abort_on_endstop_hit) { - card.endFilePrint(); + card.abortFilePrintNow(); quickstop_stepper(); thermalManager.disable_all_heaters(); print_job_timer.stop(); diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index a54884bec1..3f6b50dd4b 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -161,7 +161,7 @@ CardReader::CardReader() { #endif #endif - flag.sdprinting = flag.mounted = flag.saving = flag.logging = false; + flag.sdprinting = flag.sdprintdone = flag.mounted = flag.saving = flag.logging = false; filesize = sdpos = 0; TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0); @@ -379,7 +379,7 @@ void CardReader::ls() { // // Echo the DOS 8.3 filename (and long filename, if any) // -void CardReader::printFilename() { +void CardReader::printSelectedFilename() { if (file.isOpen()) { char dosFilename[FILENAME_LENGTH]; file.getDosName(dosFilename); @@ -487,9 +487,9 @@ void CardReader::manage_media() { void CardReader::release() { // Card removed while printing? Abort! if (IS_SD_PRINTING()) - card.flag.abort_sd_printing = true; + abortFilePrintSoon(); else - endFilePrint(); + endFilePrintNow(); flag.mounted = false; flag.workDirIsRoot = true; @@ -516,9 +516,10 @@ void CardReader::openAndPrintFile(const char *name) { * since you cannot browse files during active printing. * Used by M24 and anywhere Start / Resume applies. */ -void CardReader::startFileprint() { +void CardReader::startOrResumeFilePrinting() { if (isMounted()) { flag.sdprinting = true; + flag.sdprintdone = false; TERN_(SD_RESORT, flush_presort()); } } @@ -526,14 +527,19 @@ void CardReader::startFileprint() { // // Run tasks upon finishing or aborting a file print. // -void CardReader::endFilePrint(TERN_(SD_RESORT, const bool re_sort/*=false*/)) { +void CardReader::endFilePrintNow(TERN_(SD_RESORT, const bool re_sort/*=false*/)) { TERN_(ADVANCED_PAUSE_FEATURE, did_pause_print = 0); TERN_(DWIN_CREALITY_LCD, HMI_flag.print_finish = flag.sdprinting); - flag.sdprinting = flag.abort_sd_printing = false; + flag.abort_sd_printing = false; if (isFileOpen()) file.close(); TERN_(SD_RESORT, if (re_sort) presort()); } +void CardReader::abortFilePrintNow(TERN_(SD_RESORT, const bool re_sort/*=false*/)) { + flag.sdprinting = flag.sdprintdone = false; + endFilePrintNow(TERN_(SD_RESORT, re_sort)); +} + void CardReader::openLogFile(const char * const path) { flag.logging = DISABLED(SDCARD_READONLY); IF_DISABLED(SDCARD_READONLY, openFileWrite(path)); @@ -542,7 +548,7 @@ void CardReader::openLogFile(const char * const path) { // // Get the root-relative DOS path of the selected file // -void CardReader::getAbsFilename(char *dst) { +void CardReader::getAbsFilenameInCWD(char *dst) { *dst++ = '/'; uint8_t cnt = 1; @@ -608,7 +614,7 @@ void CardReader::openFileRead(const char * const path, const uint8_t subcall_typ } // Store current filename (based on workDirParents) and position - getAbsFilename(proc_filenames[file_subcall_ctr]); + getAbsFilenameInCWD(proc_filenames[file_subcall_ctr]); filespos[file_subcall_ctr] = sdpos; // For sub-procedures say 'SUBROUTINE CALL target: "..." parent: "..." pos12345' @@ -623,7 +629,7 @@ void CardReader::openFileRead(const char * const path, const uint8_t subcall_typ #endif } - endFilePrint(); + abortFilePrintNow(); SdFile *diveDir; const char * const fname = diveToFile(true, diveDir, path); @@ -659,7 +665,7 @@ void CardReader::openFileWrite(const char * const path) { announceOpen(2, path); TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0); - endFilePrint(); + abortFilePrintNow(); SdFile *diveDir; const char * const fname = diveToFile(false, diveDir, path); @@ -712,7 +718,7 @@ bool CardReader::fileExists(const char * const path) { void CardReader::removeFile(const char * const name) { if (!isMounted()) return; - //endFilePrint(); + //abortFilePrintNow(); SdFile *curDir; const char * const fname = diveToFile(false, curDir, name); @@ -856,6 +862,9 @@ uint16_t CardReader::countFilesInWorkDir() { /** * Dive to the given DOS 8.3 file path, with optional echo of the dive paths. * + * On entry: + * - The workDir points to the last-set navigation target by cd, cdup, cdroot, or diveToFile(true, ...) + * * On exit: * - Your curDir pointer contains an SdFile reference to the file's directory. * - If update_cwd was 'true' the workDir now points to the file's directory. @@ -865,6 +874,8 @@ uint16_t CardReader::countFilesInWorkDir() { * A nullptr result indicates an unrecoverable error. */ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, const char * const path, const bool echo/*=false*/) { + DEBUG_SECTION(est, "diveToFile", true); + // Track both parent and subfolder static SdFile newDir1, newDir2; SdFile *sub = &newDir1, *startDir; @@ -872,12 +883,12 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons // Parsing the path string const char *item_name_adr = path; - DEBUG_ECHOLNPAIR("diveToFile: path = '", path, "'"); + DEBUG_ECHOLNPAIR(" path = '", path, "'"); if (path[0] == '/') { // Starting at the root directory? diveDir = &root; item_name_adr++; - DEBUG_ECHOLNPAIR("diveToFile: CWD to root: ", hex_address((void*)diveDir)); + DEBUG_ECHOLNPAIR(" CWD to root: ", hex_address((void*)diveDir)); if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs } else @@ -885,7 +896,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons startDir = diveDir; - DEBUG_ECHOLNPAIR("diveToFile: startDir = ", hex_address((void*)startDir)); + DEBUG_ECHOLNPAIR(" startDir = ", hex_address((void*)startDir)); while (item_name_adr) { // Find next subdirectory delimiter @@ -902,7 +913,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons if (echo) SERIAL_ECHOLN(dosSubdirname); - DEBUG_ECHOLNPAIR("diveToFile: sub = ", hex_address((void*)sub)); + DEBUG_ECHOLNPAIR(" sub = ", hex_address((void*)sub)); // Open diveDir (closing first) sub->close(); @@ -914,24 +925,24 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons // Close diveDir if not at starting-point if (diveDir != startDir) { - DEBUG_ECHOLNPAIR("diveToFile: closing diveDir: ", hex_address((void*)diveDir)); + DEBUG_ECHOLNPAIR(" closing diveDir: ", hex_address((void*)diveDir)); diveDir->close(); } // diveDir now subDir diveDir = sub; - DEBUG_ECHOLNPAIR("diveToFile: diveDir = sub: ", hex_address((void*)diveDir)); + DEBUG_ECHOLNPAIR(" diveDir = sub: ", hex_address((void*)diveDir)); // Update workDirParents and workDirDepth if (update_cwd) { - DEBUG_ECHOLNPAIR("diveToFile: update_cwd"); + DEBUG_ECHOLNPAIR(" update_cwd"); if (workDirDepth < MAX_DIR_DEPTH) workDirParents[workDirDepth++] = *diveDir; } // Point sub at the other scratch object sub = (diveDir != &newDir1) ? &newDir1 : &newDir2; - DEBUG_ECHOLNPAIR("diveToFile: swapping sub = ", hex_address((void*)sub)); + DEBUG_ECHOLNPAIR(" swapping sub = ", hex_address((void*)sub)); // Next path atom address item_name_adr = name_end + 1; @@ -939,11 +950,12 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons if (update_cwd) { workDir = *diveDir; - DEBUG_ECHOLNPAIR("diveToFile: final workDir = ", hex_address((void*)diveDir)); + DEBUG_ECHOLNPAIR(" final workDir = ", hex_address((void*)diveDir)); flag.workDirIsRoot = (workDirDepth == 0); TERN_(SDCARD_SORT_ALPHA, presort()); } + DEBUG_ECHOLNPAIR(" returning string ", item_name_adr ?: "nullptr"); return item_name_adr; } @@ -1225,21 +1237,21 @@ uint16_t CardReader::get_num_Files() { // Return from procedure or close out the Print Job // void CardReader::fileHasFinished() { - planner.synchronize(); file.close(); - #if HAS_MEDIA_SUBCALLS if (file_subcall_ctr > 0) { // Resume calling file after closing procedure file_subcall_ctr--; openFileRead(proc_filenames[file_subcall_ctr], 2); // 2 = Returning from sub-procedure setIndex(filespos[file_subcall_ctr]); - startFileprint(); + startOrResumeFilePrinting(); return; } #endif - endFilePrint(TERN_(SD_RESORT, true)); - marlin_state = MF_SD_COMPLETE; + endFilePrintNow(TERN_(SD_RESORT, true)); + + flag.sdprintdone = true; // Stop getting bytes from the SD card + marlin_state = MF_SD_COMPLETE; // Tell Marlin to enqueue M1001 soon } #if ENABLED(AUTO_REPORT_SD_STATUS) diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index 5fdd1222ae..6f1633d30e 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -70,6 +70,7 @@ typedef struct { bool saving:1, logging:1, sdprinting:1, + sdprintdone:1, mounted:1, filenameIsDir:1, workDirIsRoot:1, @@ -147,23 +148,33 @@ public: // Select a file static void selectFileByIndex(const uint16_t nr); - static void selectFileByName(const char * const match); + static void selectFileByName(const char * const match); // (working directory only) // Print job - static void openAndPrintFile(const char *name); // (working directory) - static void fileHasFinished(); - static void getAbsFilename(char *dst); - static void printFilename(); - static void startFileprint(); - static void endFilePrint(TERN_(SD_RESORT, const bool re_sort=false)); static void report_status(); - static inline void pauseSDPrint() { flag.sdprinting = false; } - static inline bool isPaused() { return isFileOpen() && !flag.sdprinting; } - static inline bool isPrinting() { return flag.sdprinting; } + static void getAbsFilenameInCWD(char *dst); + static void printSelectedFilename(); + static void openAndPrintFile(const char *name); // (working directory or full path) + static void startOrResumeFilePrinting(); + static void endFilePrintNow(TERN_(SD_RESORT, const bool re_sort=false)); + static void abortFilePrintNow(TERN_(SD_RESORT, const bool re_sort=false)); + static void fileHasFinished(); + static inline void abortFilePrintSoon() { flag.abort_sd_printing = true; } + static inline void pauseSDPrint() { flag.sdprinting = false; } + static inline bool isPrinting() { return flag.sdprinting; } + static inline bool isPaused() { return isFileOpen() && !isPrinting(); } #if HAS_PRINT_PROGRESS_PERMYRIAD - static inline uint16_t permyriadDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 9999) / 10000) : 0; } + static inline uint16_t permyriadDone() { + if (flag.sdprintdone) return 10000; + if (isFileOpen() && filesize) return sdpos / ((filesize + 9999) / 10000); + return 0; + } #endif - static inline uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; } + static inline uint8_t percentDone() { + if (flag.sdprintdone) return 100; + if (isFileOpen() && filesize) return sdpos / ((filesize + 99) / 100); + return 0; + } // Helper for open and remove static const char* diveToFile(const bool update_cwd, SdFile* &curDir, const char * const path, const bool echo=false); @@ -186,15 +197,20 @@ public: static void removeJobRecoveryFile(); #endif - static inline bool isFileOpen() { return isMounted() && file.isOpen(); } - static inline uint32_t getIndex() { return sdpos; } - static inline uint32_t getFileSize() { return filesize; } - static inline bool eof() { return sdpos >= filesize; } - static inline void setIndex(const uint32_t index) { file.seekSet((sdpos = index)); } - static inline char* getWorkDirName() { workDir.getDosName(filename); return filename; } - static inline int16_t get() { int16_t out = (int16_t)file.read(); sdpos = file.curPosition(); return out; } - static inline int16_t read(void *buf, uint16_t nbyte) { return file.isOpen() ? file.read(buf, nbyte) : -1; } + // Current Working Dir - Set by cd, cdup, cdroot, and diveToFile(true, ...) + static inline char* getWorkDirName() { workDir.getDosName(filename); return filename; } + + // Print File stats + static inline uint32_t getFileSize() { return filesize; } + static inline uint32_t getIndex() { return sdpos; } + static inline bool isFileOpen() { return isMounted() && file.isOpen(); } + static inline bool eof() { return getIndex() >= getFileSize(); } + + // File data operations + static inline int16_t get() { int16_t out = (int16_t)file.read(); sdpos = file.curPosition(); return out; } + static inline int16_t read(void *buf, uint16_t nbyte) { return file.isOpen() ? file.read(buf, nbyte) : -1; } static inline int16_t write(void *buf, uint16_t nbyte) { return file.isOpen() ? file.write(buf, nbyte) : -1; } + static inline void setIndex(const uint32_t index) { file.seekSet((sdpos = index)); } // TODO: rename to diskIODriver() static DiskIODriver* diskIODriver() { return driver; } @@ -318,7 +334,8 @@ private: #define IS_SD_INSERTED() true #endif -#define IS_SD_PRINTING() card.flag.sdprinting +#define IS_SD_PRINTING() (card.flag.sdprinting && !card.flag.abort_sd_printing) +#define IS_SD_FETCHING() (!card.flag.sdprintdone && IS_SD_PRINTING()) #define IS_SD_PAUSED() card.isPaused() #define IS_SD_FILE_OPEN() card.isFileOpen() @@ -327,6 +344,7 @@ extern CardReader card; #else // !SDSUPPORT #define IS_SD_PRINTING() false +#define IS_SD_FETCHING() false #define IS_SD_PAUSED() false #define IS_SD_FILE_OPEN() false From 6f494e9bed374de9f5eed2544ad4ac8f708e05fc Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 8 May 2021 05:49:06 -0500 Subject: [PATCH 15/67] Better opt_set comment of old val --- buildroot/bin/opt_set | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildroot/bin/opt_set b/buildroot/bin/opt_set index d2d0cc241f..3f67d78900 100755 --- a/buildroot/bin/opt_set +++ b/buildroot/bin/opt_set @@ -8,7 +8,7 @@ SED=$(which gsed || which sed) while [[ $# > 1 ]]; do DID=0 for FN in Configuration Configuration_adv; do - "${SED}" -i "/^\(\s*\)\/*\s*\(#define\s\+${1}\b\)\(.*\)$/{s//\1\2 ${2} \/\/ \3/;h};\${x;/./{x;q0};x;q9}" Marlin/$FN.h && DID=1 + "${SED}" -i "/^\(\s*\)\/*\s*\(#define\s\+${1}\b\) *\(.*\)$/{s//\1\2 ${2} \/\/ \3/;h};\${x;/./{x;q0};x;q9}" Marlin/$FN.h && DID=1 done ((DID)) || eval "echo '#define ${1} ${2}' >>Marlin/Configuration.h" || From 98e7e6324074d1583e04f1fefbdb5d52a17c173a Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 2 May 2021 03:29:29 -0500 Subject: [PATCH 16/67] TFT pins for BTT GTR V1 Proposed in #21772 --- Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h | 108 ++++++++++++------ .../pins/stm32f4/pins_BTT_SKR_V2_0_common.h | 6 +- 2 files changed, 73 insertions(+), 41 deletions(-) diff --git a/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h b/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h index cae1261a81..70d502f68a 100644 --- a/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h +++ b/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h @@ -342,7 +342,7 @@ #endif #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD + #define SDCARD_CONNECTION ONBOARD #endif // @@ -352,8 +352,8 @@ // #if SD_CONNECTION_IS(LCD) - #define SD_DETECT_PIN PB10 - #define SDSS PB12 + #define SD_DETECT_PIN EXP2_04_PIN + #define SDSS EXP2_07_PIN #elif SD_CONNECTION_IS(ONBOARD) @@ -371,31 +371,63 @@ #endif /** - * ----- ----- - * NC | · · | GND 5V | · · | GND - * RESET | · · | PB10(SD_DETECT) (LCD_D7) PG5 | · · | PG6 (LCD_D6) - * (MOSI)PB15 | · · | PH10(BTN_EN2) (LCD_D5) PG7 | · · | PG8 (LCD_D4) - * (SD_SS)PB12 | · · | PD10(BTN_EN1) (LCD_RS) PA8 | · · | PC10 (LCD_EN) - * (SCK)PB13 | · · | PB14(MISO) (BTN_ENC) PA15 | · · | PC11 (BEEPER) - * ----- ----- - * EXP2 EXP1 + * ------ ------ + * NC | 1 2 | GND 5V | 1 2 | GND + * RESET | 3 4 | PB10 (SD_DETECT) (LCD_D7) PG5 | 3 4 | PG6 (LCD_D6) + * (MOSI) PB15 | 5 6 | PH10 (BTN_EN2) (LCD_D5) PG7 | 5 6 | PG8 (LCD_D4) + * (SD_SS) PB12 | 7 8 | PD10 (BTN_EN1) (LCD_RS) PA8 | 7 8 | PC10 (LCD_EN) + * (SCK) PB13 | 9 10 | PB14 (MISO) (BTN_ENC) PA15 | 9 10 | PC11 (BEEPER) + * ------ ------ + * EXP2 EXP1 */ +#define EXP1_03_PIN PG5 +#define EXP1_04_PIN PG6 +#define EXP1_05_PIN PG7 +#define EXP1_06_PIN PG8 +#define EXP1_07_PIN PA8 +#define EXP1_08_PIN PC10 +#define EXP1_09_PIN PA15 +#define EXP1_10_PIN PC11 + +#define EXP2_04_PIN PB10 +#define EXP2_05_PIN PB15 +#define EXP2_06_PIN PH10 +#define EXP2_07_PIN PB12 +#define EXP2_08_PIN PD10 +#define EXP2_09_PIN PB13 +#define EXP2_10_PIN PB14 // // LCDs and Controllers // -#if HAS_WIRED_LCD - #define BEEPER_PIN PC11 - #define BTN_ENC PA15 +#if ANY(TFT_COLOR_UI, TFT_LVGL_UI, TFT_CLASSIC_UI) + + #define TFT_CS_PIN EXP2_07_PIN + #define TFT_A0_PIN EXP2_04_PIN + #define TFT_SCK_PIN EXP2_09_PIN + #define TFT_MISO_PIN EXP2_10_PIN + #define TFT_MOSI_PIN EXP2_05_PIN + + #define TOUCH_INT_PIN EXP1_04_PIN + #define TOUCH_MISO_PIN EXP1_05_PIN + #define TOUCH_MOSI_PIN EXP1_08_PIN + #define TOUCH_SCK_PIN EXP1_06_PIN + #define TOUCH_CS_PIN EXP1_07_PIN + #define BTN_EN1 EXP2_08_PIN + #define BTN_EN2 EXP2_06_PIN + +#elif HAS_WIRED_LCD + #define BEEPER_PIN EXP1_10_PIN + #define BTN_ENC EXP1_09_PIN #if ENABLED(CR10_STOCKDISPLAY) - #define LCD_PINS_RS PG6 + #define LCD_PINS_RS EXP1_04_PIN - #define BTN_EN1 PC10 - #define BTN_EN2 PG8 + #define BTN_EN1 EXP1_08_PIN + #define BTN_EN2 EXP1_06_PIN - #define LCD_PINS_ENABLE PG5 - #define LCD_PINS_D4 PG7 + #define LCD_PINS_ENABLE EXP1_03_PIN + #define LCD_PINS_D4 EXP1_05_PIN // CR10_STOCKDISPLAY default timing is too fast #undef BOARD_ST7920_DELAY_1 @@ -403,53 +435,53 @@ #undef BOARD_ST7920_DELAY_3 #elif ENABLED(MKS_MINI_12864) - #define DOGLCD_A0 PG6 - #define DOGLCD_CS PG7 - #define BTN_EN1 PD10 - #define BTN_EN2 PH10 + #define DOGLCD_A0 EXP1_04_PIN + #define DOGLCD_CS EXP1_05_PIN + #define BTN_EN1 EXP2_08_PIN + #define BTN_EN2 EXP2_06_PIN #if SD_CONNECTION_IS(ONBOARD) #define SOFTWARE_SPI #endif #else - #define LCD_PINS_RS PA8 + #define LCD_PINS_RS EXP1_07_PIN - #define BTN_EN1 PD10 - #define BTN_EN2 PH10 + #define BTN_EN1 EXP2_08_PIN + #define BTN_EN2 EXP2_06_PIN - #define LCD_PINS_ENABLE PC10 - #define LCD_PINS_D4 PG8 + #define LCD_PINS_ENABLE EXP1_08_PIN + #define LCD_PINS_D4 EXP1_06_PIN #if ENABLED(FYSETC_MINI_12864) - #define DOGLCD_CS PC10 - #define DOGLCD_A0 PA8 + #define DOGLCD_CS EXP1_08_PIN + #define DOGLCD_A0 EXP1_07_PIN #if SD_CONNECTION_IS(ONBOARD) #define SOFTWARE_SPI #endif //#define LCD_BACKLIGHT_PIN -1 - #define LCD_RESET_PIN PG8 // Must be high or open for LCD to operate normally. + #define LCD_RESET_PIN EXP1_06_PIN // Must be high or open for LCD to operate normally. #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN PG7 + #define RGB_LED_R_PIN EXP1_05_PIN #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN PG6 + #define RGB_LED_G_PIN EXP1_04_PIN #endif #ifndef RGB_LED_B_PIN - #define RGB_LED_B_PIN PG5 + #define RGB_LED_B_PIN EXP1_03_PIN #endif #elif ENABLED(FYSETC_MINI_12864_2_1) - #define NEOPIXEL_PIN PG7 + #define NEOPIXEL_PIN EXP1_05_PIN #endif #endif // !FYSETC_MINI_12864 #if IS_ULTIPANEL - #define LCD_PINS_D5 PG7 - #define LCD_PINS_D6 PG6 - #define LCD_PINS_D7 PG5 + #define LCD_PINS_D5 EXP1_05_PIN + #define LCD_PINS_D6 EXP1_04_PIN + #define LCD_PINS_D7 EXP1_03_PIN #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) #define BTN_ENC_EN LCD_PINS_D7 // Detect the presence of the encoder diff --git a/Marlin/src/pins/stm32f4/pins_BTT_SKR_V2_0_common.h b/Marlin/src/pins/stm32f4/pins_BTT_SKR_V2_0_common.h index b88e598e6f..14cc047649 100644 --- a/Marlin/src/pins/stm32f4/pins_BTT_SKR_V2_0_common.h +++ b/Marlin/src/pins/stm32f4/pins_BTT_SKR_V2_0_common.h @@ -200,9 +200,9 @@ #if HOTENDS == 1 #if TEMP_SENSOR_PROBE - #define TEMP_PROBE_PIN TEMP_1_PIN + #define TEMP_PROBE_PIN TEMP_1_PIN #elif TEMP_SENSOR_CHAMBER - #define TEMP_CHAMBER_PIN TEMP_1_PIN + #define TEMP_CHAMBER_PIN TEMP_1_PIN #endif #endif @@ -288,7 +288,7 @@ // SD Connection // #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION LCD + #define SDCARD_CONNECTION LCD #endif /** From 4f2ff42003dda54dd20e6884564f36ee97339f7d Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 8 May 2021 06:00:59 -0500 Subject: [PATCH 17/67] Update SKR 1.3 touch pins --- Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_3.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_3.h b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_3.h index 557a4c4c65..625de05996 100644 --- a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_3.h +++ b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_3.h @@ -280,13 +280,6 @@ #define TFT_SCK_PIN EXP2_09_PIN #define TFT_MISO_PIN EXP2_10_PIN - #define TOUCH_INT_PIN EXP1_05_PIN - #define TOUCH_CS_PIN EXP1_06_PIN - - #define TOUCH_MOSI_PIN EXP2_05_PIN - #define TOUCH_SCK_PIN EXP2_09_PIN - #define TOUCH_MISO_PIN EXP2_10_PIN - #define BTN_EN2 EXP2_06_PIN #define BTN_EN1 EXP2_08_PIN #define BTN_ENC EXP1_09_PIN @@ -434,6 +427,14 @@ #endif // HAS_WIRED_LCD +#if NEED_TOUCH_PINS + #define TOUCH_CS_PIN EXP1_06_PIN + #define TOUCH_SCK_PIN EXP2_09_PIN + #define TOUCH_MOSI_PIN EXP2_05_PIN + #define TOUCH_MISO_PIN EXP2_10_PIN + #define TOUCH_INT_PIN EXP1_05_PIN +#endif + /** * Special pins * P1_30 (37) (NOT 5V tolerant) From adefecca6cea42f0baca81705c078fa4dbd8c442 Mon Sep 17 00:00:00 2001 From: Antonino Di Guardo <64427768+digant73@users.noreply.github.com> Date: Sat, 8 May 2021 11:27:02 +0000 Subject: [PATCH 18/67] Always prompt in M125 if host-prompt (as with Ext UI) (#21828) Co-authored-by: Scott Lahteine --- Marlin/src/gcode/feature/pause/M125.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/gcode/feature/pause/M125.cpp b/Marlin/src/gcode/feature/pause/M125.cpp index dcd3e99f7a..3e495eb9d3 100644 --- a/Marlin/src/gcode/feature/pause/M125.cpp +++ b/Marlin/src/gcode/feature/pause/M125.cpp @@ -81,7 +81,7 @@ void GcodeSuite::M125() { TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true)); if (pause_print(retract, park_point, show_lcd, 0)) { - if (ENABLED(EXTENSIBLE_UI) || !sd_printing || show_lcd) { + if (ENABLED(EXTENSIBLE_UI) || BOTH(EMERGENCY_PARSER, HOST_PROMPT_SUPPORT) || !sd_printing || show_lcd) { wait_for_confirmation(false, 0); resume_print(0, 0, -retract, 0); } From f95f18c8e51ab5ff2782a3fbd873d2f48207cb10 Mon Sep 17 00:00:00 2001 From: sanek88lbl <42996016+sanek88lbl@users.noreply.github.com> Date: Sun, 9 May 2021 01:06:21 +0300 Subject: [PATCH 19/67] Lerdge K EEPROM and TFT (#21812) Co-authored-by: Scott Lahteine --- .github/workflows/test-builds.yml | 1 + Marlin/src/HAL/shared/eeprom_if_i2c.cpp | 10 +++- Marlin/src/lcd/tft_io/st7796s.h | 4 +- Marlin/src/pins/stm32f4/pins_LERDGE_K.h | 62 ++++++++++++++++++------- buildroot/tests/LERDGEK | 18 +++++++ ini/features.ini | 1 + ini/stm32f4.ini | 3 +- 7 files changed, 76 insertions(+), 23 deletions(-) create mode 100755 buildroot/tests/LERDGEK diff --git a/.github/workflows/test-builds.yml b/.github/workflows/test-builds.yml index 93bda9726e..6fdd7d67bc 100644 --- a/.github/workflows/test-builds.yml +++ b/.github/workflows/test-builds.yml @@ -86,6 +86,7 @@ jobs: - FLYF407ZG - rumba32 - LERDGEX + - LERDGEK - mks_robin_nano35_stm32 - NUCLEO_F767ZI - REMRAM_V1 diff --git a/Marlin/src/HAL/shared/eeprom_if_i2c.cpp b/Marlin/src/HAL/shared/eeprom_if_i2c.cpp index f6dd33b7c4..27f0233562 100644 --- a/Marlin/src/HAL/shared/eeprom_if_i2c.cpp +++ b/Marlin/src/HAL/shared/eeprom_if_i2c.cpp @@ -30,11 +30,17 @@ #if ENABLED(I2C_EEPROM) #include "eeprom_if.h" -#include + +#if ENABLED(SOFT_I2C_EEPROM) + #include + SlowSoftWire Wire = SlowSoftWire(I2C_SDA_PIN, I2C_SCL_PIN, true); +#else + #include +#endif void eeprom_init() { Wire.begin( - #if PINS_EXIST(I2C_SCL, I2C_SDA) + #if PINS_EXIST(I2C_SCL, I2C_SDA) && DISABLED(SOFT_I2C_EEPROM) uint8_t(I2C_SDA_PIN), uint8_t(I2C_SCL_PIN) #endif ); diff --git a/Marlin/src/lcd/tft_io/st7796s.h b/Marlin/src/lcd/tft_io/st7796s.h index 8653a49ca2..e1931ed551 100644 --- a/Marlin/src/lcd/tft_io/st7796s.h +++ b/Marlin/src/lcd/tft_io/st7796s.h @@ -154,6 +154,9 @@ static const uint16_t st7796s_init[] = { static const uint16_t lerdge_st7796s_init[] = { DATASIZE_8BIT, + ESC_REG(ST7796S_SWRESET), ESC_DELAY(100), + ESC_REG(ST7796S_SLPOUT), ESC_DELAY(20), + ESC_REG(ST7796S_CSCON), 0x00C3, // enable command 2 part I ESC_REG(ST7796S_CSCON), 0x0096, // enable command 2 part II @@ -165,7 +168,6 @@ static const uint16_t lerdge_st7796s_init[] = { ESC_REG(ST7796S_PWR2), 0x0015, ESC_REG(ST7796S_PWR3), 0x00AF, - ESC_REG(0xC3), 0x0009, // Register not documented in datasheet ESC_REG(ST7796S_VCMPCTL), 0x0022, ESC_REG(ST7796S_VCMOST), 0x0000, ESC_REG(ST7796S_DOCA), 0x0040, 0x008A, 0x0000, 0x0000, 0x0029, 0x0019, 0x00A5, 0x0033, diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_K.h b/Marlin/src/pins/stm32f4/pins_LERDGE_K.h index 1bc7bbc99e..b92056ea86 100644 --- a/Marlin/src/pins/stm32f4/pins_LERDGE_K.h +++ b/Marlin/src/pins/stm32f4/pins_LERDGE_K.h @@ -28,7 +28,14 @@ #define BOARD_INFO_NAME "Lerdge K" #define DEFAULT_MACHINE_NAME "LERDGE" -#define I2C_EEPROM +// EEPROM +#if NO_EEPROM_SELECTED + #define I2C_EEPROM + #define SOFT_I2C_EEPROM // Force the use of Software I2C + #define I2C_SCL_PIN PG14 + #define I2C_SDA_PIN PG13 + #define MARLIN_EEPROM_SIZE 0x10000 +#endif // USB Flash Drive support #define HAS_OTG_USB_HOST_SUPPORT @@ -36,7 +43,7 @@ // // Servos // -//#define SERVO0_PIN PB11 +#define SERVO0_PIN PB11 // // Limit Switches @@ -96,6 +103,13 @@ // #define E1_CS_PIN PE4 //#endif +//#define E2_STEP_PIN PF4 // best guess +//#define E2_DIR_PIN PF3 // best guess +//#define E2_ENABLE_PIN PF5 // best guess +//#ifndef E2_CS_PIN +// #define E2_CS_PIN PB2 // best guess +//#endif + #if HAS_TMC_UART /** * TMC2208/TMC2209 stepper drivers @@ -163,13 +177,19 @@ #ifndef FAN_PIN #define FAN_PIN PF7 #endif + #define FAN1_PIN PF6 -#define FAN2_PIN PF8 #ifndef E0_AUTO_FAN_PIN - #define E0_AUTO_FAN_PIN PF6 + #define E0_AUTO_FAN_PIN PB1 #endif +#ifndef E1_AUTO_FAN_PIN + #define E1_AUTO_FAN_PIN PB0 +#endif + +#define CONTROLLER_FAN_PIN PF8 + // // LED / Lighting // @@ -177,10 +197,10 @@ //#define CASE_LIGHT_PIN_DO -1 //#define NEOPIXEL_PIN -1 #ifndef RGB_LED_R_PIN - #define RGB_LED_R_PIN PB7 + #define RGB_LED_R_PIN PB8 // swap R and G pin for compatibility with real wires #endif #ifndef RGB_LED_G_PIN - #define RGB_LED_G_PIN PB8 + #define RGB_LED_G_PIN PB7 #endif #ifndef RGB_LED_B_PIN #define RGB_LED_B_PIN PB9 @@ -197,7 +217,7 @@ // #define SDSS PC11 #define LED_PIN PA15 // Alive -#define PS_ON_PIN -1 +#define PS_ON_PIN PA4 #define KILL_PIN -1 #define POWER_LOSS_PIN PA4 // Power-loss / nAC_FAULT @@ -213,17 +233,23 @@ // LCD / Controller // -#define TFT_RESET_PIN PD6 -#define TFT_BACKLIGHT_PIN PD3 +#if HAS_FSMC_TFT + //#define TFT_DRIVER LERDGE_ST7796 -#define TFT_CS_PIN PD7 -#define TFT_RS_PIN PD11 + #define TFT_RESET_PIN PD6 + #define TFT_BACKLIGHT_PIN PD3 -#define TOUCH_CS_PIN PG15 -#define TOUCH_SCK_PIN PB3 -#define TOUCH_MOSI_PIN PB5 -#define TOUCH_MISO_PIN PB4 + #define TFT_CS_PIN PD7 + #define TFT_RS_PIN PD11 -#define BTN_EN1 PG10 -#define BTN_EN2 PG11 -#define BTN_ENC PG9 + #define TOUCH_CS_PIN PG15 + #define TOUCH_SCK_PIN PB3 + #define TOUCH_MOSI_PIN PB5 + #define TOUCH_MISO_PIN PB4 +#endif + +#if IS_NEWPANEL + #define BTN_EN1 PG10 + #define BTN_EN2 PG11 + #define BTN_ENC PG9 +#endif diff --git a/buildroot/tests/LERDGEK b/buildroot/tests/LERDGEK new file mode 100755 index 0000000000..1aca42c18a --- /dev/null +++ b/buildroot/tests/LERDGEK @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# +# Build tests for LERDGEK environment +# + +# exit on first failure +set -e + +# +# Build with the typical configuration +# +restore_configs +opt_set MOTHERBOARD BOARD_LERDGE_K SERIAL_PORT 1 +opt_enable TFT_GENERIC TFT_INTERFACE_FSMC TFT_COLOR_UI +exec_test $1 $2 "LERDGE K with Generic FSMC TFT with ColorUI" "$3" + +# clean up +restore_configs diff --git a/ini/features.ini b/ini/features.ini index 871741dca8..6fa74a343f 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -41,6 +41,7 @@ HAS_(FSMC|SPI|LTDC)_TFT = src_filter=+ + + HAS_SPI_TFT = src_filter=+ + I2C_EEPROM = src_filter=+ +SOFT_I2C_EEPROM = SlowSoftI2CMaster, SlowSoftWire=https://github.com/felias-fogg/SlowSoftWire/archive/master.zip SPI_EEPROM = src_filter=+ HAS_GRAPHICAL_TFT = src_filter=+ DWIN_CREALITY_LCD = src_filter=+ diff --git a/ini/stm32f4.ini b/ini/stm32f4.ini index ff99296877..325dc4b502 100644 --- a/ini/stm32f4.ini +++ b/ini/stm32f4.ini @@ -308,8 +308,7 @@ build_flags = ${stm_flash_drive.build_flags} platform = ${lerdge_common.platform} extends = lerdge_common board_build.firmware = Lerdge_K_firmware_force.bin -build_flags = ${lerdge_common.build_flags} - -DLERDGEK +build_flags = ${lerdge_common.build_flags} -DLERDGEK # # Lerdge K with USB Flash Drive Support From 42a2b5c3ec1c4067113b87ad8c1977018bbb763e Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 8 May 2021 17:34:21 -0500 Subject: [PATCH 20/67] Move temp errors calling kill() out of ISR (#21832) --- Marlin/src/module/temperature.cpp | 173 +++++++++++++++--------------- Marlin/src/module/temperature.h | 12 ++- 2 files changed, 94 insertions(+), 91 deletions(-) diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 2f1a54e91d..72d801652f 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -576,8 +576,7 @@ volatile bool Temperature::raw_temps_ready = false; const millis_t ms = millis(); - if (raw_temps_ready) { // temp sample ready - updateTemperaturesFromRawValues(); + if (updateTemperaturesIfReady()) { // temp sample ready // Get the current temperature and constrain it current_temp = GHV(degChamber(), degBed(), degHotend(heater_id)); @@ -1212,9 +1211,7 @@ void Temperature::manage_heater() { } #endif - if (!raw_temps_ready) return; - - updateTemperaturesFromRawValues(); // also resets the watchdog + if (!updateTemperaturesIfReady()) return; // Will also reset the watchdog if temperatures are ready #if DISABLED(IGNORE_THERMOCOUPLE_ERRORS) #if TEMP_SENSOR_0_IS_MAX_TC @@ -1890,29 +1887,88 @@ void Temperature::manage_heater() { #endif // HAS_TEMP_PROBE /** - * Get the raw values into the actual temperatures. - * The raw values are created in interrupt context, - * and this function is called from normal context - * as it would block the stepper routine. + * Convert the raw sensor readings into actual Celsius temperatures and + * validate raw temperatures. Bad readings generate min/maxtemp errors. + * + * The raw values are generated entirely in interrupt context, and this + * method is called from normal context once 'raw_temps_ready' has been + * set by update_raw_temperatures(). + * + * The watchdog is dependent on this method. If 'raw_temps_ready' stops + * being set by the interrupt so that this method is not called for over + * 4 seconds then something has gone afoul and the machine will be reset. */ void Temperature::updateTemperaturesFromRawValues() { + + watchdog_refresh(); // Reset because raw_temps_ready was set by the interrupt + TERN_(TEMP_SENSOR_0_IS_MAX_TC, temp_hotend[0].raw = READ_MAX_TC(0)); TERN_(TEMP_SENSOR_1_IS_MAX_TC, TERN(TEMP_SENSOR_1_AS_REDUNDANT, temp_redundant, temp_hotend[1]).raw = READ_MAX_TC(1)); #if HAS_HOTEND HOTEND_LOOP() temp_hotend[e].celsius = analog_to_celsius_hotend(temp_hotend[e].raw, e); #endif TERN_(TEMP_SENSOR_1_AS_REDUNDANT, temp_redundant.celsius = analog_to_celsius_hotend(temp_redundant.raw, 1)); - TERN_(HAS_HEATED_BED, temp_bed.celsius = analog_to_celsius_bed(temp_bed.raw)); + + TERN_(HAS_HEATED_BED, temp_bed.celsius = analog_to_celsius_bed(temp_bed.raw)); TERN_(HAS_TEMP_CHAMBER, temp_chamber.celsius = analog_to_celsius_chamber(temp_chamber.raw)); - TERN_(HAS_TEMP_COOLER, temp_cooler.celsius = analog_to_celsius_cooler(temp_cooler.raw)); - TERN_(HAS_TEMP_PROBE, temp_probe.celsius = analog_to_celsius_probe(temp_probe.raw)); + TERN_(HAS_TEMP_COOLER, temp_cooler.celsius = analog_to_celsius_cooler(temp_cooler.raw)); + TERN_(HAS_TEMP_PROBE, temp_probe.celsius = analog_to_celsius_probe(temp_probe.raw)); + TERN_(FILAMENT_WIDTH_SENSOR, filwidth.update_measured_mm()); - TERN_(HAS_POWER_MONITOR, power_monitor.capture_values()); + TERN_(HAS_POWER_MONITOR, power_monitor.capture_values()); - // Reset the watchdog on good temperature measurement - watchdog_refresh(); + #if HAS_HOTEND - raw_temps_ready = false; + static constexpr int8_t temp_dir[] = { + TERN(TEMP_SENSOR_0_IS_MAX_TC, 0, TEMPDIR(0)) + #if HAS_MULTI_HOTEND + , TERN(TEMP_SENSOR_1_IS_MAX_TC, 0, TEMPDIR(1)) + #if HOTENDS > 2 + #define _TEMPDIR(N) , TEMPDIR(N) + REPEAT_S(2, HOTENDS, _TEMPDIR) + #endif + #endif + }; + + LOOP_L_N(e, COUNT(temp_dir)) { + const int8_t tdir = temp_dir[e]; + if (tdir) { + const int16_t rawtemp = temp_hotend[e].raw * tdir; // normal direction, +rawtemp, else -rawtemp + if (rawtemp > temp_range[e].raw_max * tdir) max_temp_error((heater_id_t)e); + + const bool heater_on = temp_hotend[e].target > 0; + if (heater_on && rawtemp < temp_range[e].raw_min * tdir && !is_preheating(e)) { + #if MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED > 1 + if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) + #endif + min_temp_error((heater_id_t)e); + } + #if MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED > 1 + else + consecutive_low_temperature_error[e] = 0; + #endif + } + } + + #endif // HAS_HOTEND + + #if ENABLED(THERMAL_PROTECTION_BED) + #define BEDCMP(A,B) (TEMPDIR(BED) < 0 ? ((A)<(B)) : ((A)>(B))) + if (BEDCMP(temp_bed.raw, maxtemp_raw_BED)) max_temp_error(H_BED); + if (temp_bed.target > 0 && BEDCMP(mintemp_raw_BED, temp_bed.raw)) min_temp_error(H_BED); + #endif + + #if BOTH(HAS_HEATED_CHAMBER, THERMAL_PROTECTION_CHAMBER) + #define CHAMBERCMP(A,B) (TEMPDIR(CHAMBER) < 0 ? ((A)<(B)) : ((A)>(B))) + if (CHAMBERCMP(temp_chamber.raw, maxtemp_raw_CHAMBER)) max_temp_error(H_CHAMBER); + if (temp_chamber.target > 0 && CHAMBERCMP(mintemp_raw_CHAMBER, temp_chamber.raw)) min_temp_error(H_CHAMBER); + #endif + + #if BOTH(HAS_COOLER, THERMAL_PROTECTION_COOLER) + #define COOLERCMP(A,B) (TEMPDIR(COOLER) < 0 ? ((A)<(B)) : ((A)>(B))) + if (cutter.unitPower > 0 && COOLERCMP(temp_cooler.raw, maxtemp_raw_COOLER)) max_temp_error(H_COOLER); + if (COOLERCMP(mintemp_raw_COOLER, temp_cooler.raw)) min_temp_error(H_COOLER); + #endif } #if THERMO_SEPARATE_SPI @@ -2657,6 +2713,9 @@ void Temperature::disable_all_heaters() { /** * Update raw temperatures + * + * Called by ISR => readings_ready when new temperatures have been set by updateTemperaturesFromRawValues. + * Applies all the accumulators to the current raw temperatures. */ void Temperature::update_raw_temperatures() { @@ -2686,14 +2745,19 @@ void Temperature::update_raw_temperatures() { TERN_(HAS_JOY_ADC_X, joystick.x.update()); TERN_(HAS_JOY_ADC_Y, joystick.y.update()); TERN_(HAS_JOY_ADC_Z, joystick.z.update()); - - raw_temps_ready = true; } +/** + * Called by the Temperature ISR when all the ADCs have been processed. + * Reset all the ADC accumulators for another round of updates. + */ void Temperature::readings_ready() { - // Update the raw values if they've been read. Else we could be updating them during reading. - if (!raw_temps_ready) update_raw_temperatures(); + // Update raw values only if they're not already set. + if (!raw_temps_ready) { + update_raw_temperatures(); + raw_temps_ready = true; + } // Filament Sensor - can be read any time since IIR filtering is used TERN_(FILAMENT_WIDTH_SENSOR, filwidth.reading_ready()); @@ -2711,75 +2775,6 @@ void Temperature::readings_ready() { TERN_(HAS_JOY_ADC_X, joystick.x.reset()); TERN_(HAS_JOY_ADC_Y, joystick.y.reset()); TERN_(HAS_JOY_ADC_Z, joystick.z.reset()); - - #if HAS_HOTEND - - static constexpr int8_t temp_dir[] = { - TERN(TEMP_SENSOR_0_IS_MAX_TC, 0, TEMPDIR(0)) - #if HAS_MULTI_HOTEND - , TERN(TEMP_SENSOR_1_IS_MAX_TC, 0, TEMPDIR(1)) - #if HOTENDS > 2 - #define _TEMPDIR(N) , TEMPDIR(N) - REPEAT_S(2, HOTENDS, _TEMPDIR) - #endif - #endif - }; - - LOOP_L_N(e, COUNT(temp_dir)) { - const int8_t tdir = temp_dir[e]; - if (tdir) { - const int16_t rawtemp = temp_hotend[e].raw * tdir; // normal direction, +rawtemp, else -rawtemp - if (rawtemp > temp_range[e].raw_max * tdir) max_temp_error((heater_id_t)e); - - const bool heater_on = (temp_hotend[e].target > 0 || TERN0(PIDTEMP, temp_hotend[e].soft_pwm_amount > 0)); - if (heater_on && rawtemp < temp_range[e].raw_min * tdir && !is_preheating(e)) { - #if MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED > 1 - if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) - #endif - min_temp_error((heater_id_t)e); - } - #if MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED > 1 - else - consecutive_low_temperature_error[e] = 0; - #endif - } - } - - #endif // HAS_HOTEND - - #if ENABLED(THERMAL_PROTECTION_BED) - #if TEMPDIR(BED) < 0 - #define BEDCMP(A,B) ((A)<(B)) - #else - #define BEDCMP(A,B) ((A)>(B)) - #endif - const bool bed_on = (temp_bed.target > 0) || TERN0(PIDTEMPBED, temp_bed.soft_pwm_amount > 0); - if (BEDCMP(temp_bed.raw, maxtemp_raw_BED)) max_temp_error(H_BED); - if (bed_on && BEDCMP(mintemp_raw_BED, temp_bed.raw)) min_temp_error(H_BED); - #endif - - #if BOTH(HAS_HEATED_CHAMBER, THERMAL_PROTECTION_CHAMBER) - #if TEMPDIR(CHAMBER) < 0 - #define CHAMBERCMP(A,B) ((A)<(B)) - #else - #define CHAMBERCMP(A,B) ((A)>(B)) - #endif - const bool chamber_on = (temp_chamber.target > 0); - if (CHAMBERCMP(temp_chamber.raw, maxtemp_raw_CHAMBER)) max_temp_error(H_CHAMBER); - if (chamber_on && CHAMBERCMP(mintemp_raw_CHAMBER, temp_chamber.raw)) min_temp_error(H_CHAMBER); - #endif - - #if BOTH(HAS_COOLER, THERMAL_PROTECTION_COOLER) - #if TEMPDIR(COOLER) < 0 - #define COOLERCMP(A,B) ((A)<(B)) - #else - #define COOLERCMP(A,B) ((A)>(B)) - #endif - if (cutter.unitPower > 0) { - if (COOLERCMP(temp_cooler.raw, maxtemp_raw_COOLER)) max_temp_error(H_COOLER); - } - if (COOLERCMP(mintemp_raw_COOLER, temp_cooler.raw)) min_temp_error(H_COOLER); - #endif } /** diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index 96ff8b5895..83fbc8fd46 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -419,8 +419,6 @@ class Temperature { private: - static volatile bool raw_temps_ready; - #if ENABLED(WATCH_HOTENDS) static hotend_watch_t watch_hotend[HOTENDS]; #endif @@ -880,9 +878,19 @@ class Temperature { #endif private: + + // Reading raw temperatures and converting to Celsius when ready + static volatile bool raw_temps_ready; static void update_raw_temperatures(); static void updateTemperaturesFromRawValues(); + static inline bool updateTemperaturesIfReady() { + if (!raw_temps_ready) return false; + updateTemperaturesFromRawValues(); + raw_temps_ready = false; + return true; + } + // MAX Thermocouples #if HAS_MAX_TC #define MAX_TC_COUNT 1 + BOTH(TEMP_SENSOR_0_IS_MAX_TC, TEMP_SENSOR_1_IS_MAX_TC) #if MAX_TC_COUNT > 1 From 9f10695b3f7460a1981c5d1c6ea3999a85f63cc2 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 8 May 2021 19:00:47 -0500 Subject: [PATCH 21/67] Fix TFT typo --- Marlin/src/HAL/STM32/tft/tft_ltdc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/HAL/STM32/tft/tft_ltdc.cpp b/Marlin/src/HAL/STM32/tft/tft_ltdc.cpp index c1a56101ad..f2509ce5e4 100644 --- a/Marlin/src/HAL/STM32/tft/tft_ltdc.cpp +++ b/Marlin/src/HAL/STM32/tft/tft_ltdc.cpp @@ -312,7 +312,7 @@ void TFT_LTDC::DrawImage(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uin uint16_t offline = TFT_WIDTH - (ex - sx); uint32_t addr = (uint32_t)&framebuffer[(TFT_WIDTH * sy) + sx]; - CBI(DMA2D->CR, 0) + CBI(DMA2D->CR, 0); DMA2D->CR = 0 << 16; DMA2D->FGPFCCR = 0X02; DMA2D->FGOR = 0; From 6cc45d2578fe925841bce17c917f7778849a30d1 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Sun, 9 May 2021 01:08:03 +0000 Subject: [PATCH 22/67] [cron] Bump distribution date (2021-05-09) --- Marlin/src/inc/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 572722416f..9991da493f 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2021-05-08" + #define STRING_DISTRIBUTION_DATE "2021-05-09" #endif /** From c9de9d4f9b8aee4ac3dfd0f49591b822230f43c7 Mon Sep 17 00:00:00 2001 From: BigTreeTech <38851044+bigtreetech@users.noreply.github.com> Date: Sun, 9 May 2021 10:02:16 +0800 Subject: [PATCH 23/67] Capacitive Touch Screen (GT911) for SKR SE BX (#21843) Co-authored-by: Msq001 Co-authored-by: Scott Lahteine --- Marlin/Configuration.h | 2 +- Marlin/src/HAL/LPC1768/tft/xpt2046.cpp | 2 +- Marlin/src/HAL/STM32/tft/gt911.cpp | 202 +++++++++++++++++++ Marlin/src/HAL/STM32/tft/gt911.h | 120 +++++++++++ Marlin/src/HAL/STM32/tft/xpt2046.cpp | 2 +- Marlin/src/HAL/STM32F1/tft/xpt2046.cpp | 2 +- Marlin/src/inc/Conditionals_LCD.h | 27 ++- Marlin/src/inc/Conditionals_adv.h | 4 +- Marlin/src/inc/SanityCheck.h | 18 +- Marlin/src/lcd/tft/touch.cpp | 25 ++- Marlin/src/lcd/tft/touch.h | 13 +- Marlin/src/lcd/tft/ui_1024x600.cpp | 43 ++-- Marlin/src/lcd/touch/touch_buttons.cpp | 11 +- Marlin/src/pins/stm32h7/pins_BTT_SKR_SE_BX.h | 16 +- 14 files changed, 425 insertions(+), 62 deletions(-) create mode 100644 Marlin/src/HAL/STM32/tft/gt911.cpp create mode 100644 Marlin/src/HAL/STM32/tft/gt911.h diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index e1f9a4be70..755b58fe15 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -2571,7 +2571,7 @@ //#define DWIN_CREALITY_LCD // -// ADS7843/XPT2046 ADC Touchscreen such as ILI9341 2.8 +// Touch Screen Settings // //#define TOUCH_SCREEN #if ENABLED(TOUCH_SCREEN) diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp index cf14405484..9c1e158981 100644 --- a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp +++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp @@ -22,7 +22,7 @@ #include "../../../inc/MarlinConfig.h" -#if HAS_TFT_XPT2046 || HAS_TOUCH_BUTTONS +#if HAS_TFT_XPT2046 || HAS_RES_TOUCH_BUTTONS #include "xpt2046.h" #include diff --git a/Marlin/src/HAL/STM32/tft/gt911.cpp b/Marlin/src/HAL/STM32/tft/gt911.cpp new file mode 100644 index 0000000000..f99fa46e19 --- /dev/null +++ b/Marlin/src/HAL/STM32/tft/gt911.cpp @@ -0,0 +1,202 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) + +#include "../../../inc/MarlinConfig.h" + +#if ENABLED(TFT_TOUCH_DEVICE_GT911) + +#include "gt911.h" +#include "pinconfig.h" + +SW_IIC::SW_IIC(uint16_t sda, uint16_t scl) { + scl_pin = scl; + sda_pin = sda; +} + +// Software I2C hardware io init +void SW_IIC::init() { + OUT_WRITE(scl_pin, HIGH); + OUT_WRITE(sda_pin, HIGH); +} + +// Software I2C start signal +void SW_IIC::start() { + write_sda(HIGH); // SDA = 1 + write_scl(HIGH); // SCL = 1 + iic_delay(2); + write_sda(LOW); // SDA = 0 + iic_delay(1); + write_scl(LOW); // SCL = 0 // keep SCL low, avoid false stop caused by level jump caused by SDA switching IN/OUT +} + +// Software I2C stop signal +void SW_IIC::stop() { + write_scl(LOW); // SCL = 0 + iic_delay(2); + write_sda(LOW); // SDA = 0 + iic_delay(2); + write_scl(HIGH); // SCL = 1 + iic_delay(2); + write_sda(HIGH); // SDA = 1 +} + +// Software I2C sends ACK or NACK signal +void SW_IIC::send_ack(bool ack) { + write_sda(ack ? LOW : HIGH); // SDA = !ack + iic_delay(2); + write_scl(HIGH); // SCL = 1 + iic_delay(2); + write_scl(LOW); // SCL = 0 +} + +// Software I2C read ACK or NACK signal +bool SW_IIC::read_ack() { + bool error = 0; + set_sda_in(); + + iic_delay(2); + + write_scl(HIGH); // SCL = 1 + error = read_sda(); + + iic_delay(2); + + write_scl(LOW); // SCL = 0 + + set_sda_out(); + return error; +} + +void SW_IIC::send_byte(uint8_t txd) { + LOOP_L_N(i, 8) { + write_sda(txd & 0x80); // write data bit + txd <<= 1; + iic_delay(1); + write_scl(HIGH); // SCL = 1 + iic_delay(2); + write_scl(LOW); // SCL = 0 + iic_delay(1); + } + + read_ack(); // wait ack +} + +uint8_t SW_IIC::read_byte(bool ack) { + uint8_t data = 0; + + set_sda_in(); + LOOP_L_N(i, 8) { + write_scl(HIGH); // SCL = 1 + iic_delay(1); + data <<= 1; + if (read_sda()) data++; + write_scl(LOW); // SCL = 0 + iic_delay(2); + } + set_sda_out(); + + send_ack(ack); + + return data; +} + +GT911_REG_MAP GT911::reg; +SW_IIC GT911::sw_iic = SW_IIC(GT911_SW_I2C_SDA_PIN, GT911_SW_I2C_SCL_PIN); + +void GT911::write_reg(uint16_t reg, uint8_t reg_len, uint8_t* w_data, uint8_t w_len) { + sw_iic.start(); + sw_iic.send_byte(gt911_slave_address); // Set IIC Slave address + LOOP_L_N(i, reg_len) { // Set reg address + uint8_t r = (reg >> (8 * (reg_len - 1 - i))) & 0xFF; + sw_iic.send_byte(r); + } + + LOOP_L_N(i, w_len) { // Write data to reg + sw_iic.send_byte(w_data[i]); + } + sw_iic.stop(); +} + +void GT911::read_reg(uint16_t reg, uint8_t reg_len, uint8_t* r_data, uint8_t r_len) { + sw_iic.start(); + sw_iic.send_byte(gt911_slave_address); // Set IIC Slave address + LOOP_L_N(i, reg_len) { // Set reg address + uint8_t r = (reg >> (8 * (reg_len - 1 - i))) & 0xFF; + sw_iic.send_byte(r); + } + + sw_iic.start(); + sw_iic.send_byte(gt911_slave_address + 1); // Set read mode + + LOOP_L_N(i, r_len) { + r_data[i] = sw_iic.read_byte(1); // Read data from reg + } + sw_iic.stop(); +} + +void GT911::Init() { + OUT_WRITE(GT911_RST_PIN, LOW); + OUT_WRITE(GT911_INT_PIN, LOW); + delay(20); + WRITE(GT911_RST_PIN, HIGH); + SET_INPUT(GT911_INT_PIN); + + sw_iic.init(); + + uint8_t clear_reg = 0x0000; + write_reg(0x814E, 2, &clear_reg, 2); // Reset to 0 for start +} + +bool GT911::getFirstTouchPoint(int16_t *x, int16_t *y) { + read_reg(0x814E, 2, ®.REG.status, 1); + + if (reg.REG.status & 0x80) { + uint8_t clear_reg = 0x00; + write_reg(0x814E, 2, &clear_reg, 1); // Reset to 0 for start + read_reg(0x8150, 2, reg.map + 2, 8 * (reg.REG.status & 0x0F)); + + // First touch point + *x = ((reg.REG.point[0].xh & 0x0F) << 8) | reg.REG.point[0].xl; + *y = ((reg.REG.point[0].yh & 0x0F) << 8) | reg.REG.point[0].yl; + return true; + } + return false; +} + +bool GT911::getPoint(int16_t *x, int16_t *y) { + static bool touched = 0; + static int16_t read_x = 0, read_y = 0; + static millis_t next_time = 0; + + if (ELAPSED(millis(), next_time)) { + touched = getFirstTouchPoint(&read_x, &read_y); + next_time = millis() + 20; + } + + *x = read_x; + *y = read_y; + return touched; +} + +#endif // TFT_TOUCH_DEVICE_GT911 +#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/STM32/tft/gt911.h b/Marlin/src/HAL/STM32/tft/gt911.h new file mode 100644 index 0000000000..752a554d98 --- /dev/null +++ b/Marlin/src/HAL/STM32/tft/gt911.h @@ -0,0 +1,120 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../../inc/MarlinConfig.h" + +#define GT911_SLAVE_ADDRESS 0xBA + +#if !PIN_EXISTS(GT911_RST) + #error "GT911_RST_PIN is not defined." +#elif !PIN_EXISTS(GT911_INT) + #error "GT911_INT_PIN is not defined." +#elif !PIN_EXISTS(GT911_SW_I2C_SCL) + #error "GT911_SW_I2C_SCL_PIN is not defined." +#elif !PIN_EXISTS(GT911_SW_I2C_SDA) + #error "GT911_SW_I2C_SDA_PIN is not defined." +#endif + +class SW_IIC { + private: + uint16_t scl_pin; + uint16_t sda_pin; + void write_scl(bool level) + { + WRITE(scl_pin, level); + } + void write_sda(bool level) + { + WRITE(sda_pin, level); + } + bool read_sda() + { + return READ(sda_pin); + } + void set_sda_out() + { + SET_OUTPUT(sda_pin); + } + void set_sda_in() + { + SET_INPUT_PULLUP(sda_pin); + } + static void iic_delay(uint8_t t) + { + delayMicroseconds(t); + } + + public: + SW_IIC(uint16_t sda, uint16_t scl); + // setSCL/SDA have to be called before begin() + void setSCL(uint16_t scl) + { + scl_pin = scl; + }; + void setSDA(uint16_t sda) + { + sda_pin = sda; + }; + void init(); // Initialize the IO port of IIC + void start(); // Send IIC start signal + void stop(); // Send IIC stop signal + void send_byte(uint8_t txd); // IIC sends a byte + uint8_t read_byte(bool ack); // IIC reads a byte + void send_ack(bool ack); // IIC sends ACK or NACK signal + bool read_ack(); +}; + +typedef struct __attribute__((__packed__)) { + uint8_t xl; + uint8_t xh; + uint8_t yl; + uint8_t yh; + uint8_t sizel; + uint8_t sizeh; + uint8_t reserved; + uint8_t track_id; +} GT911_POINT; + +typedef union __attribute__((__packed__)) { + uint8_t map[42]; + struct { + uint8_t status; // 0x814E + uint8_t track_id; // 0x814F + + GT911_POINT point[5]; // [0]:0x8150 - 0x8157 / [1]:0x8158 - 0x815F / [2]:0x8160 - 0x8167 / [3]:0x8168 - 0x816F / [4]:0x8170 - 0x8177 + } REG; +} GT911_REG_MAP; + +class GT911 { + private: + static const uint8_t gt911_slave_address = GT911_SLAVE_ADDRESS; + static GT911_REG_MAP reg; + static SW_IIC sw_iic; + static void write_reg(uint16_t reg, uint8_t reg_len, uint8_t* w_data, uint8_t w_len); + static void read_reg(uint16_t reg, uint8_t reg_len, uint8_t* r_data, uint8_t r_len); + + public: + static void Init(); + static bool getFirstTouchPoint(int16_t *x, int16_t *y); + static bool getPoint(int16_t *x, int16_t *y); +}; diff --git a/Marlin/src/HAL/STM32/tft/xpt2046.cpp b/Marlin/src/HAL/STM32/tft/xpt2046.cpp index 04294e669c..dffeb6aaf7 100644 --- a/Marlin/src/HAL/STM32/tft/xpt2046.cpp +++ b/Marlin/src/HAL/STM32/tft/xpt2046.cpp @@ -23,7 +23,7 @@ #include "../../../inc/MarlinConfig.h" -#if HAS_TFT_XPT2046 || HAS_TOUCH_BUTTONS +#if HAS_TFT_XPT2046 || HAS_RES_TOUCH_BUTTONS #include "xpt2046.h" #include "pinconfig.h" diff --git a/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp b/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp index 98371c5ffb..ac9ad072aa 100644 --- a/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp +++ b/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp @@ -22,7 +22,7 @@ #include "../../../inc/MarlinConfig.h" -#if HAS_TFT_XPT2046 || HAS_TOUCH_BUTTONS +#if HAS_TFT_XPT2046 || HAS_RES_TOUCH_BUTTONS #include "xpt2046.h" #include diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index afec2c2b44..ed86c1bf65 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -1131,6 +1131,9 @@ #define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY) #define TFT_RES_1024x600 #define TFT_INTERFACE_LTDC + #if ENABLED(TOUCH_SCREEN) + #define TFT_TOUCH_DEVICE_GT911 + #endif #elif ENABLED(TFT_GENERIC) #define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_X | TFT_INVERT_Y) #if NONE(TFT_RES_320x240, TFT_RES_480x272, TFT_RES_480x320) @@ -1219,16 +1222,30 @@ #define HAS_UI_1024x600 1 #endif #if ANY(HAS_UI_320x240, HAS_UI_480x320, HAS_UI_480x272) - #define LCD_HEIGHT TERN(TOUCH_SCREEN, 6, 7) // Fewer lines with touch buttons onscreen + #define LCD_HEIGHT TERN(TOUCH_SCREEN, 6, 7) // Fewer lines with touch buttons onscreen #elif HAS_UI_1024x600 #define LCD_HEIGHT TERN(TOUCH_SCREEN, 12, 13) // Fewer lines with touch buttons onscreen #endif // This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046' -#if ENABLED(TOUCH_SCREEN) && !HAS_GRAPHICAL_TFT - #undef TOUCH_SCREEN - #if ENABLED(TFT_CLASSIC_UI) - #define HAS_TOUCH_BUTTONS 1 +#if ENABLED(TOUCH_SCREEN) + #if NONE(TFT_TOUCH_DEVICE_GT911, TFT_TOUCH_DEVICE_XPT2046) + #define TFT_TOUCH_DEVICE_XPT2046 // ADS7843/XPT2046 ADC Touchscreen such as ILI9341 2.8 + #endif + #if ENABLED(TFT_TOUCH_DEVICE_GT911) // GT911 Capacitive touch screen such as BIQU_BX_TFT70 + #undef TOUCH_SCREEN_CALIBRATION + #undef TOUCH_CALIBRATION_AUTO_SAVE + #endif + #if !HAS_GRAPHICAL_TFT + #undef TOUCH_SCREEN + #if ENABLED(TFT_CLASSIC_UI) + #define HAS_TOUCH_BUTTONS 1 + #if ENABLED(TFT_TOUCH_DEVICE_GT911) + #define HAS_CAP_TOUCH_BUTTONS 1 + #else + #define HAS_RES_TOUCH_BUTTONS 1 + #endif + #endif #endif #endif diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 19ab98fed3..44ea34a490 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -371,13 +371,13 @@ #endif // Full Touch Screen needs 'tft/xpt2046' -#if EITHER(TOUCH_SCREEN, HAS_TFT_LVGL_UI) +#if EITHER(TFT_TOUCH_DEVICE_XPT2046, HAS_TFT_LVGL_UI) #define HAS_TFT_XPT2046 1 #endif // Touch Screen or "Touch Buttons" need XPT2046 pins // but they use different components -#if EITHER(HAS_TFT_XPT2046, HAS_TOUCH_BUTTONS) +#if HAS_TFT_XPT2046 || HAS_RES_TOUCH_BUTTONS #define NEED_TOUCH_PINS 1 #endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 2cc90e0e8b..bbd646a30d 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -3180,21 +3180,11 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #endif /** - * Touch Buttons + * Touch Screen Calibration */ -#if ENABLED(TOUCH_SCREEN) && DISABLED(TOUCH_SCREEN_CALIBRATION) - #ifndef TOUCH_CALIBRATION_X - #error "TOUCH_CALIBRATION_X must be defined with TOUCH_SCREEN." - #endif - #ifndef TOUCH_CALIBRATION_Y - #error "TOUCH_CALIBRATION_Y must be defined with TOUCH_SCREEN." - #endif - #ifndef TOUCH_OFFSET_X - #error "TOUCH_OFFSET_X must be defined with TOUCH_SCREEN." - #endif - #ifndef TOUCH_OFFSET_Y - #error "TOUCH_OFFSET_Y must be defined with TOUCH_SCREEN." - #endif +#if ENABLED(TFT_TOUCH_DEVICE_XPT2046) && DISABLED(TOUCH_SCREEN_CALIBRATION) \ + && (!defined(TOUCH_CALIBRATION_X) || !defined(TOUCH_CALIBRATION_Y) || !defined(TOUCH_OFFSET_X) || !defined(TOUCH_OFFSET_Y)) + #error "TOUCH_CALIBRATION_[XY] and TOUCH_OFFSET_[XY] are required for resistive touch screens with TOUCH_SCREEN_CALIBRATION disabled." #endif /** diff --git a/Marlin/src/lcd/tft/touch.cpp b/Marlin/src/lcd/tft/touch.cpp index 83a7ea78b7..3d4e0a40e1 100644 --- a/Marlin/src/lcd/tft/touch.cpp +++ b/Marlin/src/lcd/tft/touch.cpp @@ -257,18 +257,23 @@ void Touch::hold(touch_control_t *control, millis_t delay) { } bool Touch::get_point(int16_t *x, int16_t *y) { - #if ENABLED(TOUCH_SCREEN_CALIBRATION) - bool is_touched = (touch_calibration.calibration.orientation == TOUCH_PORTRAIT ? io.getRawPoint(y, x) : io.getRawPoint(x, y)); + #if ENABLED(TFT_TOUCH_DEVICE_XPT2046) + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + bool is_touched = (touch_calibration.calibration.orientation == TOUCH_PORTRAIT ? io.getRawPoint(y, x) : io.getRawPoint(x, y)); - if (is_touched && touch_calibration.calibration.orientation != TOUCH_ORIENTATION_NONE) { - *x = int16_t((int32_t(*x) * touch_calibration.calibration.x) >> 16) + touch_calibration.calibration.offset_x; - *y = int16_t((int32_t(*y) * touch_calibration.calibration.y) >> 16) + touch_calibration.calibration.offset_y; - } - #else - bool is_touched = (TOUCH_ORIENTATION == TOUCH_PORTRAIT ? io.getRawPoint(y, x) : io.getRawPoint(x, y)); - *x = uint16_t((uint32_t(*x) * TOUCH_CALIBRATION_X) >> 16) + TOUCH_OFFSET_X; - *y = uint16_t((uint32_t(*y) * TOUCH_CALIBRATION_Y) >> 16) + TOUCH_OFFSET_Y; + if (is_touched && touch_calibration.calibration.orientation != TOUCH_ORIENTATION_NONE) { + *x = int16_t((int32_t(*x) * touch_calibration.calibration.x) >> 16) + touch_calibration.calibration.offset_x; + *y = int16_t((int32_t(*y) * touch_calibration.calibration.y) >> 16) + touch_calibration.calibration.offset_y; + } + #else + bool is_touched = (TOUCH_ORIENTATION == TOUCH_PORTRAIT ? io.getRawPoint(y, x) : io.getRawPoint(x, y)); + *x = uint16_t((uint32_t(*x) * TOUCH_CALIBRATION_X) >> 16) + TOUCH_OFFSET_X; + *y = uint16_t((uint32_t(*y) * TOUCH_CALIBRATION_Y) >> 16) + TOUCH_OFFSET_Y; + #endif + #elif ENABLED(TFT_TOUCH_DEVICE_GT911) + bool is_touched = (TOUCH_ORIENTATION == TOUCH_PORTRAIT ? io.getPoint(y, x) : io.getPoint(x, y)); #endif + return is_touched; } Touch touch; diff --git a/Marlin/src/lcd/tft/touch.h b/Marlin/src/lcd/tft/touch.h index 6726f031ff..8d6001b8d8 100644 --- a/Marlin/src/lcd/tft/touch.h +++ b/Marlin/src/lcd/tft/touch.h @@ -30,8 +30,15 @@ #include "../tft_io/touch_calibration.h" #endif -#include HAL_PATH(../../HAL, tft/xpt2046.h) -#define TOUCH_DRIVER XPT2046 +#if ENABLED(TFT_TOUCH_DEVICE_GT911) + #include HAL_PATH(../../HAL, tft/gt911.h) + #define TOUCH_DRIVER_CLASS GT911 +#elif ENABLED(TFT_TOUCH_DEVICE_XPT2046) + #include HAL_PATH(../../HAL, tft/xpt2046.h) + #define TOUCH_DRIVER_CLASS XPT2046 +#else + #error "Unknown Touch Screen Type." +#endif // Menu Navigation extern int8_t encoderTopLine, encoderLine, screen_items; @@ -85,7 +92,7 @@ typedef struct __attribute__((__packed__)) { class Touch { private: - static TOUCH_DRIVER io; + static TOUCH_DRIVER_CLASS io; static int16_t x, y; static bool enabled; diff --git a/Marlin/src/lcd/tft/ui_1024x600.cpp b/Marlin/src/lcd/tft/ui_1024x600.cpp index c9c0aae05a..3b12ab2b60 100644 --- a/Marlin/src/lcd/tft/ui_1024x600.cpp +++ b/Marlin/src/lcd/tft/ui_1024x600.cpp @@ -48,9 +48,9 @@ void MarlinUI::tft_idle() { #if ENABLED(TOUCH_SCREEN) if (draw_menu_navigation) { - add_control(104, TFT_HEIGHT - 34, PAGE_UP, imgPageUp, encoderTopLine > 0); - add_control(344, TFT_HEIGHT - 34, PAGE_DOWN, imgPageDown, encoderTopLine + LCD_HEIGHT < screen_items); - add_control(224, TFT_HEIGHT - 34, BACK, imgBack); + add_control(164, TFT_HEIGHT - 50, PAGE_UP, imgPageUp, encoderTopLine > 0); + add_control(796, TFT_HEIGHT - 50, PAGE_DOWN, imgPageDown, encoderTopLine + LCD_HEIGHT < screen_items); + add_control(480, TFT_HEIGHT - 50, BACK, imgBack); draw_menu_navigation = false; } #endif @@ -60,6 +60,7 @@ void MarlinUI::tft_idle() { } #if ENABLED(SHOW_BOOTSCREEN) + void MarlinUI::show_bootscreen() { tft.queue.reset(); @@ -81,9 +82,13 @@ void MarlinUI::tft_idle() { #endif tft.queue.sync(); - safe_delay(BOOTSCREEN_TIMEOUT); + } + + void MarlinUI::bootscreen_completion(const millis_t sofar) { + if ((BOOTSCREEN_TIMEOUT) > sofar) safe_delay((BOOTSCREEN_TIMEOUT) - sofar); clear_lcd(); } + #endif void MarlinUI::draw_kill_screen() { @@ -289,7 +294,7 @@ void MarlinUI::draw_status_screen() { tft_string.set(i16tostr3rj(feedrate_percentage)); tft_string.add('%'); tft.add_text(36, 1, color , tft_string); - TERN_(TOUCH_SCREEN, touch.add_control(FEEDRATE, 96, 176, 100, 32)); + TERN_(TOUCH_SCREEN, touch.add_control(FEEDRATE, 274, y, 100, 32)); // flow rate tft.canvas(650, y, 100, 32); @@ -299,10 +304,10 @@ void MarlinUI::draw_status_screen() { tft_string.set(i16tostr3rj(planner.flow_percentage[active_extruder])); tft_string.add('%'); tft.add_text(36, 1, color , tft_string); - TERN_(TOUCH_SCREEN, touch.add_control(FLOWRATE, 284, 176, 100, 32, active_extruder)); + TERN_(TOUCH_SCREEN, touch.add_control(FLOWRATE, 650, y, 100, 32, active_extruder)); #if ENABLED(TOUCH_SCREEN) - add_control(404, y, menu_main, imgSettings); + add_control(900, y, menu_main, imgSettings); TERN_(SDSUPPORT, add_control(12, y, menu_media, imgSD, !printingIsActive(), COLOR_CONTROL_ENABLED, card.isMounted() && printingIsActive() ? COLOR_BUSY : COLOR_CONTROL_DISABLED)); #endif @@ -375,8 +380,8 @@ void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const val extern screenFunc_t _manual_move_func_ptr; if (ui.currentScreen != _manual_move_func_ptr && !ui.external_control) { - #define SLIDER_LENGTH 336 - #define SLIDER_Y_POSITION 186 + #define SLIDER_LENGTH 600 + #define SLIDER_Y_POSITION 200 tft.canvas((TFT_WIDTH - SLIDER_LENGTH) / 2, SLIDER_Y_POSITION, SLIDER_LENGTH, 16); tft.set_background(COLOR_BACKGROUND); @@ -398,9 +403,9 @@ void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const val void TFT::draw_edit_screen_buttons() { #if ENABLED(TOUCH_SCREEN) - add_control(64, TFT_HEIGHT - 64, DECREASE, imgDecrease); - add_control(352, TFT_HEIGHT - 64, INCREASE, imgIncrease); - add_control(208, TFT_HEIGHT - 64, CLICK, imgConfirm); + add_control(164, TFT_HEIGHT - 64, DECREASE, imgDecrease); + add_control(796, TFT_HEIGHT - 64, INCREASE, imgIncrease); + add_control(480, TFT_HEIGHT - 64, CLICK, imgConfirm); #endif } @@ -755,7 +760,7 @@ static void z_minus() { moveAxis(Z_AXIS, -1); } drawMessage(GET_TEXT(MSG_LEVEL_BED_HOMING)); queue.inject_P(G28_STR); // Disable touch until home is done - TERN_(HAS_TFT_XPT2046, touch.disable()); + TERN_(TOUCH_SCREEN, touch.disable()); drawAxisValue(E_AXIS); drawAxisValue(X_AXIS); drawAxisValue(Y_AXIS); @@ -804,14 +809,14 @@ static void drawBtn(int x, int y, const char *label, intptr_t data, MarlinImage tft.add_image(0, 0, img, bgColor, COLOR_BACKGROUND, COLOR_DARKGREY); } - TERN_(HAS_TFT_XPT2046, if (enabled) touch.add_control(BUTTON, x, y, width, height, data)); + TERN_(TOUCH_SCREEN, if (enabled) touch.add_control(BUTTON, x, y, width, height, data)); } void MarlinUI::move_axis_screen() { // Reset defer_status_screen(true); motionAxisState.blocked = false; - TERN_(HAS_TFT_XPT2046, touch.enable()); + TERN_(TOUCH_SCREEN, touch.enable()); ui.clear_lcd(); @@ -849,13 +854,13 @@ void MarlinUI::move_axis_screen() { motionAxisState.eNamePos.x = x; motionAxisState.eNamePos.y = y; drawCurESelection(); - TERN_(HAS_TFT_XPT2046, if (!busy) touch.add_control(BUTTON, x, y, BTN_WIDTH, BTN_HEIGHT, (intptr_t)e_select)); + TERN_(TOUCH_SCREEN, if (!busy) touch.add_control(BUTTON, x, y, BTN_WIDTH, BTN_HEIGHT, (intptr_t)e_select)); x += BTN_WIDTH + spacing; drawBtn(x, y, "X-", (intptr_t)x_minus, imgLeft, X_BTN_COLOR, !busy); x += BTN_WIDTH + spacing; //imgHome is 64x64 - TERN_(HAS_TFT_XPT2046, add_control(TFT_WIDTH / 2 - Images[imgHome].width / 2, y - (Images[imgHome].width - BTN_HEIGHT) / 2, BUTTON, (intptr_t)do_home, imgHome, !busy)); + TERN_(TOUCH_SCREEN, add_control(TFT_WIDTH / 2 - Images[imgHome].width / 2, y - (Images[imgHome].width - BTN_HEIGHT) / 2, BUTTON, (intptr_t)do_home, imgHome, !busy)); x += BTN_WIDTH + spacing; uint16_t xplus_x = x; @@ -904,13 +909,13 @@ void MarlinUI::move_axis_screen() { motionAxisState.stepValuePos.y = y; if (!busy) { drawCurStepValue(); - TERN_(HAS_TFT_XPT2046, touch.add_control(BUTTON, motionAxisState.stepValuePos.x, motionAxisState.stepValuePos.y, CUR_STEP_VALUE_WIDTH, BTN_HEIGHT, (intptr_t)step_size)); + TERN_(TOUCH_SCREEN, touch.add_control(BUTTON, motionAxisState.stepValuePos.x, motionAxisState.stepValuePos.y, CUR_STEP_VALUE_WIDTH, BTN_HEIGHT, (intptr_t)step_size)); } // aligned with x+ drawBtn(xplus_x, TFT_HEIGHT - Y_MARGIN - BTN_HEIGHT, "off", (intptr_t)disable_steppers, imgCancel, COLOR_WHITE, !busy); - TERN_(HAS_TFT_XPT2046, add_control(TFT_WIDTH - X_MARGIN - BTN_WIDTH, y, BACK, imgBack)); + TERN_(TOUCH_SCREEN, add_control(TFT_WIDTH - X_MARGIN - BTN_WIDTH, y, BACK, imgBack)); } #endif // HAS_UI_480x320 diff --git a/Marlin/src/lcd/touch/touch_buttons.cpp b/Marlin/src/lcd/touch/touch_buttons.cpp index 975de58211..c9476bd2bb 100644 --- a/Marlin/src/lcd/touch/touch_buttons.cpp +++ b/Marlin/src/lcd/touch/touch_buttons.cpp @@ -24,8 +24,15 @@ #include "touch_buttons.h" #include "../scaled_tft.h" -#include HAL_PATH(../../HAL, tft/xpt2046.h) -XPT2046 touchIO; +#if ENABLED(TFT_TOUCH_DEVICE_GT911) + #include HAL_PATH(../../HAL, tft/gt911.h) + GT911 touchIO; +#elif ENABLED(TFT_TOUCH_DEVICE_XPT2046) + #include HAL_PATH(../../HAL, tft/xpt2046.h) + XPT2046 touchIO; +#else + #error "Unknown Touch Screen Type." +#endif #if ENABLED(TOUCH_SCREEN_CALIBRATION) #include "../tft_io/touch_calibration.h" diff --git a/Marlin/src/pins/stm32h7/pins_BTT_SKR_SE_BX.h b/Marlin/src/pins/stm32h7/pins_BTT_SKR_SE_BX.h index 320d04e0b1..c4349d182b 100644 --- a/Marlin/src/pins/stm32h7/pins_BTT_SKR_SE_BX.h +++ b/Marlin/src/pins/stm32h7/pins_BTT_SKR_SE_BX.h @@ -207,11 +207,21 @@ #define LCD_B4_PIN PI4 #define LCD_B3_PIN PG11 + // GT911 Capacitive Touch Sensor + #if ENABLED(TFT_TOUCH_DEVICE_GT911) + #define GT911_RST_PIN PE4 + #define GT911_INT_PIN PE3 + #define GT911_SW_I2C_SCL_PIN PE2 + #define GT911_SW_I2C_SDA_PIN PE6 + #endif + #endif -#define BTN_EN1 PH6 -#define BTN_EN2 PH7 -#define BTN_ENC PH8 +#if IS_NEWPANEL + #define BTN_EN1 PH6 + #define BTN_EN2 PH7 + #define BTN_ENC PH8 +#endif #ifndef SDCARD_CONNECTION #define SDCARD_CONNECTION ONBOARD From 4335f4e41f694a92bf79e1fe0e9bfc3491fa1bd9 Mon Sep 17 00:00:00 2001 From: Victor Oliveira Date: Sat, 8 May 2021 23:05:47 -0300 Subject: [PATCH 24/67] =?UTF-8?q?=F0=9F=90=9B=20Fix=20Lerdge=20USB=20Flash?= =?UTF-8?q?=20Drive=20envs=20(#21847)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ini/stm32f4.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ini/stm32f4.ini b/ini/stm32f4.ini index 325dc4b502..62038332b3 100644 --- a/ini/stm32f4.ini +++ b/ini/stm32f4.ini @@ -282,7 +282,7 @@ board_build.firmware = Lerdge_X_firmware_force.bin platform = ${env:LERDGEX.platform} extends = env:LERDGEX platform_packages = ${stm_flash_drive.platform_packages} -build_flags = ${stm_flash_drive.build_flags} +build_flags = ${stm_flash_drive.build_flags} ${lerdge_common.build_flags} # # Lerdge S @@ -299,7 +299,7 @@ board_build.firmware = Lerdge_firmware_force.bin platform = ${env:LERDGES.platform} extends = env:LERDGES platform_packages = ${stm_flash_drive.platform_packages} -build_flags = ${stm_flash_drive.build_flags} +build_flags = ${stm_flash_drive.build_flags} ${lerdge_common.build_flags} # # Lerdge K @@ -317,7 +317,7 @@ build_flags = ${lerdge_common.build_flags} -DLERDGEK platform = ${env:LERDGEK.platform} extends = env:LERDGEK platform_packages = ${stm_flash_drive.platform_packages} -build_flags = ${stm_flash_drive.build_flags} +build_flags = ${stm_flash_drive.build_flags} ${lerdge_common.build_flags} # # RUMBA32 From 4588d836a3b6fa7560c6f1bc5c23aa93a1609d71 Mon Sep 17 00:00:00 2001 From: charlespick Date: Sat, 8 May 2021 20:46:35 -0700 Subject: [PATCH 25/67] Update Advanced Pause description (#21829) Co-authored-by: Scott Lahteine --- Marlin/Configuration_adv.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 7d89cf5205..3ec45f3f46 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -2301,14 +2301,15 @@ #endif // HAS_MULTI_EXTRUDER /** - * Advanced Pause - * Experimental feature for filament change support and for parking the nozzle when paused. - * Adds the GCode M600 for initiating filament change. - * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * Advanced Pause for Filament Change + * - Adds the G-code M600 Filament Change to initiate a filament change. + * - This feature is required for the default FILAMENT_RUNOUT_SCRIPT. * - * Requires an LCD display. - * Requires NOZZLE_PARK_FEATURE. - * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + * Requirements: + * - For Filament Change parking enable and configure NOZZLE_PARK_FEATURE. + * - For user interaction enable an LCD display, HOST_PROMPT_SUPPORT, or EMERGENCY_PARSER. + * + * Enable PARK_HEAD_ON_PAUSE to add the G-code M125 Pause and Park. */ //#define ADVANCED_PAUSE_FEATURE #if ENABLED(ADVANCED_PAUSE_FEATURE) @@ -3484,7 +3485,7 @@ #define PROPORTIONAL_FONT_RATIO 1.0 /** - * Spend 28 bytes of SRAM to optimize the GCode parser + * Spend 28 bytes of SRAM to optimize the G-code parser */ #define FASTER_GCODE_PARSER From 49548c343deb1e7f38f6027af20c02a79dbe5031 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 9 May 2021 03:50:51 -0500 Subject: [PATCH 26/67] Optimize G-code flag parameters (#21849) --- Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp | 40 ++++++++++---------- Marlin/src/feature/encoder_i2c.cpp | 14 +++---- Marlin/src/feature/fwretract.cpp | 14 +++---- Marlin/src/gcode/bedlevel/G26.cpp | 8 ++-- Marlin/src/gcode/bedlevel/M420.cpp | 2 +- Marlin/src/gcode/bedlevel/abl/G29.cpp | 12 +++--- Marlin/src/gcode/bedlevel/mbl/G29.cpp | 2 +- Marlin/src/gcode/bedlevel/ubl/M421.cpp | 25 ++++++------ Marlin/src/gcode/calibrate/G28.cpp | 6 +-- Marlin/src/gcode/calibrate/G33.cpp | 4 +- Marlin/src/gcode/feature/pause/M125.cpp | 2 +- Marlin/src/gcode/feature/pause/M600.cpp | 14 +++---- Marlin/src/gcode/feature/powerloss/M1000.cpp | 4 +- Marlin/src/gcode/feature/powerloss/M413.cpp | 12 +++--- Marlin/src/gcode/feature/runout/M412.cpp | 2 +- Marlin/src/gcode/feature/trinamic/M122.cpp | 2 +- Marlin/src/gcode/gcode_d.cpp | 2 +- Marlin/src/gcode/host/M114.cpp | 6 +-- Marlin/src/gcode/motion/G0_G1.cpp | 6 +-- Marlin/src/gcode/motion/M290.cpp | 2 +- Marlin/src/gcode/parser.h | 2 + Marlin/src/gcode/sd/M27.cpp | 2 +- Marlin/src/gcode/sd/M808.cpp | 2 +- Marlin/src/gcode/temp/M106_M107.cpp | 2 +- Marlin/src/gcode/temp/M303.cpp | 2 +- 25 files changed, 95 insertions(+), 94 deletions(-) diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp index 6130123f7a..6f1425b60c 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp @@ -306,7 +306,7 @@ void unified_bed_leveling::G29() { if (G29_parse_parameters()) return; // Abort on parameter error const int8_t p_val = parser.intval('P', -1); - const bool may_move = p_val == 1 || p_val == 2 || p_val == 4 || parser.seen('J'); + const bool may_move = p_val == 1 || p_val == 2 || p_val == 4 || parser.seen_test('J'); #if ENABLED(HAS_MULTI_HOTEND) const uint8_t old_tool_index = active_extruder; #endif @@ -315,7 +315,7 @@ void unified_bed_leveling::G29() { if (may_move) { planner.synchronize(); // Send 'N' to force homing before G29 (internal only) - if (axes_should_home() || parser.seen('N')) gcode.home_all_axes(); + if (axes_should_home() || parser.seen_test('N')) gcode.home_all_axes(); TERN_(HAS_MULTI_HOTEND, if (active_extruder) tool_change(0)); } @@ -380,7 +380,7 @@ void unified_bed_leveling::G29() { // Allow the user to specify the height because 10mm is a little extreme in some cases. for (uint8_t x = (GRID_MAX_POINTS_X) / 3; x < 2 * (GRID_MAX_POINTS_X) / 3; x++) // Create a rectangular raised area in for (uint8_t y = (GRID_MAX_POINTS_Y) / 3; y < 2 * (GRID_MAX_POINTS_Y) / 3; y++) { // the center of the bed - z_values[x][y] += parser.seen('C') ? param.C_constant : 9.99f; + z_values[x][y] += parser.seen_test('C') ? param.C_constant : 9.99f; TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); } break; @@ -389,7 +389,7 @@ void unified_bed_leveling::G29() { #if HAS_BED_PROBE - if (parser.seen('J')) { + if (parser.seen_test('J')) { save_ubl_active_state_and_disable(); tilt_mesh_based_on_probed_grid(param.J_grid_size == 0); // Zero size does 3-Point restore_ubl_active_state_and_leave(); @@ -402,7 +402,7 @@ void unified_bed_leveling::G29() { #endif // HAS_BED_PROBE - if (parser.seen('P')) { + if (parser.seen_test('P')) { if (WITHIN(param.P_phase, 0, 1) && storage_slot == -1) { storage_slot = 0; SERIAL_ECHOLNPGM("Default storage slot 0 selected."); @@ -423,7 +423,7 @@ void unified_bed_leveling::G29() { // // Invalidate Entire Mesh and Automatically Probe Mesh in areas that can be reached by the probe // - if (!parser.seen('C')) { + if (!parser.seen_test('C')) { invalidate(); SERIAL_ECHOLNPGM("Mesh invalidated. Probing mesh."); } @@ -433,7 +433,7 @@ void unified_bed_leveling::G29() { SERIAL_DECIMAL(param.XY_pos.y); SERIAL_ECHOLNPGM(").\n"); } - probe_entire_mesh(param.XY_pos, parser.seen('T'), parser.seen('E'), parser.seen('U')); + probe_entire_mesh(param.XY_pos, parser.seen_test('T'), parser.seen_test('E'), parser.seen_test('U')); report_current_position(); probe_deployed = true; @@ -449,7 +449,7 @@ void unified_bed_leveling::G29() { SERIAL_ECHOLNPGM("Manually probing unreachable points."); do_z_clearance(Z_CLEARANCE_BETWEEN_PROBES); - if (parser.seen('C') && !param.XY_seen) { + if (parser.seen_test('C') && !param.XY_seen) { /** * Use a good default location for the path. @@ -483,7 +483,7 @@ void unified_bed_leveling::G29() { } const float height = parser.floatval('H', Z_CLEARANCE_BETWEEN_PROBES); - manually_probe_remaining_mesh(param.XY_pos, height, param.B_shim_thickness, parser.seen('T')); + manually_probe_remaining_mesh(param.XY_pos, height, param.B_shim_thickness, parser.seen_test('T')); SERIAL_ECHOLNPGM("G29 P2 finished."); @@ -555,7 +555,7 @@ void unified_bed_leveling::G29() { case 4: // Fine Tune (i.e., Edit) the Mesh #if HAS_LCD_MENU - fine_tune_mesh(param.XY_pos, parser.seen('T')); + fine_tune_mesh(param.XY_pos, parser.seen_test('T')); #else SERIAL_ECHOLNPGM("?P4 is only available when an LCD is present."); return; @@ -574,14 +574,14 @@ void unified_bed_leveling::G29() { // Much of the 'What?' command can be eliminated. But until we are fully debugged, it is // good to have the extra information. Soon... we prune this to just a few items // - if (parser.seen('W')) g29_what_command(); + if (parser.seen_test('W')) g29_what_command(); // // When we are fully debugged, this may go away. But there are some valid // use cases for the users. So we can wait and see what to do with it. // - if (parser.seen('K')) // Kompare Current Mesh Data to Specified Stored Mesh + if (parser.seen_test('K')) // Kompare Current Mesh Data to Specified Stored Mesh g29_compare_current_mesh_to_stored_mesh(); #endif // UBL_DEVEL_DEBUGGING @@ -640,7 +640,7 @@ void unified_bed_leveling::G29() { SERIAL_ECHOLNPGM("Done."); } - if (parser.seen('T')) + if (parser.seen_test('T')) display_map(param.T_map_type); LEAVE: @@ -915,7 +915,7 @@ void set_message_with_feedback(PGM_P const msg_P) { if (do_ubl_mesh_map) display_map(param.T_map_type); // Show user where we're probing - if (parser.seen('B')) { + if (parser.seen_test('B')) { SERIAL_ECHOPGM_P(GET_TEXT(MSG_UBL_BC_INSERT)); LCD_MESSAGEPGM(MSG_UBL_BC_INSERT); } @@ -954,7 +954,7 @@ void set_message_with_feedback(PGM_P const msg_P) { * NOTE: Blocks the G-code queue and captures Marlin UI during use. */ void unified_bed_leveling::fine_tune_mesh(const xy_pos_t &pos, const bool do_ubl_mesh_map) { - if (!parser.seen('R')) // fine_tune_mesh() is special. If no repetition count flag is specified + if (!parser.seen_test('R')) // fine_tune_mesh() is special. If no repetition count flag is specified param.R_repetition = 1; // do exactly one mesh location. Otherwise use what the parser decided. #if ENABLED(UBL_MESH_EDIT_MOVES_Z) @@ -1091,7 +1091,7 @@ bool unified_bed_leveling::G29_parse_parameters() { } } - param.V_verbosity = parser.seen('V') ? parser.value_int() : 0; + param.V_verbosity = parser.intval('V'); if (!WITHIN(param.V_verbosity, 0, 4)) { SERIAL_ECHOLNPGM("?(V)erbose level implausible (0-4).\n"); err_flag = true; @@ -1153,15 +1153,15 @@ bool unified_bed_leveling::G29_parse_parameters() { * Leveling is being enabled here with old data, possibly * none. Error handling should disable for safety... */ - if (parser.seen('A')) { - if (parser.seen('D')) { + if (parser.seen_test('A')) { + if (parser.seen_test('D')) { SERIAL_ECHOLNPGM("?Can't activate and deactivate at the same time.\n"); return UBL_ERR; } set_bed_leveling_enabled(true); report_state(); } - else if (parser.seen('D')) { + else if (parser.seen_test('D')) { set_bed_leveling_enabled(false); report_state(); } @@ -1520,7 +1520,7 @@ void unified_bed_leveling::smart_fill_mesh() { SERIAL_ECHOLNPAIR("Tilting mesh point ", point_num, "/", total_points, "\n"); TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points)); - measured_z = probe.probe_at_point(rpos, parser.seen('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, param.V_verbosity); // TODO: Needs error handling + measured_z = probe.probe_at_point(rpos, parser.seen_test('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, param.V_verbosity); // TODO: Needs error handling abort_flag = isnan(measured_z); diff --git a/Marlin/src/feature/encoder_i2c.cpp b/Marlin/src/feature/encoder_i2c.cpp index abaa93f767..b3265b2c59 100644 --- a/Marlin/src/feature/encoder_i2c.cpp +++ b/Marlin/src/feature/encoder_i2c.cpp @@ -819,11 +819,11 @@ int8_t I2CPositionEncodersMgr::parse() { void I2CPositionEncodersMgr::M860() { if (parse()) return; - const bool hasU = parser.seen('U'), hasO = parser.seen('O'); + const bool hasU = parser.seen_test('U'), hasO = parser.seen_test('O'); if (I2CPE_idx == 0xFF) { LOOP_XYZE(i) { - if (!I2CPE_anyaxis || parser.seen(axis_codes[i])) { + if (!I2CPE_anyaxis || parser.seen_test(axis_codes[i])) { const uint8_t idx = idx_from_axis(AxisEnum(i)); if ((int8_t)idx >= 0) report_position(idx, hasU, hasO); } @@ -956,10 +956,10 @@ void I2CPositionEncodersMgr::M864() { return; } else { - if (parser.seen('X')) newAddress = I2CPE_PRESET_ADDR_X; - else if (parser.seen('Y')) newAddress = I2CPE_PRESET_ADDR_Y; - else if (parser.seen('Z')) newAddress = I2CPE_PRESET_ADDR_Z; - else if (parser.seen('E')) newAddress = I2CPE_PRESET_ADDR_E; + if (parser.seen_test('X')) newAddress = I2CPE_PRESET_ADDR_X; + else if (parser.seen_test('Y')) newAddress = I2CPE_PRESET_ADDR_Y; + else if (parser.seen_test('Z')) newAddress = I2CPE_PRESET_ADDR_Z; + else if (parser.seen_test('E')) newAddress = I2CPE_PRESET_ADDR_E; else return; } @@ -1012,7 +1012,7 @@ void I2CPositionEncodersMgr::M865() { void I2CPositionEncodersMgr::M866() { if (parse()) return; - const bool hasR = parser.seen('R'); + const bool hasR = parser.seen_test('R'); if (I2CPE_idx == 0xFF) { LOOP_XYZE(i) { diff --git a/Marlin/src/feature/fwretract.cpp b/Marlin/src/feature/fwretract.cpp index bfcdb8c001..d133d6060c 100644 --- a/Marlin/src/feature/fwretract.cpp +++ b/Marlin/src/feature/fwretract.cpp @@ -212,10 +212,10 @@ void FWRetract::retract(const bool retracting */ void FWRetract::M207() { if (!parser.seen("FSWZ")) return M207_report(); - if (parser.seen('S')) settings.retract_length = parser.value_axis_units(E_AXIS); - if (parser.seen('F')) settings.retract_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); - if (parser.seen('Z')) settings.retract_zraise = parser.value_linear_units(); - if (parser.seen('W')) settings.swap_retract_length = parser.value_axis_units(E_AXIS); + if (parser.seenval('S')) settings.retract_length = parser.value_axis_units(E_AXIS); + if (parser.seenval('F')) settings.retract_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); + if (parser.seenval('Z')) settings.retract_zraise = parser.value_linear_units(); + if (parser.seenval('W')) settings.swap_retract_length = parser.value_axis_units(E_AXIS); } void FWRetract::M207_report(const bool forReplay/*=false*/) { @@ -238,10 +238,10 @@ void FWRetract::M207_report(const bool forReplay/*=false*/) { */ void FWRetract::M208() { if (!parser.seen("FSRW")) return M208_report(); - if (parser.seen('S')) settings.retract_recover_extra = parser.value_axis_units(E_AXIS); - if (parser.seen('F')) settings.retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); + if (parser.seen('S')) settings.retract_recover_extra = parser.value_axis_units(E_AXIS); + if (parser.seen('F')) settings.retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); if (parser.seen('R')) settings.swap_retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); - if (parser.seen('W')) settings.swap_retract_recover_extra = parser.value_axis_units(E_AXIS); + if (parser.seen('W')) settings.swap_retract_recover_extra = parser.value_axis_units(E_AXIS); } void FWRetract::M208_report(const bool forReplay/*=false*/) { diff --git a/Marlin/src/gcode/bedlevel/G26.cpp b/Marlin/src/gcode/bedlevel/G26.cpp index fe039def73..1e70652bdc 100644 --- a/Marlin/src/gcode/bedlevel/G26.cpp +++ b/Marlin/src/gcode/bedlevel/G26.cpp @@ -648,12 +648,12 @@ void GcodeSuite::G26() { #if HAS_LCD_MENU g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1); #else - if (!parser.seen('R')) { + if (parser.seen('R')) + g26_repeats = parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1; + else { SERIAL_ECHOLNPGM("?(R)epeat must be specified when not using an LCD."); return; } - else - g26_repeats = parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1; #endif if (g26_repeats < 1) { SERIAL_ECHOLNPGM("?(R)epeat value not plausible; must be at least 1."); @@ -671,7 +671,7 @@ void GcodeSuite::G26() { /** * Wait until all parameters are verified before altering the state! */ - set_bed_leveling_enabled(!parser.seen('D')); + set_bed_leveling_enabled(!parser.seen_test('D')); do_z_clearance(Z_CLEARANCE_BETWEEN_PROBES); diff --git a/Marlin/src/gcode/bedlevel/M420.cpp b/Marlin/src/gcode/bedlevel/M420.cpp index e42a590265..703e73b5a4 100644 --- a/Marlin/src/gcode/bedlevel/M420.cpp +++ b/Marlin/src/gcode/bedlevel/M420.cpp @@ -133,7 +133,7 @@ void GcodeSuite::M420() { #endif // AUTO_BED_LEVELING_UBL - const bool seenV = parser.seen('V'); + const bool seenV = parser.seen_test('V'); #if HAS_MESH diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index 3bd96ef495..a8c3f45cdc 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -223,7 +223,7 @@ G29_TYPE GcodeSuite::G29() { reset_stepper_timeout(); - const bool seenQ = EITHER(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) && parser.seen('Q'); + const bool seenQ = EITHER(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) && parser.seen_test('Q'); // G29 Q is also available if debugging #if ENABLED(DEBUG_LEVELING_FEATURE) @@ -235,7 +235,7 @@ G29_TYPE GcodeSuite::G29() { if (DISABLED(PROBE_MANUALLY) && seenQ) G29_RETURN(false); #endif - const bool seenA = TERN0(PROBE_MANUALLY, parser.seen('A')), + const bool seenA = TERN0(PROBE_MANUALLY, parser.seen_test('A')), no_action = seenA || seenQ, faux = ENABLED(DEBUG_LEVELING_FEATURE) && DISABLED(PROBE_MANUALLY) ? parser.boolval('C') : no_action; @@ -245,7 +245,7 @@ G29_TYPE GcodeSuite::G29() { } // Send 'N' to force homing before G29 (internal only) - if (parser.seen('N')) + if (parser.seen_test('N')) process_subcommands_now_P(TERN(G28_L0_ENSURES_LEVELING_OFF, PSTR("G28L0"), G28_STR)); // Don't allow auto-leveling without homing first @@ -275,7 +275,7 @@ G29_TYPE GcodeSuite::G29() { #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - const bool seen_w = parser.seen('W'); + const bool seen_w = parser.seen_test('W'); if (seen_w) { if (!leveling_is_valid()) { SERIAL_ERROR_MSG("No bilinear grid"); @@ -308,7 +308,7 @@ G29_TYPE GcodeSuite::G29() { if (abl.reenable) report_current_position(); } G29_RETURN(false); - } // parser.seen('W') + } // parser.seen_test('W') #else @@ -317,7 +317,7 @@ G29_TYPE GcodeSuite::G29() { #endif // Jettison bed leveling data - if (!seen_w && parser.seen('J')) { + if (!seen_w && parser.seen_test('J')) { reset_bed_level(); G29_RETURN(false); } diff --git a/Marlin/src/gcode/bedlevel/mbl/G29.cpp b/Marlin/src/gcode/bedlevel/mbl/G29.cpp index afc6aad32c..07721330ba 100644 --- a/Marlin/src/gcode/bedlevel/mbl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/mbl/G29.cpp @@ -87,7 +87,7 @@ void GcodeSuite::G29() { mbl.reset(); mbl_probe_index = 0; if (!ui.wait_for_move) { - queue.inject_P(parser.seen('N') ? PSTR("G28" TERN(G28_L0_ENSURES_LEVELING_OFF, "L0", "") "\nG29S2") : PSTR("G29S2")); + queue.inject_P(parser.seen_test('N') ? PSTR("G28" TERN(G28_L0_ENSURES_LEVELING_OFF, "L0", "") "\nG29S2") : PSTR("G29S2")); return; } state = MeshNext; diff --git a/Marlin/src/gcode/bedlevel/ubl/M421.cpp b/Marlin/src/gcode/bedlevel/ubl/M421.cpp index 45c203aaca..f1e1b76126 100644 --- a/Marlin/src/gcode/bedlevel/ubl/M421.cpp +++ b/Marlin/src/gcode/bedlevel/ubl/M421.cpp @@ -21,7 +21,7 @@ */ /** - * unified.cpp - Unified Bed Leveling + * M421.cpp - Unified Bed Leveling */ #include "../../../inc/MarlinConfig.h" @@ -39,31 +39,34 @@ * M421: Set a single Mesh Bed Leveling Z coordinate * * Usage: - * M421 I J Z - * M421 I J Q - * M421 I J N - * M421 C Z - * M421 C Q + * M421 I J Z : Set the Mesh Point IJ to the Z value + * M421 I J Q : Add the Q value to the Mesh Point IJ + * M421 I J N : Set the Mesh Point IJ to NAN (not set) + * M421 C Z : Set the closest Mesh Point to the Z value + * M421 C Q : Add the Q value to the closest Mesh Point */ void GcodeSuite::M421() { xy_int8_t ij = { int8_t(parser.intval('I', -1)), int8_t(parser.intval('J', -1)) }; const bool hasI = ij.x >= 0, hasJ = ij.y >= 0, - hasC = parser.seen('C'), - hasN = parser.seen('N'), + hasC = parser.seen_test('C'), + hasN = parser.seen_test('N'), hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q'); if (hasC) ij = ubl.find_closest_mesh_point_of_type(CLOSEST, current_position); + // Test for bad parameter combinations if (int(hasC) + int(hasI && hasJ) != 1 || !(hasZ || hasQ || hasN)) SERIAL_ERROR_MSG(STR_ERR_M421_PARAMETERS); + + // Test for I J out of range else if (!WITHIN(ij.x, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(ij.y, 0, GRID_MAX_POINTS_Y - 1)) SERIAL_ERROR_MSG(STR_ERR_MESH_XY); else { - float &zval = ubl.z_values[ij.x][ij.y]; - zval = hasN ? NAN : parser.value_linear_units() + (hasQ ? zval : 0); - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ij.x, ij.y, zval)); + float &zval = ubl.z_values[ij.x][ij.y]; // Altering this Mesh Point + zval = hasN ? NAN : parser.value_linear_units() + (hasQ ? zval : 0); // N=NAN, Z=NEWVAL, or Q=ADDVAL + TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ij.x, ij.y, zval)); // Ping ExtUI in case it's showing the mesh } } diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index 10e094cba7..92bbb8e6c5 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -219,7 +219,7 @@ void GcodeSuite::G28() { #endif #if ENABLED(MARLIN_DEV_MODE) - if (parser.seen('S')) { + if (parser.seen_test('S')) { LOOP_XYZ(a) set_axis_is_at_home((AxisEnum)a); sync_plan_position(); SERIAL_ECHOLNPGM("Simulated Homing"); @@ -321,10 +321,10 @@ void GcodeSuite::G28() { #else - const bool homeZ = parser.seen('Z'), + const bool homeZ = parser.seen_test('Z'), needX = homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(X_AXIS))), needY = homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(Y_AXIS))), - homeX = needX || parser.seen('X'), homeY = needY || parser.seen('Y'), + homeX = needX || parser.seen_test('X'), homeY = needY || parser.seen_test('Y'), home_all = homeX == homeY && homeX == homeZ, // All or None doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ; diff --git a/Marlin/src/gcode/calibrate/G33.cpp b/Marlin/src/gcode/calibrate/G33.cpp index d60099a330..a8de519335 100644 --- a/Marlin/src/gcode/calibrate/G33.cpp +++ b/Marlin/src/gcode/calibrate/G33.cpp @@ -395,7 +395,7 @@ void GcodeSuite::G33() { return; } - const bool towers_set = !parser.seen('T'); + const bool towers_set = !parser.seen_test('T'); const float calibration_precision = parser.floatval('C', 0.0f); if (calibration_precision < 0) { @@ -415,7 +415,7 @@ void GcodeSuite::G33() { return; } - const bool stow_after_each = parser.seen('E'); + const bool stow_after_each = parser.seen_test('E'); const bool _0p_calibration = probe_points == 0, _1p_calibration = probe_points == 1 || probe_points == -1, diff --git a/Marlin/src/gcode/feature/pause/M125.cpp b/Marlin/src/gcode/feature/pause/M125.cpp index 3e495eb9d3..351ef01f34 100644 --- a/Marlin/src/gcode/feature/pause/M125.cpp +++ b/Marlin/src/gcode/feature/pause/M125.cpp @@ -56,7 +56,7 @@ */ void GcodeSuite::M125() { // Initial retract before move to filament change position - const float retract = -ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS) : (PAUSE_PARK_RETRACT_LENGTH)); + const float retract = -ABS(parser.axisunitsval('L', E_AXIS, PAUSE_PARK_RETRACT_LENGTH)); xyz_pos_t park_point = NOZZLE_PARK_POINT; diff --git a/Marlin/src/gcode/feature/pause/M600.cpp b/Marlin/src/gcode/feature/pause/M600.cpp index 6cab3ad352..2daa7d999a 100644 --- a/Marlin/src/gcode/feature/pause/M600.cpp +++ b/Marlin/src/gcode/feature/pause/M600.cpp @@ -81,8 +81,8 @@ void GcodeSuite::M600() { #if ENABLED(DUAL_X_CARRIAGE) int8_t DXC_ext = target_extruder; - if (!parser.seen('T')) { // If no tool index is specified, M600 was (probably) sent in response to filament runout. - // In this case, for duplicating modes set DXC_ext to the extruder that ran out. + if (!parser.seen_test('T')) { // If no tool index is specified, M600 was (probably) sent in response to filament runout. + // In this case, for duplicating modes set DXC_ext to the extruder that ran out. #if MULTI_FILAMENT_SENSOR if (idex_is_duplicating()) DXC_ext = (READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT2_STATE) ? 1 : 0; @@ -110,7 +110,7 @@ void GcodeSuite::M600() { #endif // Initial retract before move to filament change position - const float retract = -ABS(parser.seen('E') ? parser.value_axis_units(E_AXIS) : (PAUSE_PARK_RETRACT_LENGTH)); + const float retract = -ABS(parser.axisunitsval('E', E_AXIS, PAUSE_PARK_RETRACT_LENGTH)); xyz_pos_t park_point NOZZLE_PARK_POINT; @@ -132,15 +132,11 @@ void GcodeSuite::M600() { fast_load_length = 0.0f; #else // Unload filament - const float unload_length = -ABS(parser.seen('U') ? parser.value_axis_units(E_AXIS) - : fc_settings[active_extruder].unload_length); - + const float unload_length = -ABS(parser.axisunitsval('U', E_AXIS, fc_settings[active_extruder].unload_length)); // Slow load filament constexpr float slow_load_length = FILAMENT_CHANGE_SLOW_LOAD_LENGTH; - // Fast load filament - const float fast_load_length = ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS) - : fc_settings[active_extruder].load_length); + const float fast_load_length = ABS(parser.axisunitsval('L', E_AXIS, fc_settings[active_extruder].load_length)); #endif const int beep_count = parser.intval('B', -1 diff --git a/Marlin/src/gcode/feature/powerloss/M1000.cpp b/Marlin/src/gcode/feature/powerloss/M1000.cpp index a31b7732f4..ea92dc66b3 100644 --- a/Marlin/src/gcode/feature/powerloss/M1000.cpp +++ b/Marlin/src/gcode/feature/powerloss/M1000.cpp @@ -59,7 +59,7 @@ inline void plr_error(PGM_P const prefix) { void GcodeSuite::M1000() { if (recovery.valid()) { - if (parser.seen('S')) { + if (parser.seen_test('S')) { #if HAS_LCD_MENU ui.goto_screen(menu_job_recovery); #elif ENABLED(DWIN_CREALITY_LCD) @@ -70,7 +70,7 @@ void GcodeSuite::M1000() { SERIAL_ECHO_MSG("Resume requires LCD."); #endif } - else if (parser.seen('C')) { + else if (parser.seen_test('C')) { #if HAS_LCD_MENU lcd_power_loss_recovery_cancel(); #else diff --git a/Marlin/src/gcode/feature/powerloss/M413.cpp b/Marlin/src/gcode/feature/powerloss/M413.cpp index e6e3ac3b3c..18aeb507b1 100644 --- a/Marlin/src/gcode/feature/powerloss/M413.cpp +++ b/Marlin/src/gcode/feature/powerloss/M413.cpp @@ -48,14 +48,14 @@ void GcodeSuite::M413() { #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) if (parser.seen("RL")) recovery.load(); - if (parser.seen('W')) recovery.save(true); - if (parser.seen('P')) recovery.purge(); - if (parser.seen('D')) recovery.debug(PSTR("M413")); + if (parser.seen_test('W')) recovery.save(true); + if (parser.seen_test('P')) recovery.purge(); + if (parser.seen_test('D')) recovery.debug(PSTR("M413")); #if PIN_EXISTS(POWER_LOSS) - if (parser.seen('O')) recovery._outage(); + if (parser.seen_test('O')) recovery._outage(); #endif - if (parser.seen('E')) SERIAL_ECHOPGM_P(recovery.exists() ? PSTR("PLR Exists\n") : PSTR("No PLR\n")); - if (parser.seen('V')) SERIAL_ECHOPGM_P(recovery.valid() ? PSTR("Valid\n") : PSTR("Invalid\n")); + if (parser.seen_test('E')) SERIAL_ECHOPGM_P(recovery.exists() ? PSTR("PLR Exists\n") : PSTR("No PLR\n")); + if (parser.seen_test('V')) SERIAL_ECHOPGM_P(recovery.valid() ? PSTR("Valid\n") : PSTR("Invalid\n")); #endif } diff --git a/Marlin/src/gcode/feature/runout/M412.cpp b/Marlin/src/gcode/feature/runout/M412.cpp index 130f9c83e3..540a160623 100644 --- a/Marlin/src/gcode/feature/runout/M412.cpp +++ b/Marlin/src/gcode/feature/runout/M412.cpp @@ -44,7 +44,7 @@ void GcodeSuite::M412() { #if ENABLED(HOST_ACTION_COMMANDS) if (parser.seen('H')) runout.host_handling = parser.value_bool(); #endif - const bool seenR = parser.seen('R'), seenS = parser.seen('S'); + const bool seenR = parser.seen_test('R'), seenS = parser.seen('S'); if (seenR || seenS) runout.reset(); if (seenS) runout.enabled = parser.value_bool(); #if HAS_FILAMENT_RUNOUT_DISTANCE diff --git a/Marlin/src/gcode/feature/trinamic/M122.cpp b/Marlin/src/gcode/feature/trinamic/M122.cpp index 46e4365f38..429638665f 100644 --- a/Marlin/src/gcode/feature/trinamic/M122.cpp +++ b/Marlin/src/gcode/feature/trinamic/M122.cpp @@ -48,7 +48,7 @@ void GcodeSuite::M122() { tmc_set_report_interval(interval); #endif - if (parser.seen('V')) + if (parser.seen_test('V')) tmc_get_registers(print_axis.x, print_axis.y, print_axis.z, print_axis.e); else tmc_report_all(print_axis.x, print_axis.y, print_axis.z, print_axis.e); diff --git a/Marlin/src/gcode/gcode_d.cpp b/Marlin/src/gcode/gcode_d.cpp index a8a6bdfc3d..52a273964a 100644 --- a/Marlin/src/gcode/gcode_d.cpp +++ b/Marlin/src/gcode/gcode_d.cpp @@ -52,7 +52,7 @@ break; case 10: - kill(PSTR("D10"), PSTR("KILL TEST"), parser.seen('P')); + kill(PSTR("D10"), PSTR("KILL TEST"), parser.seen_test('P')); break; case 1: { diff --git a/Marlin/src/gcode/host/M114.cpp b/Marlin/src/gcode/host/M114.cpp index dd62f0ad2e..e5dc90fb30 100644 --- a/Marlin/src/gcode/host/M114.cpp +++ b/Marlin/src/gcode/host/M114.cpp @@ -193,7 +193,7 @@ void GcodeSuite::M114() { #if ENABLED(M114_DETAIL) - if (parser.seen('D')) { + if (parser.seen_test('D')) { #if DISABLED(M114_LEGACY) planner.synchronize(); #endif @@ -201,14 +201,14 @@ void GcodeSuite::M114() { report_current_position_detail(); return; } - if (parser.seen('E')) { + if (parser.seen_test('E')) { SERIAL_ECHOLNPAIR("Count E:", stepper.position(E_AXIS)); return; } #endif #if ENABLED(M114_REALTIME) - if (parser.seen('R')) { report_real_position(); return; } + if (parser.seen_test('R')) { report_real_position(); return; } #endif TERN_(M114_LEGACY, planner.synchronize()); diff --git a/Marlin/src/gcode/motion/G0_G1.cpp b/Marlin/src/gcode/motion/G0_G1.cpp index 64c07d1d89..089e00ab95 100644 --- a/Marlin/src/gcode/motion/G0_G1.cpp +++ b/Marlin/src/gcode/motion/G0_G1.cpp @@ -49,9 +49,9 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) { if (IsRunning() #if ENABLED(NO_MOTION_BEFORE_HOMING) && !homing_needed_error( - (parser.seen('X') ? _BV(X_AXIS) : 0) - | (parser.seen('Y') ? _BV(Y_AXIS) : 0) - | (parser.seen('Z') ? _BV(Z_AXIS) : 0) ) + (parser.seen_test('X') ? _BV(X_AXIS) : 0) + | (parser.seen_test('Y') ? _BV(Y_AXIS) : 0) + | (parser.seen_test('Z') ? _BV(Z_AXIS) : 0) ) #endif ) { TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_RUNNING)); diff --git a/Marlin/src/gcode/motion/M290.cpp b/Marlin/src/gcode/motion/M290.cpp index 7dd89a6fac..7cfab8d2db 100644 --- a/Marlin/src/gcode/motion/M290.cpp +++ b/Marlin/src/gcode/motion/M290.cpp @@ -74,7 +74,7 @@ void GcodeSuite::M290() { const float offs = constrain(parser.value_axis_units((AxisEnum)a), -2, 2); babystep.add_mm((AxisEnum)a, offs); #if ENABLED(BABYSTEP_ZPROBE_OFFSET) - if (a == Z_AXIS && (!parser.seen('P') || parser.value_bool())) mod_probe_offset(offs); + if (a == Z_AXIS && parser.boolval('P', true)) mod_probe_offset(offs); #endif } #else diff --git a/Marlin/src/gcode/parser.h b/Marlin/src/gcode/parser.h index b3625ec05e..3aec17554b 100644 --- a/Marlin/src/gcode/parser.h +++ b/Marlin/src/gcode/parser.h @@ -408,6 +408,8 @@ public: static inline int32_t longval(const char c, const int32_t dval=0) { return seenval(c) ? value_long() : dval; } static inline uint32_t ulongval(const char c, const uint32_t dval=0) { return seenval(c) ? value_ulong() : dval; } static inline float linearval(const char c, const float dval=0) { return seenval(c) ? value_linear_units() : dval; } + static inline float axisunitsval(const char c, const AxisEnum a, const float dval=0) + { return seenval(c) ? value_axis_units(a) : dval; } static inline celsius_t celsiusval(const char c, const float dval=0) { return seenval(c) ? value_celsius() : dval; } #if ENABLED(MARLIN_DEV_MODE) diff --git a/Marlin/src/gcode/sd/M27.cpp b/Marlin/src/gcode/sd/M27.cpp index f6e48d4ae8..88238190e2 100644 --- a/Marlin/src/gcode/sd/M27.cpp +++ b/Marlin/src/gcode/sd/M27.cpp @@ -33,7 +33,7 @@ * OR, with 'C' get the current filename. */ void GcodeSuite::M27() { - if (parser.seen('C')) { + if (parser.seen_test('C')) { SERIAL_ECHOPGM("Current file: "); card.printSelectedFilename(); return; diff --git a/Marlin/src/gcode/sd/M808.cpp b/Marlin/src/gcode/sd/M808.cpp index 0d11b16f8a..548683430c 100644 --- a/Marlin/src/gcode/sd/M808.cpp +++ b/Marlin/src/gcode/sd/M808.cpp @@ -44,7 +44,7 @@ void GcodeSuite::M808() { // Allowed to go into the queue for logging purposes. // M808 K sent from the host to cancel all loops - if (parser.seen('K')) repeat.cancel(); + if (parser.seen_test('K')) repeat.cancel(); } diff --git a/Marlin/src/gcode/temp/M106_M107.cpp b/Marlin/src/gcode/temp/M106_M107.cpp index 3ce08aafb6..73dc82b8df 100644 --- a/Marlin/src/gcode/temp/M106_M107.cpp +++ b/Marlin/src/gcode/temp/M106_M107.cpp @@ -68,7 +68,7 @@ void GcodeSuite::M106() { if (t > 0) return thermalManager.set_temp_fan_speed(pfan, t); #endif - const uint16_t dspeed = parser.seen('A') ? thermalManager.fan_speed[active_extruder] : 255; + const uint16_t dspeed = parser.seen_test('A') ? thermalManager.fan_speed[active_extruder] : 255; uint16_t speed = dspeed; diff --git a/Marlin/src/gcode/temp/M303.cpp b/Marlin/src/gcode/temp/M303.cpp index e49381cdf6..ad3afe6e46 100644 --- a/Marlin/src/gcode/temp/M303.cpp +++ b/Marlin/src/gcode/temp/M303.cpp @@ -47,7 +47,7 @@ void GcodeSuite::M303() { #if ANY(PID_DEBUG, PID_BED_DEBUG, PID_CHAMBER_DEBUG) - if (parser.seen('D')) { + if (parser.seen_test('D')) { thermalManager.pid_debug_flag ^= true; SERIAL_ECHO_START(); SERIAL_ECHOPGM("PID Debug "); From b12d0d06ebaac1db5a87750dd96b9dcbaf2ecf72 Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Sun, 9 May 2021 01:52:53 -0700 Subject: [PATCH 27/67] Unify BTT Motor Expansion Options (#21823) --- Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h | 2 +- Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h | 27 +++--- .../pins/stm32f4/pins_BTT_SKR_PRO_common.h | 72 +++++++++------ .../pins/stm32f4/pins_BTT_SKR_V2_0_common.h | 89 ++++++++++++------- 4 files changed, 114 insertions(+), 76 deletions(-) diff --git a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h index aa94bc935d..ba60db472e 100644 --- a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h +++ b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h @@ -279,7 +279,7 @@ #undef SPEAKER #endif -#elif HAS_WIRED_LCD && !HAS_BTT_EXP_MOT +#elif HAS_WIRED_LCD && !BTT_MOTOR_EXPANSION #if ENABLED(ANET_FULL_GRAPHICS_LCD_ALT_WIRING) #error "CAUTION! ANET_FULL_GRAPHICS_LCD_ALT_WIRING requires wiring modifications. See 'pins_BTT_SKR_V1_4.h' for details. Comment out this line to continue." diff --git a/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h b/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h index eadb91a8b3..01f2303a35 100644 --- a/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h +++ b/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h @@ -23,11 +23,11 @@ #include "env_validate.h" -// If you have the Big tree tech driver expansion module, enable HAS_BTT_EXP_MOT +// If you have the BigTreeTech driver expansion module, enable BTT_MOTOR_EXPANSION // https://github.com/bigtreetech/BTT-Expansion-module/tree/master/BTT%20EXP-MOT -//#define HAS_BTT_EXP_MOT 1 +//#define BTT_MOTOR_EXPANSION -#if BOTH(HAS_WIRED_LCD, HAS_BTT_EXP_MOT) +#if BOTH(HAS_WIRED_LCD, BTT_MOTOR_EXPANSION) #if EITHER(CR10_STOCKDISPLAY, ENDER2_STOCKDISPLAY) #define EXP_MOT_USE_EXP2_ONLY 1 #else @@ -138,16 +138,15 @@ #error "No custom SD drive cable defined for this board." #endif -#if HAS_BTT_EXP_MOT - - /** _____ _____ - * NC | · · | GND NC | · · | GND - * NC | · · | 1.31 (M1EN) (M2EN) 1.23 | · · | 1.22 (M3EN) - * (M1STP) 0.18 | · · 3.25 (M1DIR) (M1RX) 1.21 | · · 1.20 (M1DIAG) - * (M2DIR) 0.16 | · · | 3.26 (M2STP) (M2RX) 1.19 | · · | 1.18 (M2DIAG) - * (M3DIR) 0.15 | · · | 0.17 (M3STP) (M3RX) 0.28 | · · | 1.30 (M3DIAG) - * ----- ----- - * EXP2 EXP1 +#if ENABLED(BTT_MOTOR_EXPANSION) + /** _____ _____ + * NC | . . | GND NC | . . | GND + * NC | . . | M1EN M2EN | . . | M3EN + * M1STP | . . M1DIR M1RX | . . M1DIAG + * M2DIR | . . | M2STP M2RX | . . | M2DIAG + * M3DIR | . . | M3STP M3RX | . . | M3DIAG + * ----- ----- + * EXP2 EXP1 * * NB In EXP_MOT_USE_EXP2_ONLY mode EXP1 is not used and M2EN and M3EN need to be jumpered to M1EN */ @@ -195,4 +194,4 @@ #define E4_ENABLE_PIN EXP2_04_PIN #endif -#endif // HAS_BTT_EXP_MOT +#endif // BTT_MOTOR_EXPANSION diff --git a/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h index 01ba3d72f6..67907affa7 100644 --- a/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h +++ b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h @@ -23,11 +23,16 @@ #include "env_validate.h" -// BigTreeTech driver expansion module https://bit.ly/3ptRRoj +// If you have the BigTreeTech driver expansion module, enable BTT_MOTOR_EXPANSION +// https://github.com/bigtreetech/BTT-Expansion-module/tree/master/BTT%20EXP-MOT //#define BTT_MOTOR_EXPANSION #if BOTH(HAS_WIRED_LCD, BTT_MOTOR_EXPANSION) - #error "It's not possible to have both LCD and motor expansion module on EXP1/EXP2." + #if EITHER(CR10_STOCKDISPLAY, ENDER2_STOCKDISPLAY) + #define EXP_MOT_USE_EXP2_ONLY 1 + #else + #error "You can't use both an LCD and a Motor Expansion Module on EXP1/EXP2 at the same time." + #endif #endif // Use one of these or SDCard-based Emulation will be used @@ -311,48 +316,59 @@ #endif #if ENABLED(BTT_MOTOR_EXPANSION) - /** - * _____ _____ - * NC | · · | GND NC | · · | GND - * NC | · · | PF12 (M1EN) (M2EN) PG7 | · · | PG6 (M3EN) - * (M1STP) PB15 | · · PF11 (M1DIR) (M1RX) PG3 | · · PG2 (M1DIAG) - * (M2DIR) PB12 | · · | PG10 (M2STP) (M2RX) PD10 | · · | PD11 (M2DIAG) - * (M3DIR) PB13 | · · | PB14 (M3STP) (M3RX) PA8 | · · | PG4 (M3DIAG) - * ----- ----- - * EXP2 EXP1 + /** _____ _____ + * NC | . . | GND NC | . . | GND + * NC | . . | M1EN M2EN | . . | M3EN + * M1STP | . . M1DIR M1RX | . . M1DIAG + * M2DIR | . . | M2STP M2RX | . . | M2DIAG + * M3DIR | . . | M3STP M3RX | . . | M3DIAG + * ----- ----- + * EXP2 EXP1 + * + * NB In EXP_MOT_USE_EXP2_ONLY mode EXP1 is not used and M2EN and M3EN need to be jumpered to M1EN */ // M1 on Driver Expansion Module #define E3_STEP_PIN EXP2_05_PIN #define E3_DIR_PIN EXP2_06_PIN #define E3_ENABLE_PIN EXP2_04_PIN - #define E3_DIAG_PIN EXP1_06_PIN - #define E3_CS_PIN EXP1_05_PIN - #if HAS_TMC_UART - #define E3_SERIAL_TX_PIN EXP1_05_PIN - #define E3_SERIAL_RX_PIN EXP1_05_PIN + #if !EXP_MOT_USE_EXP2_ONLY + #define E3_DIAG_PIN EXP1_06_PIN + #define E3_CS_PIN EXP1_05_PIN + #if HAS_TMC_UART + #define E3_SERIAL_TX_PIN EXP1_05_PIN + #define E3_SERIAL_RX_PIN EXP1_05_PIN + #endif #endif // M2 on Driver Expansion Module #define E4_STEP_PIN EXP2_08_PIN #define E4_DIR_PIN EXP2_07_PIN - #define E4_ENABLE_PIN EXP1_03_PIN - #define E4_DIAG_PIN EXP1_08_PIN - #define E4_CS_PIN EXP1_07_PIN - #if HAS_TMC_UART - #define E4_SERIAL_TX_PIN EXP1_07_PIN - #define E4_SERIAL_RX_PIN EXP1_07_PIN + #if !EXP_MOT_USE_EXP2_ONLY + #define E4_ENABLE_PIN EXP1_03_PIN + #define E4_DIAG_PIN EXP1_08_PIN + #define E4_CS_PIN EXP1_07_PIN + #if HAS_TMC_UART + #define E4_SERIAL_TX_PIN EXP1_07_PIN + #define E4_SERIAL_RX_PIN EXP1_07_PIN + #endif + #else + #define E4_ENABLE_PIN EXP2_04_PIN #endif // M3 on Driver Expansion Module #define E5_STEP_PIN EXP2_10_PIN #define E5_DIR_PIN EXP2_09_PIN - #define E5_ENABLE_PIN EXP1_04_PIN - #define E5_DIAG_PIN EXP1_10_PIN - #define E5_CS_PIN EXP1_09_PIN - #if HAS_TMC_UART - #define E5_SERIAL_TX_PIN EXP1_09_PIN - #define E5_SERIAL_RX_PIN EXP1_09_PIN + #if !EXP_MOT_USE_EXP2_ONLY + #define E5_ENABLE_PIN EXP1_04_PIN + #define E5_DIAG_PIN EXP1_10_PIN + #define E5_CS_PIN EXP1_09_PIN + #if HAS_TMC_UART + #define E5_SERIAL_TX_PIN EXP1_09_PIN + #define E5_SERIAL_RX_PIN EXP1_09_PIN + #endif + #else + #define E5_ENABLE_PIN EXP2_04_PIN #endif #endif // BTT_MOTOR_EXPANSION diff --git a/Marlin/src/pins/stm32f4/pins_BTT_SKR_V2_0_common.h b/Marlin/src/pins/stm32f4/pins_BTT_SKR_V2_0_common.h index 14cc047649..a69041e2d4 100644 --- a/Marlin/src/pins/stm32f4/pins_BTT_SKR_V2_0_common.h +++ b/Marlin/src/pins/stm32f4/pins_BTT_SKR_V2_0_common.h @@ -23,6 +23,18 @@ #include "env_validate.h" +// If you have the BigTreeTech driver expansion module, enable BTT_MOTOR_EXPANSION +// https://github.com/bigtreetech/BTT-Expansion-module/tree/master/BTT%20EXP-MOT +//#define BTT_MOTOR_EXPANSION + +#if BOTH(HAS_WIRED_LCD, BTT_MOTOR_EXPANSION) + #if EITHER(CR10_STOCKDISPLAY, ENDER2_STOCKDISPLAY) + #define EXP_MOT_USE_EXP2_ONLY 1 + #else + #error "You can't use both an LCD and a Motor Expansion Module on EXP1/EXP2 at the same time." + #endif +#endif + // Use one of these or SDCard-based Emulation will be used #if NO_EEPROM_SELECTED //#define SRAM_EEPROM_EMULATION // Use BackSRAM-based EEPROM emulation @@ -349,48 +361,59 @@ #endif #if ENABLED(BTT_MOTOR_EXPANSION) - /** - * _____ _____ - * NC | · · | GND NC | · · | GND - * NC | · · | PF12 (M1EN) (M2EN) PG7 | · · | PG6 (M3EN) - * (M1STP) PB15 | · · PF11 (M1DIR) (M1RX) PG3 | · · PG2 (M1DIAG) - * (M2DIR) PB12 | · · | PG10 (M2STP) (M2RX) PD10 | · · | PD11 (M2DIAG) - * (M3DIR) PB13 | · · | PB14 (M3STP) (M3RX) PA8 | · · | PG4 (M3DIAG) - * ----- ----- - * EXP2 EXP1 + /** _____ _____ + * NC | . . | GND NC | . . | GND + * NC | . . | M1EN M2EN | . . | M3EN + * M1STP | . . M1DIR M1RX | . . M1DIAG + * M2DIR | . . | M2STP M2RX | . . | M2DIAG + * M3DIR | . . | M3STP M3RX | . . | M3DIAG + * ----- ----- + * EXP2 EXP1 + * + * NB In EXP_MOT_USE_EXP2_ONLY mode EXP1 is not used and M2EN and M3EN need to be jumpered to M1EN */ // M1 on Driver Expansion Module - #define E3_STEP_PIN EXP2_05_PIN - #define E3_DIR_PIN EXP2_06_PIN - #define E3_ENABLE_PIN EXP2_04_PIN - #define E3_DIAG_PIN EXP1_06_PIN - #define E3_CS_PIN EXP1_05_PIN - #if HAS_TMC_UART - #define E3_SERIAL_TX_PIN EXP1_05_PIN - #define E3_SERIAL_RX_PIN EXP1_05_PIN + #define E2_STEP_PIN EXP2_05_PIN + #define E2_DIR_PIN EXP2_06_PIN + #define E2_ENABLE_PIN EXP2_04_PIN + #if !EXP_MOT_USE_EXP2_ONLY + #define E2_DIAG_PIN EXP1_06_PIN + #define E2_CS_PIN EXP1_05_PIN + #if HAS_TMC_UART + #define E2_SERIAL_TX_PIN EXP1_05_PIN + #define E2_SERIAL_RX_PIN EXP1_05_PIN + #endif #endif // M2 on Driver Expansion Module - #define E4_STEP_PIN EXP2_08_PIN - #define E4_DIR_PIN EXP2_07_PIN - #define E4_ENABLE_PIN EXP1_03_PIN - #define E4_DIAG_PIN EXP1_08_PIN - #define E4_CS_PIN EXP1_07_PIN - #if HAS_TMC_UART - #define E4_SERIAL_TX_PIN EXP1_07_PIN - #define E4_SERIAL_RX_PIN EXP1_07_PIN + #define E3_STEP_PIN EXP2_08_PIN + #define E3_DIR_PIN EXP2_07_PIN + #if !EXP_MOT_USE_EXP2_ONLY + #define E3_ENABLE_PIN EXP1_03_PIN + #define E3_DIAG_PIN EXP1_08_PIN + #define E3_CS_PIN EXP1_07_PIN + #if HAS_TMC_UART + #define E3_SERIAL_TX_PIN EXP1_07_PIN + #define E3_SERIAL_RX_PIN EXP1_07_PIN + #endif + #else + #define E3_ENABLE_PIN EXP2_04_PIN #endif // M3 on Driver Expansion Module - #define E5_STEP_PIN EXP2_10_PIN - #define E5_DIR_PIN EXP2_09_PIN - #define E5_ENABLE_PIN EXP1_04_PIN - #define E5_DIAG_PIN EXP1_10_PIN - #define E5_CS_PIN EXP1_09_PIN - #if HAS_TMC_UART - #define E5_SERIAL_TX_PIN EXP1_09_PIN - #define E5_SERIAL_RX_PIN EXP1_09_PIN + #define E4_STEP_PIN EXP2_10_PIN + #define E4_DIR_PIN EXP2_09_PIN + #if !EXP_MOT_USE_EXP2_ONLY + #define E4_ENABLE_PIN EXP1_04_PIN + #define E4_DIAG_PIN EXP1_10_PIN + #define E4_CS_PIN EXP1_09_PIN + #if HAS_TMC_UART + #define E4_SERIAL_TX_PIN EXP1_09_PIN + #define E4_SERIAL_RX_PIN EXP1_09_PIN + #endif + #else + #define E4_ENABLE_PIN EXP2_04_PIN #endif #endif // BTT_MOTOR_EXPANSION From fff5e9ba4a45bbb9c4c99da9b2c5998548f925a7 Mon Sep 17 00:00:00 2001 From: Giuliano Zaro <3684609+GMagician@users.noreply.github.com> Date: Sun, 9 May 2021 22:58:36 +0200 Subject: [PATCH 28/67] Fix insane mmu2 timeout (#21855) * Fix insane mmu2 timeout Fix insane timeout value. Now match original Prusa firmware. * Update mmu2.cpp Co-authored-by: Luu Lac <45380455+shitcreek@users.noreply.github.com> --- Marlin/src/feature/mmu/mmu2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/feature/mmu/mmu2.cpp b/Marlin/src/feature/mmu/mmu2.cpp index c1c34f8eee..8a4f5ae071 100644 --- a/Marlin/src/feature/mmu/mmu2.cpp +++ b/Marlin/src/feature/mmu/mmu2.cpp @@ -159,7 +159,7 @@ void MMU2::mmu_loop() { MMU2_COMMAND("S1"); // Read Version state = -2; } - else if (millis() > 3000000) { + else if (millis() > 30000) { // 30sec after reset disable MMU SERIAL_ECHOLNPGM("MMU not responding - DISABLED"); state = 0; } From 4a7f5603de04f89aeb47cd68803b810517136acf Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Mon, 10 May 2021 01:00:29 +0000 Subject: [PATCH 29/67] [cron] Bump distribution date (2021-05-10) --- Marlin/src/inc/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 9991da493f..ad4f39ab70 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2021-05-09" + #define STRING_DISTRIBUTION_DATE "2021-05-10" #endif /** From 8e56f9366de1b0d78600064aca3f905b4d1d7300 Mon Sep 17 00:00:00 2001 From: tobuh <32395668+tobuh@users.noreply.github.com> Date: Mon, 10 May 2021 14:24:35 +0200 Subject: [PATCH 30/67] Fix and improve Power-Loss Recovery (#21779) Co-authored-by: Scott Lahteine --- Marlin/src/feature/pause.cpp | 17 +- Marlin/src/feature/powerloss.cpp | 172 ++++++++++++------ Marlin/src/feature/powerloss.h | 3 +- Marlin/src/gcode/feature/pause/M125.cpp | 2 - Marlin/src/gcode/sd/M24_M25.cpp | 2 +- Marlin/src/inc/SanityCheck.h | 2 + .../src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp | 10 + buildroot/tests/rambo | 8 +- 8 files changed, 151 insertions(+), 65 deletions(-) diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 58e0c3df0d..2bd3033808 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -406,6 +406,15 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool // Save current position resume_position = current_position; + // Will the nozzle be parking? + const bool do_park = !axes_should_home(); + + #if ENABLED(POWER_LOSS_RECOVERY) + // Save PLR info in case the power goes out while parked + const float park_raise = do_park ? nozzle.park_mode_0_height(park_point.z) - current_position.z : POWER_LOSS_ZRAISE; + if (was_sd_printing && recovery.enabled) recovery.save(true, park_raise, do_park); + #endif + // Wait for buffered blocks to complete planner.synchronize(); @@ -419,9 +428,8 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool unscaled_e_move(retract, PAUSE_PARK_RETRACT_FEEDRATE); } - // Park the nozzle by doing a Minimum Z Raise followed by an XY Move - if (!axes_should_home()) - nozzle.park(0, park_point); + // If axes don't need to home then the nozzle can park + if (do_park) nozzle.park(0, park_point); // Park the nozzle by doing a Minimum Z Raise followed by an XY Move #if ENABLED(DUAL_X_CARRIAGE) const int8_t saved_ext = active_extruder; @@ -429,7 +437,8 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool set_duplication_enabled(false, DXC_ext); #endif - if (unload_length) // Unload the filament + // Unload the filament, if specified + if (unload_length) unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT); #if ENABLED(DUAL_X_CARRIAGE) diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 9d6e0b42f5..552f1d9009 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -144,7 +144,7 @@ void PrintJobRecovery::prepare() { /** * Save the current machine state to the power-loss recovery file */ -void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=0*/) { +void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POWER_LOSS_ZRAISE*/, const bool raised/*=false*/) { // We don't check IS_SD_PRINTING here so a save may occur during a pause @@ -181,14 +181,12 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=0*/ info.current_position = current_position; info.feedrate = uint16_t(MMS_TO_MMM(feedrate_mm_s)); info.zraise = zraise; + info.flag.raised = raised; // Was Z raised before power-off? TERN_(GCODE_REPEAT_MARKERS, info.stored_repeat = repeat); TERN_(HAS_HOME_OFFSET, info.home_offset = home_offset); TERN_(HAS_POSITION_SHIFT, info.position_shift = position_shift); - - #if HAS_MULTI_EXTRUDER - info.active_extruder = active_extruder; - #endif + TERN_(HAS_MULTI_EXTRUDER, info.active_extruder = active_extruder); #if DISABLED(NO_VOLUMETRICS) info.flag.volumetric_enabled = parser.volumetric_enabled; @@ -289,8 +287,9 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=0*/ constexpr float zraise = 0; #endif - // Save, including the limited Z raise - if (IS_SD_PRINTING()) save(true, zraise); + // Save the current position, distance that Z was (or should be) raised, + // and a flag whether the raise was already done here. + if (IS_SD_PRINTING()) save(true, zraise, ENABLED(BACKUP_POWER_SUPPLY)); // Disable all heaters to reduce power loss thermalManager.disable_all_heaters(); @@ -350,10 +349,10 @@ void PrintJobRecovery::resume() { } #endif - // Restore all hotend temperatures + // Heat hotend enough to soften material #if HAS_HOTEND HOTEND_LOOP() { - const celsius_t et = info.target_temperature[e]; + const celsius_t et = _MAX(info.target_temperature[e], 180); if (et) { #if HAS_MULTI_HOTEND sprintf_P(cmd, PSTR("T%iS"), e); @@ -365,37 +364,59 @@ void PrintJobRecovery::resume() { } #endif + // Interpret the saved Z according to flags + const float z_print = info.current_position.z, + z_raised = z_print + info.zraise; + // // Home the axes that can safely be homed, and // establish the current position as best we can. // + + gcode.process_subcommands_now_P(PSTR("G92.9E0")); // Reset E to 0 + #if Z_HOME_DIR > 0 - // If Z homing goes to max... + float z_now = z_raised; + + // If Z homing goes to max then just move back to the "raised" position gcode.process_subcommands_now_P(PSTR( - "G92.9 E0\n" // Reset E to 0 - "G28R0" // Home all axes (no raise) - )); + "G28R0\n" // Home all axes (no raise) + "G1Z%sF1200" // Move Z down to (raised) height + ), + dtostrf(z_now, 1, 3, str_1) + ); #else - // If a Z raise occurred at outage restore Z, otherwise raise Z now - sprintf_P(cmd, PSTR("G92.9 E0 " TERN(BACKUP_POWER_SUPPLY, "Z%s", "Z0\nG1Z%s")), dtostrf(info.zraise, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); + #if ENABLED(POWER_LOSS_RECOVER_ZHOME) && defined(POWER_LOSS_ZHOME_POS) + #define HOMING_Z_DOWN 1 + #else + #define HOME_XY_ONLY 1 + #endif - // Home safely with no Z raise - gcode.process_subcommands_now_P(PSTR( - "G28R0" // No raise during G28 - #if IS_CARTESIAN && (DISABLED(POWER_LOSS_RECOVER_ZHOME) || defined(POWER_LOSS_ZHOME_POS)) - "XY" // Don't home Z on Cartesian unless overridden - #endif - )); + float z_now = info.flag.raised ? z_raised : z_print; + + // Reset E to 0 and set Z to the real position + #if HOME_XY_ONLY + sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 3, str_1)); + gcode.process_subcommands_now(cmd); + #endif + + // Does Z need to be raised now? It should be raised before homing XY. + if (z_raised > z_now) { + z_now = z_raised; + sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1)); + gcode.process_subcommands_now(cmd); + } + + // Home XY with no Z raise, and also home Z here if Z isn't homing down below. + gcode.process_subcommands_now_P(PSTR("G28R0" TERN_(HOME_XY_ONLY, "XY"))); // No raise during G28 #endif - #if ENABLED(POWER_LOSS_RECOVER_ZHOME) && defined(POWER_LOSS_ZHOME_POS) - // Move to a safe XY position where Z can home while avoiding the print. - // If Z_SAFE_HOMING is enabled, its position must also be outside the print area! + #if HOMING_Z_DOWN + // Move to a safe XY position and home Z while avoiding the print. constexpr xy_pos_t p = POWER_LOSS_ZHOME_POS; sprintf_P(cmd, PSTR("G1X%sY%sF1000\nG28Z"), dtostrf(p.x, 1, 3, str_1), dtostrf(p.y, 1, 3, str_2)); gcode.process_subcommands_now(cmd); @@ -404,9 +425,24 @@ void PrintJobRecovery::resume() { // Mark all axes as having been homed (no effect on current_position) set_all_homed(); + #if HAS_LEVELING + // Restore Z fade and possibly re-enable bed leveling compensation. + // Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option. + // TODO: Add a G28 parameter to leave leveling disabled. + sprintf_P(cmd, PSTR("M420S%cZ%s"), '0' + (char)info.flag.leveling, dtostrf(info.fade, 1, 1, str_1)); + gcode.process_subcommands_now(cmd); + + #if HOME_XY_ONLY + // The physical Z was adjusted at power-off so undo the M420S1 correction to Z with G92.9. + sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 1, str_1)); + gcode.process_subcommands_now(cmd); + #endif + #endif + #if ENABLED(POWER_LOSS_RECOVER_ZHOME) - // Z was homed. Now move Z back up to the saved Z height, plus the POWER_LOSS_ZRAISE. - sprintf_P(cmd, PSTR("G1Z%sF500"), dtostrf(info.current_position.z + POWER_LOSS_ZRAISE, 1, 3, str_1)); + // Z was homed down to the bed, so move up to the raised height. + z_now = z_raised; + sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1)); gcode.process_subcommands_now(cmd); #endif @@ -429,8 +465,23 @@ void PrintJobRecovery::resume() { #endif #endif - // Select the previously active tool (with no_move) - #if HAS_MULTI_EXTRUDER + // Restore all hotend temperatures + #if HAS_HOTEND + HOTEND_LOOP() { + const celsius_t et = info.target_temperature[e]; + if (et) { + #if HAS_MULTI_HOTEND + sprintf_P(cmd, PSTR("T%iS"), e); + gcode.process_subcommands_now(cmd); + #endif + sprintf_P(cmd, PSTR("M109S%i"), et); + gcode.process_subcommands_now(cmd); + } + } + #endif + + // Restore the previously active tool (with no_move) + #if HAS_MULTI_EXTRUDER || HAS_MULTI_HOTEND sprintf_P(cmd, PSTR("T%i S"), info.active_extruder); gcode.process_subcommands_now(cmd); #endif @@ -457,15 +508,6 @@ void PrintJobRecovery::resume() { fwretract.current_hop = info.retract_hop; #endif - #if HAS_LEVELING - // Restore leveling state before 'G92 Z' to ensure - // the Z stepper count corresponds to the native Z. - if (info.fade || info.flag.leveling) { - sprintf_P(cmd, PSTR("M420S%cZ%s"), '0' + (char)info.flag.leveling, dtostrf(info.fade, 1, 1, str_1)); - gcode.process_subcommands_now(cmd); - } - #endif - #if ENABLED(GRADIENT_MIX) memcpy(&mixer.gradient, &info.gradient, sizeof(info.gradient)); #endif @@ -492,14 +534,8 @@ void PrintJobRecovery::resume() { ); gcode.process_subcommands_now(cmd); - // Move back to the saved Z - dtostrf(info.current_position.z, 1, 3, str_1); - #if Z_HOME_DIR > 0 || ENABLED(POWER_LOSS_RECOVER_ZHOME) - sprintf_P(cmd, PSTR("G1 Z%s F500"), str_1); - #else - gcode.process_subcommands_now_P(PSTR("G1 Z0 F200")); - sprintf_P(cmd, PSTR("G92.9 Z%s"), str_1); - #endif + // Move back down to the saved Z for printing + sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_print, 1, 3, str_1)); gcode.process_subcommands_now(cmd); // Restore the feedrate @@ -552,7 +588,15 @@ void PrintJobRecovery::resume() { } DEBUG_EOL(); - DEBUG_ECHOLNPAIR("zraise: ", info.zraise); + DEBUG_ECHOLNPAIR("feedrate: ", info.feedrate); + + DEBUG_ECHOLNPAIR("zraise: ", info.zraise, " ", info.flag.raised ? "(before)" : ""); + + #if ENABLED(GCODE_REPEAT_MARKERS) + DEBUG_ECHOLNPAIR("repeat index: ", info.stored_repeat.index); + LOOP_L_N(i, info.stored_repeat.index) + DEBUG_ECHOLNPAIR("..... sdpos: ", info.stored_repeat.marker.sdpos, " count: ", info.stored_repeat.marker.counter); + #endif #if HAS_HOME_OFFSET DEBUG_ECHOPGM("home_offset: "); @@ -572,12 +616,16 @@ void PrintJobRecovery::resume() { DEBUG_EOL(); #endif - DEBUG_ECHOLNPAIR("feedrate: ", info.feedrate); - #if HAS_MULTI_EXTRUDER DEBUG_ECHOLNPAIR("active_extruder: ", info.active_extruder); #endif + #if DISABLED(NO_VOLUMETRICS) + DEBUG_ECHOPGM("filament_size:"); + LOOP_L_N(i, EXTRUDERS) DEBUG_ECHOLNPAIR(" ", info.filament_size[i]); + DEBUG_EOL(); + #endif + #if HAS_HOTEND DEBUG_ECHOPGM("target_temperature: "); HOTEND_LOOP() { @@ -601,8 +649,9 @@ void PrintJobRecovery::resume() { #endif #if HAS_LEVELING - DEBUG_ECHOLNPAIR("leveling: ", info.flag.leveling, " fade: ", info.fade); + DEBUG_ECHOLNPAIR("leveling: ", info.flag.leveling ? "ON" : "OFF", " fade: ", info.fade); #endif + #if ENABLED(FWRETRACT) DEBUG_ECHOPGM("retract: "); for (int8_t e = 0; e < EXTRUDERS; e++) { @@ -612,11 +661,28 @@ void PrintJobRecovery::resume() { DEBUG_EOL(); DEBUG_ECHOLNPAIR("retract_hop: ", info.retract_hop); #endif + + // Mixing extruder and gradient + #if BOTH(MIXING_EXTRUDER, GRADIENT_MIX) + DEBUG_ECHOLNPAIR("gradient: ", info.gradient.enabled ? "ON" : "OFF"); + #endif + DEBUG_ECHOLNPAIR("sd_filename: ", info.sd_filename); DEBUG_ECHOLNPAIR("sdpos: ", info.sdpos); DEBUG_ECHOLNPAIR("print_job_elapsed: ", info.print_job_elapsed); - DEBUG_ECHOLNPAIR("dryrun: ", AS_DIGIT(info.flag.dryrun)); - DEBUG_ECHOLNPAIR("allow_cold_extrusion: ", info.flag.allow_cold_extrusion); + + DEBUG_ECHOPGM("axis_relative:"); + if (TEST(info.axis_relative, REL_X)) DEBUG_ECHOPGM(" REL_X"); + if (TEST(info.axis_relative, REL_Y)) DEBUG_ECHOPGM(" REL_Y"); + if (TEST(info.axis_relative, REL_Z)) DEBUG_ECHOPGM(" REL_Z"); + if (TEST(info.axis_relative, REL_E)) DEBUG_ECHOPGM(" REL_E"); + if (TEST(info.axis_relative, E_MODE_ABS)) DEBUG_ECHOPGM(" E_MODE_ABS"); + if (TEST(info.axis_relative, E_MODE_REL)) DEBUG_ECHOPGM(" E_MODE_REL"); + DEBUG_EOL(); + + DEBUG_ECHOLNPAIR("flag.dryrun: ", AS_DIGIT(info.flag.dryrun)); + DEBUG_ECHOLNPAIR("flag.allow_cold_extrusion: ", AS_DIGIT(info.flag.allow_cold_extrusion)); + DEBUG_ECHOLNPAIR("flag.volumetric_enabled: ", AS_DIGIT(info.flag.volumetric_enabled)); } else DEBUG_ECHOLNPGM("INVALID DATA"); diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index df3ae222a2..0fa9172fcf 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -117,6 +117,7 @@ typedef struct { // Misc. Marlin flags struct { + bool raised:1; // Raised before saved bool dryrun:1; // M111 S8 bool allow_cold_extrusion:1; // M302 P1 #if ENABLED(HAS_LEVELING) @@ -182,7 +183,7 @@ class PrintJobRecovery { static inline void cancel() { purge(); IF_DISABLED(NO_SD_AUTOSTART, card.autofile_begin()); } static void load(); - static void save(const bool force=ENABLED(SAVE_EACH_CMD_MODE), const float zraise=0); + static void save(const bool force=ENABLED(SAVE_EACH_CMD_MODE), const float zraise=POWER_LOSS_ZRAISE, const bool raised=false); #if PIN_EXISTS(POWER_LOSS) static inline void outage() { diff --git a/Marlin/src/gcode/feature/pause/M125.cpp b/Marlin/src/gcode/feature/pause/M125.cpp index 351ef01f34..2eb4ceea41 100644 --- a/Marlin/src/gcode/feature/pause/M125.cpp +++ b/Marlin/src/gcode/feature/pause/M125.cpp @@ -78,8 +78,6 @@ void GcodeSuite::M125() { // If possible, show an LCD prompt with the 'P' flag const bool show_lcd = TERN0(HAS_LCD_MENU, parser.boolval('P')); - TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true)); - if (pause_print(retract, park_point, show_lcd, 0)) { if (ENABLED(EXTENSIBLE_UI) || BOTH(EMERGENCY_PARSER, HOST_PROMPT_SUPPORT) || !sd_printing || show_lcd) { wait_for_confirmation(false, 0); diff --git a/Marlin/src/gcode/sd/M24_M25.cpp b/Marlin/src/gcode/sd/M24_M25.cpp index f46a964af0..4cb040feb3 100644 --- a/Marlin/src/gcode/sd/M24_M25.cpp +++ b/Marlin/src/gcode/sd/M24_M25.cpp @@ -105,7 +105,7 @@ void GcodeSuite::M25() { if (IS_SD_PRINTING()) card.pauseSDPrint(); #endif - #if ENABLED(POWER_LOSS_RECOVERY) + #if ENABLED(POWER_LOSS_RECOVERY) && DISABLED(DGUS_LCD_UI_MKS) if (recovery.enabled) recovery.save(true); #endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index bbd646a30d..c9aebe89ad 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -2903,6 +2903,8 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #error "POWER_LOSS_RECOVER_ZHOME cannot be used with Z_SAFE_HOMING." #elif BOTH(POWER_LOSS_PULLUP, POWER_LOSS_PULLDOWN) #error "You can't enable POWER_LOSS_PULLUP and POWER_LOSS_PULLDOWN at the same time." + #elif ENABLED(POWER_LOSS_RECOVER_ZHOME) && Z_HOME_DIR > 0 + #error "POWER_LOSS_RECOVER_ZHOME is not needed on a machine that homes to ZMAX." #elif BOTH(IS_CARTESIAN, POWER_LOSS_RECOVER_ZHOME) && Z_HOME_DIR < 0 && !defined(POWER_LOSS_ZHOME_POS) #error "POWER_LOSS_RECOVER_ZHOME requires POWER_LOSS_ZHOME_POS for a Cartesian that homes to ZMIN." #endif diff --git a/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp b/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp index 7d98b64991..525b781599 100644 --- a/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp +++ b/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp @@ -39,6 +39,10 @@ #include "../../../../module/stepper/trinamic.h" #endif +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../../../feature/powerloss.h" +#endif + #if ENABLED(DGUS_UI_MOVE_DIS_OPTION) uint16_t distanceToMove = 10; #endif @@ -78,8 +82,13 @@ constexpr feedRate_t park_speed_xy = TERN(NOZZLE_PARK_FEATURE, NOZZLE_PARK_XY_FE void MKS_pause_print_move() { queue.exhaust(); position_before_pause = current_position; + + // Save the current position, the raise amount, and 'already raised' + TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true, mks_park_pos.z, true)); + destination.z = _MIN(current_position.z + mks_park_pos.z, Z_MAX_POS); prepare_internal_move_to_destination(park_speed_z); + destination.set(X_MIN_POS + mks_park_pos.x, Y_MIN_POS + mks_park_pos.y); prepare_internal_move_to_destination(park_speed_xy); } @@ -89,6 +98,7 @@ void MKS_resume_print_move() { prepare_internal_move_to_destination(park_speed_xy); destination.z = position_before_pause.z; prepare_internal_move_to_destination(park_speed_z); + TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true)); } float z_offset_add = 0; diff --git a/buildroot/tests/rambo b/buildroot/tests/rambo index 95260e58b4..87772a988b 100755 --- a/buildroot/tests/rambo +++ b/buildroot/tests/rambo @@ -14,9 +14,9 @@ opt_set MOTHERBOARD BOARD_RAMBO \ EXTRUDERS 2 TEMP_SENSOR_0 -2 TEMP_SENSOR_1 1 TEMP_SENSOR_BED 2 \ TEMP_SENSOR_PROBE 1 TEMP_PROBE_PIN 12 \ TEMP_SENSOR_CHAMBER 3 TEMP_CHAMBER_PIN 3 HEATER_CHAMBER_PIN 45 \ - Z_HOME_DIR 1 GRID_MAX_POINTS_X 16 \ + GRID_MAX_POINTS_X 16 \ FANMUX0_PIN 53 -opt_disable USE_ZMIN_PLUG Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN USE_WATCHDOG +opt_disable Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN USE_WATCHDOG opt_enable USE_ZMAX_PLUG REPRAP_DISCOUNT_SMART_CONTROLLER LCD_PROGRESS_BAR LCD_PROGRESS_BAR_TEST \ FIX_MOUNTED_PROBE CODEPENDENT_XY_HOMING PIDTEMPBED PROBE_TEMP_COMPENSATION \ PREHEAT_BEFORE_PROBING PROBING_HEATERS_OFF PROBING_FANS_OFF PROBING_STEPPERS_OFF WAIT_FOR_BED_HEATER \ @@ -32,7 +32,7 @@ opt_enable USE_ZMAX_PLUG REPRAP_DISCOUNT_SMART_CONTROLLER LCD_PROGRESS_BAR LCD_P SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE \ BACKLASH_COMPENSATION BACKLASH_GCODE BAUD_RATE_GCODE BEZIER_CURVE_SUPPORT \ FWRETRACT ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS \ - PSU_CONTROL AUTO_POWER_CONTROL POWER_LOSS_RECOVERY POWER_LOSS_PIN POWER_LOSS_STATE POWER_LOSS_RECOVER_ZHOME \ + PSU_CONTROL AUTO_POWER_CONTROL POWER_LOSS_RECOVERY POWER_LOSS_PIN POWER_LOSS_STATE POWER_LOSS_RECOVER_ZHOME POWER_LOSS_ZHOME_POS \ SLOW_PWM_HEATERS THERMAL_PROTECTION_CHAMBER LIN_ADVANCE EXTRA_LIN_ADVANCE_K \ HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT PINS_DEBUGGING MAX7219_DEBUG M114_DETAIL opt_add DEBUG_POWER_LOSS_RECOVERY @@ -43,7 +43,7 @@ exec_test $1 $2 "RAMBO | EXTRUDERS 2 | CHAR LCD + SD | FIX Probe | ABL-Linear | # restore_configs opt_set MOTHERBOARD BOARD_RAMBO \ - EXTRUDERS 0 TEMP_SENSOR_0 999 DUMMY_THERMISTOR_999_VALUE 170 \ + EXTRUDERS 0 TEMP_SENSOR_0 999 DUMMY_THERMISTOR_999_VALUE 170 Z_HOME_DIR 1 \ DIGIPOT_MOTOR_CURRENT '{ 120, 120, 120, 120, 120 }' \ LEVEL_CORNERS_LEVELING_ORDER '{ LF, RF }' opt_enable USE_XMAX_PLUG USE_YMAX_PLUG USE_ZMAX_PLUG \ From 61ac1ed2f61e7d699354dbeb5f9fac5d75d7f7a6 Mon Sep 17 00:00:00 2001 From: ellensp Date: Tue, 11 May 2021 09:33:43 +1200 Subject: [PATCH 31/67] update FLSUN_HISPEED env to flsun_hispeedv1 (#21510) --- Marlin/src/pins/pins.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index 70e6836a32..d38dc595f2 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -557,7 +557,7 @@ #elif MB(FLY_MINI) #include "stm32f1/pins_FLY_MINI.h" // STM32F1 env:FLY_MINI #elif MB(FLSUN_HISPEED) - #include "stm32f1/pins_FLSUN_HISPEED.h" // STM32F1 env:flsun_hispeed + #include "stm32f1/pins_FLSUN_HISPEED.h" // STM32F1 env:flsun_hispeedv1 #elif MB(BEAST) #include "stm32f1/pins_BEAST.h" // STM32F1 env:STM32F103RE #elif MB(MINGDA_MPX_ARM_MINI) From 782ced6ff728b05b0a1bf668c5bae628340a9018 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Tue, 11 May 2021 01:00:06 +0000 Subject: [PATCH 32/67] [cron] Bump distribution date (2021-05-11) --- Marlin/src/inc/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index ad4f39ab70..7e63f30775 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2021-05-10" + #define STRING_DISTRIBUTION_DATE "2021-05-11" #endif /** From dd16d6ad6e4857a4ead1e7791cfe6df3974ba87b Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 10 May 2021 22:47:34 -0500 Subject: [PATCH 33/67] Update Chart.js to 2.9.4 Addressing CVE-2020-7746 --- buildroot/web-ui/data/www/chart.min.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 buildroot/web-ui/data/www/chart.min.js diff --git a/buildroot/web-ui/data/www/chart.min.js b/buildroot/web-ui/data/www/chart.min.js old mode 100644 new mode 100755 index 7c16b0d128..a87f61443e --- a/buildroot/web-ui/data/www/chart.min.js +++ b/buildroot/web-ui/data/www/chart.min.js @@ -1,7 +1,7 @@ /*! - * Chart.js v2.9.3 + * Chart.js v2.9.4 * https://www.chartjs.org - * (c) 2019 Chart.js Contributors + * (c) 2020 Chart.js Contributors * Released under the MIT License */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(function(){try{return require("moment")}catch(t){}}()):"function"==typeof define&&define.amd?define(["require"],(function(t){return e(function(){try{return t("moment")}catch(t){}}())})):(t=t||self).Chart=e(t.moment)}(this,(function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},n=function(t,e){return t(e={exports:{}},e.exports),e.exports}((function(t){var n={};for(var i in e)e.hasOwnProperty(i)&&(n[e[i]]=i);var a=t.exports={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};for(var r in a)if(a.hasOwnProperty(r)){if(!("channels"in a[r]))throw new Error("missing channels property: "+r);if(!("labels"in a[r]))throw new Error("missing channel labels property: "+r);if(a[r].labels.length!==a[r].channels)throw new Error("channel and label counts mismatch: "+r);var o=a[r].channels,s=a[r].labels;delete a[r].channels,delete a[r].labels,Object.defineProperty(a[r],"channels",{value:o}),Object.defineProperty(a[r],"labels",{value:s})}a.rgb.hsl=function(t){var e,n,i=t[0]/255,a=t[1]/255,r=t[2]/255,o=Math.min(i,a,r),s=Math.max(i,a,r),l=s-o;return s===o?e=0:i===s?e=(a-r)/l:a===s?e=2+(r-i)/l:r===s&&(e=4+(i-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),n=(o+s)/2,[e,100*(s===o?0:n<=.5?l/(s+o):l/(2-s-o)),100*n]},a.rgb.hsv=function(t){var e,n,i,a,r,o=t[0]/255,s=t[1]/255,l=t[2]/255,u=Math.max(o,s,l),d=u-Math.min(o,s,l),h=function(t){return(u-t)/6/d+.5};return 0===d?a=r=0:(r=d/u,e=h(o),n=h(s),i=h(l),o===u?a=i-n:s===u?a=1/3+e-i:l===u&&(a=2/3+n-e),a<0?a+=1:a>1&&(a-=1)),[360*a,100*r,100*u]},a.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[a.rgb.hsl(t)[0],100*(1/255*Math.min(e,Math.min(n,i))),100*(i=1-1/255*Math.max(e,Math.max(n,i)))]},a.rgb.cmyk=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-i,1-a)))/(1-e)||0),100*((1-i-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]},a.rgb.keyword=function(t){var i=n[t];if(i)return i;var a,r,o,s=1/0;for(var l in e)if(e.hasOwnProperty(l)){var u=e[l],d=(r=t,o=u,Math.pow(r[0]-o[0],2)+Math.pow(r[1]-o[1],2)+Math.pow(r[2]-o[2],2));d.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]},a.rgb.lab=function(t){var e=a.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},a.hsl.rgb=function(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a},a.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,a=n,r=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,a*=r<=1?r:2-r,[e,100*(0===i?2*a/(r+a):2*n/(i+n)),100*((i+n)/2)]},a.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}},a.hsv.hsl=function(t){var e,n,i,a=t[0],r=t[1]/100,o=t[2]/100,s=Math.max(o,.01);return i=(2-r)*o,n=r*s,[a,100*(n=(n/=(e=(2-r)*s)<=1?e:2-e)||0),100*(i/=2)]},a.hwb.rgb=function(t){var e,n,i,a,r,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(h>1&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),a=u+i*((n=1-d)-u),e){default:case 6:case 0:r=n,o=a,s=u;break;case 1:r=a,o=n,s=u;break;case 2:r=u,o=n,s=a;break;case 3:r=u,o=a,s=n;break;case 4:r=a,o=u,s=n;break;case 5:r=n,o=u,s=a}return[255*r,255*o,255*s]},a.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a))]},a.xyz.rgb=function(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:12.92*i,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]},a.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},a.lab.xyz=function(t){var e,n,i,a=t[0];e=t[1]/500+(n=(a+16)/116),i=n-t[2]/200;var r=Math.pow(n,3),o=Math.pow(e,3),s=Math.pow(i,3);return n=r>.008856?r:(n-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,i=s>.008856?s:(i-16/116)/7.787,[e*=95.047,n*=100,i*=108.883]},a.lab.lch=function(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]},a.lch.lab=function(t){var e,n=t[0],i=t[1];return e=t[2]/360*2*Math.PI,[n,i*Math.cos(e),i*Math.sin(e)]},a.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:a.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var o=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(o+=60),o},a.hsv.ansi16=function(t){return a.rgb.ansi16(a.hsv.rgb(t),t[2])},a.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5)},a.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(t>50));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},a.ansi256.rgb=function(t){if(t>=232){var e=10*(t-232)+8;return[e,e,e]}var n;return t-=16,[Math.floor(t/36)/5*255,Math.floor((n=t%36)/6)/5*255,n%6/5*255]},a.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},a.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map((function(t){return t+t})).join(""));var i=parseInt(n,16);return[i>>16&255,i>>8&255,255&i]},a.rgb.hcg=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255,r=Math.max(Math.max(n,i),a),o=Math.min(Math.min(n,i),a),s=r-o;return e=s<=0?0:r===n?(i-a)/s%6:r===i?2+(a-n)/s:4+(n-i)/s+4,e/=6,[360*(e%=1),100*s,100*(s<1?o/(1-s):0)]},a.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,a=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(a=(n-.5*i)/(1-i)),[t[0],100*i,100*a]},a.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,i=t[2]/100;if(0===n)return[255*i,255*i,255*i];var a,r=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=l,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=l,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=l}return a=(1-n)*i,[255*(n*r[0]+a),255*(n*r[1]+a),255*(n*r[2]+a)]},a.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0;return n>0&&(i=e/n),[t[0],100*i,100*n]},a.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return n>0&&n<.5?i=e/(2*n):n>=.5&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},a.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],100*(n-e),100*(1-n)]},a.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},a.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},a.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},a.gray.hsl=a.gray.hsv=function(t){return[0,0,t[0]]},a.gray.hwb=function(t){return[0,100,t[0]]},a.gray.cmyk=function(t){return[0,0,0,t[0]]},a.gray.lab=function(t){return[t[0],0,0]},a.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},a.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}}));n.rgb,n.hsl,n.hsv,n.hwb,n.cmyk,n.xyz,n.lab,n.lch,n.hex,n.keyword,n.ansi16,n.ansi256,n.hcg,n.apple,n.gray;function i(t){var e=function(){for(var t={},e=Object.keys(n),i=e.length,a=0;a1&&(e=Array.prototype.slice.call(arguments));var n=t(e);if("object"==typeof n)for(var i=n.length,a=0;a1&&(e=Array.prototype.slice.call(arguments)),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(i)}))}));var s=o,l={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},u={getRgba:d,getHsla:h,getRgb:function(t){var e=d(t);return e&&e.slice(0,3)},getHsl:function(t){var e=h(t);return e&&e.slice(0,3)},getHwb:c,getAlpha:function(t){var e=d(t);if(e)return e[3];if(e=h(t))return e[3];if(e=c(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+v(t[0])+v(t[1])+v(t[2])+(e>=0&&e<1?v(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return f(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:f,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"},percentaString:g,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:p,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return b[t.slice(0,3)]}};function d(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(i){a=(i=i[1])[3];for(var r=0;rn?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,i=void 0===e?.5:e,a=2*i-1,r=this.alpha()-n.alpha(),o=((a*r==-1?a:(a+r)/(1+a*r))+1)/2,s=1-o;return this.rgb(o*this.red()+s*n.red(),o*this.green()+s*n.green(),o*this.blue()+s*n.blue()).alpha(this.alpha()*i+n.alpha()*(1-i))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new y,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},y.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},y.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},y.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i=0;a--)e.call(n,t[a],a);else for(a=0;a=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-S.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*S.easeInBounce(2*t):.5*S.easeOutBounce(2*t-1)+.5}},C={effects:S};M.easingEffects=S;var P=Math.PI,A=P/180,D=2*P,T=P/2,I=P/4,F=2*P/3,L={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2,i/2),s=e+o,l=n+o,u=e+i-o,d=n+a-o;t.moveTo(e,l),se.left-1e-6&&t.xe.top-1e-6&&t.y0&&this.requestAnimationFrame()},advance:function(){for(var t,e,n,i,a=this.animations,r=0;r=n?(V.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},J=V.options.resolve,Q=["push","pop","shift","splice","unshift"];function tt(t,e){var n=t._chartjs;if(n){var i=n.listeners,a=i.indexOf(e);-1!==a&&i.splice(a,1),i.length>0||(Q.forEach((function(e){delete t[e]})),delete t._chartjs)}}var et=function(t,e){this.initialize(t,e)};V.extend(et.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements(),n._type=n.getMeta().type},updateIndex:function(t){this.index=t},linkScales:function(){var t=this.getMeta(),e=this.chart,n=e.scales,i=this.getDataset(),a=e.options.scales;null!==t.xAxisID&&t.xAxisID in n&&!i.xAxisID||(t.xAxisID=i.xAxisID||a.xAxes[0].id),null!==t.yAxisID&&t.yAxisID in n&&!i.yAxisID||(t.yAxisID=i.yAxisID||a.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&tt(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),i=this.getDataset().data||[],a=n.data;for(t=0,e=i.length;tn&&this.insertElements(n,i-n)},insertElements:function(t,e){for(var n=0;na?(r=a/e.innerRadius,t.arc(o,s,e.innerRadius-a,i+r,n-r,!0)):t.arc(o,s,a,i+Math.PI/2,n-Math.PI/2),t.closePath(),t.clip()}function rt(t,e,n){var i="inner"===e.borderAlign;i?(t.lineWidth=2*e.borderWidth,t.lineJoin="round"):(t.lineWidth=e.borderWidth,t.lineJoin="bevel"),n.fullCircles&&function(t,e,n,i){var a,r=n.endAngle;for(i&&(n.endAngle=n.startAngle+it,at(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=it,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+it,n.startAngle,!0),a=0;as;)a-=it;for(;a=o&&a<=s,u=r>=n.innerRadius&&r<=n.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t,e=this._chart.ctx,n=this._view,i="inner"===n.borderAlign?.33:0,a={x:n.x,y:n.y,innerRadius:n.innerRadius,outerRadius:Math.max(n.outerRadius-i,0),pixelMargin:i,startAngle:n.startAngle,endAngle:n.endAngle,fullCircles:Math.floor(n.circumference/it)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+it,e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),t=0;tt.x&&(e=vt(e,"left","right")):t.basen?n:i,r:l.right||a<0?0:a>e?e:a,b:l.bottom||r<0?0:r>n?n:r,l:l.left||o<0?0:o>e?e:o}}function xt(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&mt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}z._set("global",{elements:{rectangle:{backgroundColor:gt,borderColor:gt,borderSkipped:"bottom",borderWidth:0}}});var yt=X.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=mt(t),n=e.right-e.left,i=e.bottom-e.top,a=bt(t,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+a.l,y:e.top+a.t,w:n-a.l-a.r,h:i-a.t-a.b}}}(e),i=n.outer,a=n.inner;t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h),i.w===a.w&&i.h===a.h||(t.save(),t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return xt(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return pt(n)?xt(n,t,null):xt(n,null,e)},inXRange:function(t){return xt(this._view,t,null)},inYRange:function(t){return xt(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return pt(n)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return pt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),_t={},kt=ot,wt=ut,Mt=ft,St=yt;_t.Arc=kt,_t.Line=wt,_t.Point=Mt,_t.Rectangle=St;var Ct=V._deprecated,Pt=V.valueOrDefault;function At(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=V.isNullOrUndef(r)?function(t,e){var n,i,a,r,o=t._length;for(a=1,r=e.length;a0?Math.min(o,Math.abs(i-n)):o,n=i;return o}(e.scale,e.pixels):-1;return V.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}z._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),z._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var Dt=nt.extend({dataElementType:_t.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;nt.prototype.initialize.apply(n,arguments),(t=n.getMeta()).stack=n.getDataset().stack,t.bar=!0,e=n._getIndexScale().options,Ct("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Ct("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Ct("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Ct("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Ct("bar chart",e.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(t){var e,n,i=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,n=i.length;e=0&&p.min>=0?p.min:p.max,y=void 0===p.start?p.end:p.max>=0&&p.min>=0?p.max-p.min:p.min-p.max,_=g.length;if(v||void 0===v&&void 0!==b)for(i=0;i<_&&(a=g[i]).index!==t;++i)a.stack===b&&(r=void 0===(u=h._parseValue(f[a.index].data[e])).start?u.end:u.min>=0&&u.max>=0?u.max:u.min,(p.min<0&&r<0||p.max>=0&&r>0)&&(x+=r));return o=h.getPixelForValue(x),l=(s=h.getPixelForValue(x+y))-o,void 0!==m&&Math.abs(l)=0&&!c||y<0&&c?o-m:o+m),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var a="flex"===i.barThickness?function(t,e,n){var i,a=e.pixels,r=a[t],o=t>0?a[t-1]:null,s=t=Ot?-Rt:b<-Ot?Rt:0)+m,y=Math.cos(b),_=Math.sin(b),k=Math.cos(x),w=Math.sin(x),M=b<=0&&x>=0||x>=Rt,S=b<=zt&&x>=zt||x>=Rt+zt,C=b<=-zt&&x>=-zt||x>=Ot+zt,P=b===-Ot||x>=Ot?-1:Math.min(y,y*p,k,k*p),A=C?-1:Math.min(_,_*p,w,w*p),D=M?1:Math.max(y,y*p,k,k*p),T=S?1:Math.max(_,_*p,w,w*p);u=(D-P)/2,d=(T-A)/2,h=-(D+P)/2,c=-(T+A)/2}for(i=0,a=g.length;i0&&!isNaN(t)?Rt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,a,r,o,s,l,u=0,d=this.chart;if(!t)for(e=0,n=d.data.datasets.length;e(u=s>u?s:u)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=V.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Lt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Lt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Lt(n.hoverBorderWidth,n.borderWidth)},_getRingWeightOffset:function(t){for(var e=0,n=0;n0&&Vt(l[t-1]._model,s)&&(n.controlPointPreviousX=u(n.controlPointPreviousX,s.left,s.right),n.controlPointPreviousY=u(n.controlPointPreviousY,s.top,s.bottom)),t0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return ie(t,e,{intersect:!1})},point:function(t,e){return te(t,Jt(e,t))},nearest:function(t,e,n){var i=Jt(e,t);n.axis=n.axis||"xy";var a=ne(n.axis);return ee(t,i,n.intersect,a)},x:function(t,e,n){var i=Jt(e,t),a=[],r=!1;return Qt(t,(function(t){t.inXRange(i.x)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a},y:function(t,e,n){var i=Jt(e,t),a=[],r=!1;return Qt(t,(function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a}}},re=V.extend;function oe(t,e){return V.where(t,(function(t){return t.pos===e}))}function se(t,e){return t.sort((function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i.index-a.index:i.weight-a.weight}))}function le(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function ue(t,e,n){var i,a,r=n.box,o=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?r.height:r.width,t[n.pos]+=n.size,r.getPadding){var s=r.getPadding();o.top=Math.max(o.top,s.top),o.left=Math.max(o.left,s.left),o.bottom=Math.max(o.bottom,s.bottom),o.right=Math.max(o.right,s.right)}if(i=e.outerWidth-le(o,t,"left","right"),a=e.outerHeight-le(o,t,"top","bottom"),i!==t.w||a!==t.h)return t.w=i,t.h=a,n.horizontal?i!==t.w:a!==t.h}function de(t,e){var n=e.maxPadding;function i(t){var i={left:0,top:0,right:0,bottom:0};return t.forEach((function(t){i[t]=Math.max(e[t],n[t])})),i}return i(t?["left","right"]:["top","bottom"])}function he(t,e,n){var i,a,r,o,s,l,u=[];for(i=0,a=t.length;idiv{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}"}))&&fe.default||fe,me="$chartjs",ve="chartjs-size-monitor",be="chartjs-render-monitor",xe="chartjs-render-animation",ye=["animationstart","webkitAnimationStart"],_e={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function ke(t,e){var n=V.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var we=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function Me(t,e,n){t.addEventListener(e,n,we)}function Se(t,e,n){t.removeEventListener(e,n,we)}function Ce(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Pe(t){var e=document.createElement("div");return e.className=t||"",e}function Ae(t,e,n){var i,a,r,o,s=t[me]||(t[me]={}),l=s.resizer=function(t){var e=Pe(ve),n=Pe(ve+"-expand"),i=Pe(ve+"-shrink");n.appendChild(Pe()),i.appendChild(Pe()),e.appendChild(n),e.appendChild(i),e._reset=function(){n.scrollLeft=1e6,n.scrollTop=1e6,i.scrollLeft=1e6,i.scrollTop=1e6};var a=function(){e._reset(),t()};return Me(n,"scroll",a.bind(n,"expand")),Me(i,"scroll",a.bind(i,"shrink")),e}((i=function(){if(s.resizer){var i=n.options.maintainAspectRatio&&t.parentNode,a=i?i.clientWidth:0;e(Ce("resize",n)),i&&i.clientWidth0){var r=t[0];r.label?n=r.label:r.xLabel?n=r.xLabel:a>0&&r.index-1?t.split("\n"):t}function We(t){var e=z.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:Re(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:Re(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:Re(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:Re(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:Re(t.titleFontStyle,e.defaultFontStyle),titleFontSize:Re(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:Re(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:Re(t.footerFontStyle,e.defaultFontStyle),footerFontSize:Re(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function Ve(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function He(t){return Be([],Ee(t))}var je=X.extend({initialize:function(){this._model=We(this._options),this._lastActive=[]},getTitle:function(){var t=this,e=t._options,n=e.callbacks,i=n.beforeTitle.apply(t,arguments),a=n.title.apply(t,arguments),r=n.afterTitle.apply(t,arguments),o=[];return o=Be(o,Ee(i)),o=Be(o,Ee(a)),o=Be(o,Ee(r))},getBeforeBody:function(){return He(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return V.each(t,(function(t){var r={before:[],lines:[],after:[]};Be(r.before,Ee(i.beforeLabel.call(n,t,e))),Be(r.lines,i.label.call(n,t,e)),Be(r.after,Ee(i.afterLabel.call(n,t,e))),a.push(r)})),a},getAfterBody:function(){return He(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this,e=t._options.callbacks,n=e.beforeFooter.apply(t,arguments),i=e.footer.apply(t,arguments),a=e.afterFooter.apply(t,arguments),r=[];return r=Be(r,Ee(n)),r=Be(r,Ee(i)),r=Be(r,Ee(a))},update:function(t){var e,n,i,a,r,o,s,l,u,d,h=this,c=h._options,f=h._model,g=h._model=We(c),p=h._active,m=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},x={width:f.width,height:f.height},y={x:f.caretX,y:f.caretY};if(p.length){g.opacity=1;var _=[],k=[];y=Ne[c.position].call(h,p,h._eventPosition);var w=[];for(e=0,n=p.length;ei.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===d?r+=h:r-="bottom"===d?e.height+h:e.height/2,"center"===d?"left"===u?a+=h:"right"===u&&(a-=h):"left"===u?a-=c:"right"===u&&(a+=c),{x:a,y:r}}(g,x,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.yl.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,x),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=x.width,g.height=x.height,g.caretX=y.x,g.caretY=y.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===c)s=g+m/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+p)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+p-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+m)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n){var i,a,r,o=e.title,s=o.length;if(s){var l=ze(e.rtl,e.x,e.width);for(t.x=Ve(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=V.fontString(i,e._titleFontStyle,e._titleFontFamily),r=0;r0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(t.save(),t.globalAlpha=a,this.drawBackground(i,e,t,n),i.y+=e.yPadding,V.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),V.rtl.restoreTextDirection(t,e.textDirection),t.restore())}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],"mouseout"===t.type?n._active=[]:(n._active=n._chart.getElementsAtEventForMode(t,i.mode,i),i.reverse&&n._active.reverse()),(e=!V.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}}),qe=Ne,Ue=je;Ue.positioners=qe;var Ye=V.valueOrDefault;function Ge(){return V.merge({},[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var a,r,o,s=n[t].length;for(e[t]||(e[t]=[]),a=0;a=e[t].length&&e[t].push({}),!e[t][a].type||o.type&&o.type!==e[t][a].type?V.merge(e[t][a],[Oe.getScaleDefaults(r),o]):V.merge(e[t][a],o)}else V._merger(t,e,n,i)}})}function Xe(){return V.merge({},[].slice.call(arguments),{merger:function(t,e,n,i){var a=e[t]||{},r=n[t];"scales"===t?e[t]=Ge(a,r):"scale"===t?e[t]=V.merge(a,[Oe.getScaleDefaults(r.type),r]):V._merger(t,e,n,i)}})}function Ke(t){var e=t.options;V.each(t.scales,(function(e){ge.removeBox(t,e)})),e=Xe(z.global,z[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function Ze(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(V.findIndex(t,a)>=0);return i}function $e(t){return"top"===t||"bottom"===t}function Je(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}z._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var Qe=function(t,e){return this.construct(t,e),this};V.extend(Qe.prototype,{construct:function(t,e){var n=this;e=function(t){var e=(t=t||{}).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=Xe(z.global,z[t.type],t.options||{}),t}(e);var i=Fe.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=V.uid(),n.ctx=i,n.canvas=a,n.config=e,n.width=o,n.height=r,n.aspectRatio=r?o/r:null,n.options=e.options,n._bufferedRender=!1,n._layers=[],n.chart=n,n.controller=n,Qe.instances[n.id]=n,Object.defineProperty(n,"data",{get:function(){return n.config.data},set:function(t){n.config.data=t}}),i&&a?(n.initialize(),n.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Le.notify(t,"beforeInit"),V.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Le.notify(t,"afterInit"),t},clear:function(){return V.canvas.clear(this),this},stop:function(){return $.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(V.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:V.getMaximumHeight(i)));if((e.width!==r||e.height!==o)&&(i.width=e.width=r,i.height=e.height=o,i.style.width=r+"px",i.style.height=o+"px",V.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Le.notify(e,"resize",[s]),n.onResize&&n.onResize(e,s),e.stop(),e.update({duration:n.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;V.each(e.xAxes,(function(t,n){t.id||(t.id=Ze(e.xAxes,"x-axis-",n))})),V.each(e.yAxes,(function(t,n){t.id||(t.id=Ze(e.yAxes,"y-axis-",n))})),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,n=t.scales||{},i=[],a=Object.keys(n).reduce((function(t,e){return t[e]=!1,t}),{});e.scales&&(i=i.concat((e.scales.xAxes||[]).map((function(t){return{options:t,dtype:"category",dposition:"bottom"}})),(e.scales.yAxes||[]).map((function(t){return{options:t,dtype:"linear",dposition:"left"}})))),e.scale&&i.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),V.each(i,(function(e){var i=e.options,r=i.id,o=Ye(i.type,e.dtype);$e(i.position)!==$e(e.dposition)&&(i.position=e.dposition),a[r]=!0;var s=null;if(r in n&&n[r].type===o)(s=n[r]).options=i,s.ctx=t.ctx,s.chart=t;else{var l=Oe.getScaleConstructor(o);if(!l)return;s=new l({id:r,type:o,options:i,ctx:t.ctx,chart:t}),n[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)})),V.each(a,(function(t,e){t||delete n[e]})),t.scales=n,Oe.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t,e,n=this,i=[],a=n.data.datasets;for(t=0,e=a.length;t=0;--n)this.drawDataset(e[n],t);Le.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Le.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Le.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Le.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Le.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return ae.modes.single(this,t)},getElementsAtEvent:function(t){return ae.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return ae.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=ae.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return ae.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e.order||0,index:t}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e3?n[2]-n[1]:n[1]-n[0];Math.abs(i)>1&&t!==Math.floor(t)&&(i=t-Math.floor(t));var a=V.log10(Math.abs(i)),r="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=V.log10(Math.abs(t)),s=Math.floor(o)-Math.floor(a);s=Math.max(Math.min(s,20),0),r=t.toExponential(s)}else{var l=-1*Math.floor(a);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(V.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},on=V.isArray,sn=V.isNullOrUndef,ln=V.valueOrDefault,un=V.valueAtIndexOrDefault;function dn(t,e,n){var i,a=t.getTicks().length,r=Math.min(e,a-1),o=t.getPixelForTick(r),s=t._startPixel,l=t._endPixel;if(!(n&&(i=1===a?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(r-1))/2,(o+=rl+1e-6)))return o}function hn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,p,m,v=n.length,b=[],x=[],y=[];for(a=0;ae){for(n=0;n=c||d<=1||!s.isHorizontal()?s.labelRotation=h:(e=(t=s._getLabelSizes()).widest.width,n=t.highest.height-t.highest.offset,i=Math.min(s.maxWidth,s.chart.width-e),e+6>(a=l.offset?s.maxWidth/d:i/(d-1))&&(a=i/(d-(l.offset?.5:1)),r=s.maxHeight-cn(l.gridLines)-u.padding-fn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=V.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/a,1)),Math.asin(Math.min(r/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){V.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){V.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=t.chart,i=t.options,a=i.ticks,r=i.scaleLabel,o=i.gridLines,s=t._isVisible(),l="bottom"===i.position,u=t.isHorizontal();if(u?e.width=t.maxWidth:s&&(e.width=cn(o)+fn(r)),u?s&&(e.height=cn(o)+fn(r)):e.height=t.maxHeight,a.display&&s){var d=pn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,p=h.highest,m=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,x=V.toRadians(t.labelRotation),y=Math.cos(x),_=Math.sin(x),k=_*g.width+y*(p.height-(b?p.offset:0))+(b?0:m);e.height=Math.min(t.maxHeight,e.height+k+v);var w,M,S=t.getPixelForTick(0)-t.left,C=t.right-t.getPixelForTick(t.getTicks().length-1);b?(w=l?y*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):y*f.width+_*f.offset):(w=c.width/2,M=f.width/2),t.paddingLeft=Math.max((w-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-C)*t.width/(t.width-C),0)+3}else{var P=a.mirror?0:g.width+v+m;e.width=Math.min(t.maxWidth,e.width+P),t.paddingTop=c.height/2,t.paddingBottom=f.height/2}}t.handleMargins(),u?(t.width=t._length=n.width-t.margins.left-t.margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=n.height-t.margins.top-t.margins.bottom)},handleMargins:function(){var t=this;t.margins&&(t.margins.left=Math.max(t.paddingLeft,t.margins.left),t.margins.top=Math.max(t.paddingTop,t.margins.top),t.margins.right=Math.max(t.paddingRight,t.margins.right),t.margins.bottom=Math.max(t.paddingBottom,t.margins.bottom))},afterFit:function(){V.callback(this.options.afterFit,[this])},isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(sn(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},_convertTicksToLabels:function(t){var e,n,i,a=this;for(a.ticks=t.map((function(t){return t.value})),a.beforeTickToLabelConversion(),e=a.convertTicksToLabels(t)||a.ticks,a.afterTickToLabelConversion(),n=0,i=t.length;nn-1?null:this.getPixelForDecimal(t*i+(e?i/2:0))},getPixelForDecimal:function(t){return this._reversePixels&&(t=1-t),this._startPixel+t*this._length},getDecimalForPixel:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,i,a,r=this.options.ticks,o=this._length,s=r.maxTicksLimit||o/this._tickSize()+1,l=r.major.enabled?function(t){var e,n,i=[];for(e=0,n=t.length;es)return function(t,e,n){var i,a,r=0,o=e[0];for(n=Math.ceil(n),i=0;iu)return r;return Math.max(u,1)}(l,t,0,s),u>0){for(e=0,n=u-1;e1?(h-d)/(u-1):null,vn(t,i,V.isNullOrUndef(a)?0:d-a,d),vn(t,i,h,V.isNullOrUndef(a)?t.length:h+a),mn(t)}return vn(t,i),mn(t)},_tickSize:function(){var t=this.options.ticks,e=V.toRadians(this.labelRotation),n=Math.abs(Math.cos(e)),i=Math.abs(Math.sin(e)),a=this._getLabelSizes(),r=t.autoSkipPadding||0,o=a?a.widest.width+r:0,s=a?a.highest.height+r:0;return this.isHorizontal()?s*n>o*i?o/n:s/i:s*i=0&&(o=t),void 0!==r&&(t=n.indexOf(r))>=0&&(s=t),e.minIndex=o,e.maxIndex=s,e.min=n[o],e.max=n[s]},buildTicks:function(){var t=this._getLabels(),e=this.minIndex,n=this.maxIndex;this.ticks=0===e&&n===t.length-1?t:t.slice(e,n+1)},getLabelForIndex:function(t,e){var n=this.chart;return n.getDatasetMeta(e).controller._getValueScaleId()===this.id?this.getRightValue(n.data.datasets[e].data[t]):this._getLabels()[t]},_configure:function(){var t=this,e=t.options.offset,n=t.ticks;xn.prototype._configure.call(t),t.isHorizontal()||(t._reversePixels=!t._reversePixels),n&&(t._startValue=t.minIndex-(e?.5:0),t._valueRange=Math.max(n.length-(e?0:1),1))},getPixelForValue:function(t,e,n){var i,a,r,o=this;return yn(e)||yn(n)||(t=o.chart.data.datasets[n].data[e]),yn(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=V.valueOrDefault(i,t),e=-1!==(r=a.indexOf(t))?r:e,isNaN(e)&&(e=t)),o.getPixelForDecimal((e-o._startValue)/o._valueRange)},getPixelForTick:function(t){var e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t],t+this.minIndex)},getValueForPixel:function(t){var e=Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange);return Math.min(Math.max(e,0),this.ticks.length-1)},getBasePixel:function(){return this.bottom}}),kn={position:"bottom"};_n._defaults=kn;var wn=V.noop,Mn=V.isNullOrUndef;var Sn=xn.extend({getRightValue:function(t){return"string"==typeof t?+t:xn.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=V.sign(t.min),i=V.sign(t.max);n<0&&i<0?t.max=0:n>0&&i>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==r&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this.options.ticks,n=e.stepSize,i=e.maxTicksLimit;return n?t=Math.ceil(this.max/n)-Math.floor(this.min/n)+1:(t=this._computeTickLimit(),i=i||11),i&&(t=Math.min(i,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:wn,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),i={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:V.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var n,i,a,r,o=[],s=t.stepSize,l=s||1,u=t.maxTicks-1,d=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,p=V.niceNum((g-f)/u/l)*l;if(p<1e-14&&Mn(d)&&Mn(h))return[f,g];(r=Math.ceil(g/p)-Math.floor(f/p))>u&&(p=V.niceNum(r*p/u/l)*l),s||Mn(c)?n=Math.pow(10,V._decimalPlaces(p)):(n=Math.pow(10,c),p=Math.ceil(p*n)/n),i=Math.floor(f/p)*p,a=Math.ceil(g/p)*p,s&&(!Mn(d)&&V.almostWhole(d/p,p/1e3)&&(i=d),!Mn(h)&&V.almostWhole(h/p,p/1e3)&&(a=h)),r=(a-i)/p,r=V.almostEquals(r,Math.round(r),p/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Mn(d)?i:d);for(var m=1;me.length-1?null:this.getPixelForValue(e[t])}}),Tn=Cn;Dn._defaults=Tn;var In=V.valueOrDefault,Fn=V.math.log10;var Ln={position:"left",ticks:{callback:rn.formatters.logarithmic}};function On(t,e){return V.isFinite(t)&&t>=0?t:e}var Rn=xn.extend({determineDataLimits:function(){var t,e,n,i,a,r,o=this,s=o.options,l=o.chart,u=l.data.datasets,d=o.isHorizontal();function h(t){return d?t.xAxisID===o.id:t.yAxisID===o.id}o.min=Number.POSITIVE_INFINITY,o.max=Number.NEGATIVE_INFINITY,o.minNotZero=Number.POSITIVE_INFINITY;var c=s.stacked;if(void 0===c)for(t=0;t0){var e=V.min(t),n=V.max(t);o.min=Math.min(o.min,e),o.max=Math.max(o.max,n)}}))}else for(t=0;t0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(Fn(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:On(e.min),max:On(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=In(t.min,Math.pow(10,Math.floor(Fn(e.min)))),o=Math.floor(Fn(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(Fn(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(Fn(r)),i=Math.floor(r/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{a.push(r),10===++i&&(i=1,l=++n>=0?1:l),r=Math.round(i*Math.pow(10,n)*l)/l}while(ne.length-1?null:this.getPixelForValue(e[t])},_getFirstTickValue:function(t){var e=Math.floor(Fn(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;xn.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=In(t.options.ticks.fontSize,z.global.defaultFontSize)/t._length),t._startValue=Fn(e),t._valueOffset=n,t._valueRange=(Fn(t.max)-Fn(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(Fn(t)-e._startValue)/e._valueRange+e._valueOffset),e.getPixelForDecimal(n)},getValueForPixel:function(t){var e=this,n=e.getDecimalForPixel(t);return 0===n&&0===e.min?0:Math.pow(10,e._startValue+(n-e._valueOffset)*e._valueRange)}}),zn=Ln;Rn._defaults=zn;var Nn=V.valueOrDefault,Bn=V.valueAtIndexOrDefault,En=V.options.resolve,Wn={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:rn.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Vn(t){var e=t.ticks;return e.display&&t.display?Nn(e.fontSize,z.global.defaultFontSize)+2*e.backdropPaddingY:0}function Hn(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:ta?{start:e-n,end:e}:{start:e,end:e+n}}function jn(t){return 0===t||180===t?"center":t<180?"left":"right"}function qn(t,e,n,i){var a,r,o=n.y+i/2;if(V.isArray(e))for(a=0,r=e.length;a270||t<90)&&(n.y-=e.h)}function Yn(t){return V.isNumber(t)?t:0}var Gn=Sn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Vn(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;V.each(e.data.datasets,(function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);V.each(a.data,(function(e,a){var r=+t.getRightValue(e);isNaN(r)||o.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))}))}})),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Vn(this.options))},convertTicksToLabels:function(){var t=this;Sn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map((function(){var e=V.callback(t.options.pointLabels.callback,arguments,t);return e||0===e?e:""}))},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this.options;t.display&&t.pointLabels.display?function(t){var e,n,i,a=V.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},o={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,u,d=t.chart.data.labels.length;for(e=0;er.r&&(r.r=f.end,o.r=h),g.startr.b&&(r.b=g.end,o.b=h)}t.setReductions(t.drawingArea,r,o)}(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-(i.height-i.paddingTop),0)/Math.cos(n.b);a=Yn(a),r=Yn(r),o=Yn(o),s=Yn(s),i.drawingArea=Math.min(Math.floor(t-(a+r)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-a.paddingTop-i-a.drawingArea;a.xCenter=Math.floor((o+r)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?n+360:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(V.isNullOrUndef(t))return NaN;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(n)*e+this.xCenter,y:Math.sin(n)*e+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(t){var e=this.min,n=this.max;return this.getPointPositionForValue(t||0,this.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},_drawGrid:function(){var t,e,n,i=this,a=i.ctx,r=i.options,o=r.gridLines,s=r.angleLines,l=Nn(s.lineWidth,o.lineWidth),u=Nn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Vn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=V.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s=t.chart.data.labels.length-1;s>=0;s--){var l=0===s?a/2:0,u=t.getPointPosition(s,r+l+5),d=Bn(i.fontColor,s,z.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=V.toDegrees(h);e.textAlign=jn(c),Un(c,t._pointLabelSizes[s],u),qn(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&V.each(i.ticks,(function(t,n){0!==n&&(e=i.getDistanceFromCenterForValue(i.ticksAsNumbers[n]),function(t,e,n,i){var a,r=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=Bn(e.color,i-1),u=Bn(e.lineWidth,i-1);if((o||s)&&l&&u){if(r.save(),r.strokeStyle=l,r.lineWidth=u,r.setLineDash&&(r.setLineDash(e.borderDash||[]),r.lineDashOffset=e.borderDashOffset||0),r.beginPath(),o)r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{a=t.getPointPosition(0,n),r.moveTo(a.x,a.y);for(var d=1;d=0;t--)e=i.getDistanceFromCenterForValue(r.ticks.reverse?i.min:i.max),n=i.getPointPosition(t,e),a.beginPath(),a.moveTo(i.xCenter,i.yCenter),a.lineTo(n.x,n.y),a.stroke();a.restore()}},_drawLabels:function(){var t=this,e=t.ctx,n=t.options.ticks;if(n.display){var i,a,r=t.getIndexAngle(0),o=V.options._parseFont(n),s=Nn(n.fontColor,z.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",V.each(t.ticks,(function(r,l){(0!==l||n.reverse)&&(i=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),n.showLabelBackdrop&&(a=e.measureText(r).width,e.fillStyle=n.backdropColor,e.fillRect(-a/2-n.backdropPaddingX,-i-o.size/2-n.backdropPaddingY,a+2*n.backdropPaddingX,o.size+2*n.backdropPaddingY)),e.fillStyle=s,e.fillText(r,0,-i))})),e.restore()}},_drawTitle:V.noop}),Xn=Wn;Gn._defaults=Xn;var Kn=V._deprecated,Zn=V.options.resolve,$n=V.valueOrDefault,Jn=Number.MIN_SAFE_INTEGER||-9007199254740991,Qn=Number.MAX_SAFE_INTEGER||9007199254740991,ti={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ei=Object.keys(ti);function ni(t,e){return t-e}function ii(t){return V.valueOrDefault(t.time.min,t.ticks.min)}function ai(t){return V.valueOrDefault(t.time.max,t.ticks.max)}function ri(t,e,n,i){var a=function(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(a=t[(i=o+s>>1)-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(n-r[e])/s:0,u=(o[i]-r[i])*l;return r[i]+u}function oi(t,e){var n=t._adapter,i=t.options.time,a=i.parser,r=a||i.format,o=e;return"function"==typeof a&&(o=a(o)),V.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),V.isFinite(o)||(o=n.parse(o))),o)}function si(t,e){if(V.isNullOrUndef(e))return null;var n=t.options.time,i=oi(t,t.getRightValue(e));return null===i?i:(n.round&&(i=+t._adapter.startOf(i,n.round)),i)}function li(t,e,n,i){var a,r,o,s=ei.length;for(a=ei.indexOf(t);a=0&&(e[r].major=!0);return e}(t,r,o,n):r}var di=xn.extend({initialize:function(){this.mergeTicksOptions(),xn.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new an._date(e.adapters.date);return Kn("time scale",n.format,"time.format","time.parser"),Kn("time scale",n.min,"time.min","ticks.min"),Kn("time scale",n.max,"time.max","ticks.max"),V.mergeIf(n.displayFormats,i.formats()),xn.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),xn.prototype.getRightValue.call(this,t)},determineDataLimits:function(){var t,e,n,i,a,r,o,s=this,l=s.chart,u=s._adapter,d=s.options,h=d.time.unit||"day",c=Qn,f=Jn,g=[],p=[],m=[],v=s._getLabels();for(t=0,n=v.length;t1?function(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(a=h;a=a&&n<=r&&d.push(n);return i.min=a,i.max=r,i._unit=l.unit||(s.autoSkip?li(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ei.length-1;r>=ei.indexOf(n);r--)if(o=ei[r],ti[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ei[n?ei.indexOf(n):0]}(i,d.length,l.minUnit,i.min,i.max)),i._majorUnit=s.major.enabled&&"year"!==i._unit?function(t){for(var e=ei.indexOf(t)+1,n=ei.length;ee&&s=0&&t0?s:1}}),hi={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};di._defaults=hi;var ci={category:_n,linear:Dn,logarithmic:Rn,radialLinear:Gn,time:di},fi={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};an._date.override("function"==typeof t?{_id:"moment",formats:function(){return fi},parse:function(e,n){return"string"==typeof e&&"string"==typeof n?e=t(e,n):e instanceof t||(e=t(e)),e.isValid()?e.valueOf():null},format:function(e,n){return t(e).format(n)},add:function(e,n,i){return t(e).add(n,i).valueOf()},diff:function(e,n,i){return t(e).diff(t(n),i)},startOf:function(e,n,i){return e=t(e),"isoWeek"===n?e.isoWeekday(i).valueOf():e.startOf(n).valueOf()},endOf:function(e,n){return t(e).endOf(n).valueOf()},_create:function(e){return t(e)}}:{}),z._set("global",{plugins:{filler:{propagate:!0}}});var gi={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function mi(t){return(t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,a,r,o=t.el._scale,s=o.options,l=o.chart.data.labels.length,u=t.fill,d=[];if(!l)return null;for(e=s.ticks.reverse?o.max:o.min,n=s.ticks.reverse?o.min:o.max,i=o.getPointPositionForValue(0,e),a=0;a0;--r)V.canvas.lineTo(t,n[r],n[r-1],!0);else for(o=n[0].cx,s=n[0].cy,l=Math.sqrt(Math.pow(n[0].x-o,2)+Math.pow(n[0].y-s,2)),r=a-1;r>0;--r)t.arc(o,s,l,n[r].angle,n[r-1].angle,!0)}}function _i(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,p=i.spanGaps,m=[],v=[],b=0,x=0;for(t.beginPath(),o=0,s=g;o=0;--n)(e=l[n].$filler)&&e.visible&&(a=(i=e.el)._view,r=i._children||[],o=e.mapper,s=a.backgroundColor||z.global.defaultColor,o&&s&&r.length&&(V.canvas.clipArea(u,t.chartArea),_i(u,r,o,a,s,i._loop),V.canvas.unclipArea(u)))}},wi=V.rtl.getRtlAdapter,Mi=V.noop,Si=V.valueOrDefault;function Ci(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}z._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data.datasets,n=t.options.legend||{},i=n.labels&&n.labels.usePointStyle;return t._getSortedDatasetMetas().map((function(n){var a=n.controller.getStyle(i?0:void 0);return{text:e[n.index].label,fillStyle:a.backgroundColor,hidden:!t.isDatasetVisible(n.index),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,rotation:a.rotation,datasetIndex:n.index}}),this)}}},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data.datasets;for(a.setAttribute("class",t.id+"-legend"),e=0,n=r.length;el.width)&&(h+=o+n.padding,d[d.length-(e>0?0:1)]=0),s[e]={left:0,top:0,width:i,height:o},d[d.length-1]+=i+n.padding})),l.height+=h}else{var c=n.padding,f=t.columnWidths=[],g=t.columnHeights=[],p=n.padding,m=0,v=0;V.each(t.legendItems,(function(t,e){var i=Ci(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(p+=m+n.padding,f.push(m),g.push(v),m=0,v=0),m=Math.max(m,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}})),p+=m,f.push(m),g.push(v),l.width+=p}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Mi,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=z.global,a=i.defaultColor,r=i.elements.line,o=t.height,s=t.columnHeights,l=t.width,u=t.lineWidths;if(e.display){var d,h=wi(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Si(n.fontColor,i.defaultFontColor),g=V.options._parseFont(n),p=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var m=Ci(n,p),v=t.legendHitBoxes,b=function(t,i){switch(e.align){case"start":return n.padding;case"end":return t-i;default:return(t-i+n.padding)/2}},x=t.isHorizontal();d=x?{x:t.left+b(l,u[0]),y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+b(o,s[0]),line:0},V.rtl.overrideTextDirection(t.ctx,e.textDirection);var y=p+n.padding;V.each(t.legendItems,(function(e,i){var f=c.measureText(e.text).width,g=m+p/2+f,_=d.x,k=d.y;h.setWidth(t.minSize.width),x?i>0&&_+g+n.padding>t.left+t.minSize.width&&(k=d.y+=y,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&k+y>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,k=d.y=t.top+b(o,s[d.line]));var w=h.x(_);!function(t,e,i){if(!(isNaN(m)||m<=0)){c.save();var o=Si(i.lineWidth,r.borderWidth);if(c.fillStyle=Si(i.fillStyle,a),c.lineCap=Si(i.lineCap,r.borderCapStyle),c.lineDashOffset=Si(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Si(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Si(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Si(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=m*Math.SQRT2/2,l=h.xPlus(t,m/2),u=e+p/2;V.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,m),e,m,p),0!==o&&c.strokeRect(h.leftForLtr(t,m),e,m,p);c.restore()}}(w,k,e),v[i].left=h.leftForLtr(w,v[i].width),v[i].top=k,function(t,e,n,i){var a=p/2,r=h.xPlus(t,m+a),o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(h.xPlus(r,i),o),c.stroke())}(w,k,e,f),x?d.x+=g+n.padding:d.y+=y})),V.rtl.restoreTextDirection(t.ctx,e.textDirection)}},_getLegendItemAt:function(t,e){var n,i,a,r=this;if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)for(a=r.legendHitBoxes,n=0;n=(i=a[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return r.legendItems[n];return null},handleEvent:function(t){var e,n=this,i=n.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!i.onHover&&!i.onLeave)return}else{if("click"!==a)return;if(!i.onClick)return}e=n._getLegendItemAt(t.x,t.y),"click"===a?e&&i.onClick&&i.onClick.call(n,t.native,e):(i.onLeave&&e!==n._hoveredItem&&(n._hoveredItem&&i.onLeave.call(n,t.native,n._hoveredItem),n._hoveredItem=e),i.onHover&&e&&i.onHover.call(n,t.native,e))}});function Ai(t,e){var n=new Pi({ctx:t.ctx,options:e,chart:t});ge.configure(t,n,e),ge.addBox(t,n),t.legend=n}var Di={id:"legend",_element:Pi,beforeInit:function(t){var e=t.options.legend;e&&Ai(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(V.mergeIf(e,z.global.legend),n?(ge.configure(t,n,e),n.options=e):Ai(t,e)):n&&(ge.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Ti=V.noop;z._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Ii=X.extend({initialize:function(t){V.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:Ti,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Ti,beforeSetDimensions:Ti,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Ti,beforeBuildLabels:Ti,buildLabels:Ti,afterBuildLabels:Ti,beforeFit:Ti,fit:function(){var t,e=this,n=e.options,i=e.minSize={},a=e.isHorizontal();n.display?(t=(V.isArray(n.text)?n.text.length:1)*V.options._parseFont(n).lineHeight+2*n.padding,e.width=i.width=a?e.maxWidth:t,e.height=i.height=a?t:e.maxHeight):e.width=i.width=e.height=i.height=0},afterFit:Ti,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=t.options;if(n.display){var i,a,r,o=V.options._parseFont(n),s=o.lineHeight,l=s/2+n.padding,u=0,d=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=V.valueOrDefault(n.fontColor,z.global.defaultFontColor),e.font=o.string,t.isHorizontal()?(a=h+(f-h)/2,r=d+l,i=f-h):(a="left"===n.position?h+l:f-l,r=d+(c-d)/2,i=c-d,u=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(a,r),e.rotate(u),e.textAlign="center",e.textBaseline="middle";var g=n.text;if(V.isArray(g))for(var p=0,m=0;m=0;i--){var a=t[i];if(e(a))return a}},V.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},V.almostEquals=function(t,e,n){return Math.abs(t-e)=t},V.max=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.max(t,e)}),Number.NEGATIVE_INFINITY)},V.min=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.min(t,e)}),Number.POSITIVE_INFINITY)},V.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},V.toRadians=function(t){return t*(Math.PI/180)},V.toDegrees=function(t){return t*(180/Math.PI)},V._decimalPlaces=function(t){if(V.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},V.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},V.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},V.aliasPixel=function(t){return t%2==0?0:.5},V._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},V.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},V.EPSILON=Number.EPSILON||1e-14,V.splineCurveMonotone=function(t){var e,n,i,a,r,o,s,l,u,d=(t||[]).map((function(t){return{model:t._model,deltaK:0,mK:0}})),h=d.length;for(e=0;e0?d[e-1]:null,(a=e0?d[e-1]:null,a=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},V.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},V.niceNum=function(t,e){var n=Math.floor(V.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},V.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},V.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.target||t.srcElement,o=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var l=parseFloat(V.getStyle(r,"padding-left")),u=parseFloat(V.getStyle(r,"padding-top")),d=parseFloat(V.getStyle(r,"padding-right")),h=parseFloat(V.getStyle(r,"padding-bottom")),c=o.right-o.left-l-d,f=o.bottom-o.top-u-h;return{x:n=Math.round((n-o.left-l)/c*r.width/e.currentDevicePixelRatio),y:i=Math.round((i-o.top-u)/f*r.height/e.currentDevicePixelRatio)}},V.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},V.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},V._calculatePadding=function(t,e,n){return(e=V.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},V._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},V.getMaximumWidth=function(t){var e=V._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-V._calculatePadding(e,"padding-left",n)-V._calculatePadding(e,"padding-right",n),a=V.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},V.getMaximumHeight=function(t){var e=V._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-V._calculatePadding(e,"padding-top",n)-V._calculatePadding(e,"padding-bottom",n),a=V.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},V.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},V.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},V.fontString=function(t,e,n){return e+" "+t+"px "+n},V.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var o,s,l,u,d,h=0,c=n.length;for(o=0;on.length){for(o=0;oi&&(i=r),i},V.numberOfLabelLines=function(t){var e=1;return V.each(t,(function(t){V.isArray(t)&&t.length>e&&(e=t.length)})),e},V.color=k?function(t){return t instanceof CanvasGradient&&(t=z.global.defaultColor),k(t)}:function(t){return console.error("Color.js not found!"),t},V.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:V.color(t).saturate(.5).darken(.1).rgbString()}}(),tn._adapters=an,tn.Animation=Z,tn.animationService=$,tn.controllers=$t,tn.DatasetController=nt,tn.defaults=z,tn.Element=X,tn.elements=_t,tn.Interaction=ae,tn.layouts=ge,tn.platform=Fe,tn.plugins=Le,tn.Scale=xn,tn.scaleService=Oe,tn.Ticks=rn,tn.Tooltip=Ue,tn.helpers.each(ci,(function(t,e){tn.scaleService.registerScaleType(e,t,t._defaults)})),Li)Li.hasOwnProperty(Ni)&&tn.plugins.register(Li[Ni]);tn.platform.initialize();var Bi=tn;return"undefined"!=typeof window&&(window.Chart=tn),tn.Chart=tn,tn.Legend=Li.legend._element,tn.Title=Li.title._element,tn.pluginService=tn.plugins,tn.PluginBase=tn.Element.extend({}),tn.canvasHelpers=tn.helpers.canvas,tn.layoutService=tn.layouts,tn.LinearScaleBase=Sn,tn.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],(function(t){tn[t]=function(e,n){return new tn(e,tn.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}})),Bi})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(function(){try{return require("moment")}catch(t){}}()):"function"==typeof define&&define.amd?define(["require"],(function(t){return e(function(){try{return t("moment")}catch(t){}}())})):(t=t||self).Chart=e(t.moment)}(this,(function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},n=function(t,e){return t(e={exports:{}},e.exports),e.exports}((function(t){var n={};for(var i in e)e.hasOwnProperty(i)&&(n[e[i]]=i);var a=t.exports={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};for(var r in a)if(a.hasOwnProperty(r)){if(!("channels"in a[r]))throw new Error("missing channels property: "+r);if(!("labels"in a[r]))throw new Error("missing channel labels property: "+r);if(a[r].labels.length!==a[r].channels)throw new Error("channel and label counts mismatch: "+r);var o=a[r].channels,s=a[r].labels;delete a[r].channels,delete a[r].labels,Object.defineProperty(a[r],"channels",{value:o}),Object.defineProperty(a[r],"labels",{value:s})}a.rgb.hsl=function(t){var e,n,i=t[0]/255,a=t[1]/255,r=t[2]/255,o=Math.min(i,a,r),s=Math.max(i,a,r),l=s-o;return s===o?e=0:i===s?e=(a-r)/l:a===s?e=2+(r-i)/l:r===s&&(e=4+(i-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),n=(o+s)/2,[e,100*(s===o?0:n<=.5?l/(s+o):l/(2-s-o)),100*n]},a.rgb.hsv=function(t){var e,n,i,a,r,o=t[0]/255,s=t[1]/255,l=t[2]/255,u=Math.max(o,s,l),d=u-Math.min(o,s,l),h=function(t){return(u-t)/6/d+.5};return 0===d?a=r=0:(r=d/u,e=h(o),n=h(s),i=h(l),o===u?a=i-n:s===u?a=1/3+e-i:l===u&&(a=2/3+n-e),a<0?a+=1:a>1&&(a-=1)),[360*a,100*r,100*u]},a.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[a.rgb.hsl(t)[0],100*(1/255*Math.min(e,Math.min(n,i))),100*(i=1-1/255*Math.max(e,Math.max(n,i)))]},a.rgb.cmyk=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-i,1-a)))/(1-e)||0),100*((1-i-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]},a.rgb.keyword=function(t){var i=n[t];if(i)return i;var a,r,o,s=1/0;for(var l in e)if(e.hasOwnProperty(l)){var u=e[l],d=(r=t,o=u,Math.pow(r[0]-o[0],2)+Math.pow(r[1]-o[1],2)+Math.pow(r[2]-o[2],2));d.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]},a.rgb.lab=function(t){var e=a.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},a.hsl.rgb=function(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a},a.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,a=n,r=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,a*=r<=1?r:2-r,[e,100*(0===i?2*a/(r+a):2*n/(i+n)),100*((i+n)/2)]},a.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}},a.hsv.hsl=function(t){var e,n,i,a=t[0],r=t[1]/100,o=t[2]/100,s=Math.max(o,.01);return i=(2-r)*o,n=r*s,[a,100*(n=(n/=(e=(2-r)*s)<=1?e:2-e)||0),100*(i/=2)]},a.hwb.rgb=function(t){var e,n,i,a,r,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(h>1&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),a=u+i*((n=1-d)-u),e){default:case 6:case 0:r=n,o=a,s=u;break;case 1:r=a,o=n,s=u;break;case 2:r=u,o=n,s=a;break;case 3:r=u,o=a,s=n;break;case 4:r=a,o=u,s=n;break;case 5:r=n,o=u,s=a}return[255*r,255*o,255*s]},a.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a))]},a.xyz.rgb=function(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:12.92*i,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]},a.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},a.lab.xyz=function(t){var e,n,i,a=t[0];e=t[1]/500+(n=(a+16)/116),i=n-t[2]/200;var r=Math.pow(n,3),o=Math.pow(e,3),s=Math.pow(i,3);return n=r>.008856?r:(n-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,i=s>.008856?s:(i-16/116)/7.787,[e*=95.047,n*=100,i*=108.883]},a.lab.lch=function(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]},a.lch.lab=function(t){var e,n=t[0],i=t[1];return e=t[2]/360*2*Math.PI,[n,i*Math.cos(e),i*Math.sin(e)]},a.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:a.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var o=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(o+=60),o},a.hsv.ansi16=function(t){return a.rgb.ansi16(a.hsv.rgb(t),t[2])},a.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5)},a.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(t>50));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},a.ansi256.rgb=function(t){if(t>=232){var e=10*(t-232)+8;return[e,e,e]}var n;return t-=16,[Math.floor(t/36)/5*255,Math.floor((n=t%36)/6)/5*255,n%6/5*255]},a.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},a.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map((function(t){return t+t})).join(""));var i=parseInt(n,16);return[i>>16&255,i>>8&255,255&i]},a.rgb.hcg=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255,r=Math.max(Math.max(n,i),a),o=Math.min(Math.min(n,i),a),s=r-o;return e=s<=0?0:r===n?(i-a)/s%6:r===i?2+(a-n)/s:4+(n-i)/s+4,e/=6,[360*(e%=1),100*s,100*(s<1?o/(1-s):0)]},a.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,a=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(a=(n-.5*i)/(1-i)),[t[0],100*i,100*a]},a.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,i=t[2]/100;if(0===n)return[255*i,255*i,255*i];var a,r=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=l,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=l,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=l}return a=(1-n)*i,[255*(n*r[0]+a),255*(n*r[1]+a),255*(n*r[2]+a)]},a.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0;return n>0&&(i=e/n),[t[0],100*i,100*n]},a.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return n>0&&n<.5?i=e/(2*n):n>=.5&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},a.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],100*(n-e),100*(1-n)]},a.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},a.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},a.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},a.gray.hsl=a.gray.hsv=function(t){return[0,0,t[0]]},a.gray.hwb=function(t){return[0,100,t[0]]},a.gray.cmyk=function(t){return[0,0,0,t[0]]},a.gray.lab=function(t){return[t[0],0,0]},a.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},a.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}}));n.rgb,n.hsl,n.hsv,n.hwb,n.cmyk,n.xyz,n.lab,n.lch,n.hex,n.keyword,n.ansi16,n.ansi256,n.hcg,n.apple,n.gray;function i(t){var e=function(){for(var t={},e=Object.keys(n),i=e.length,a=0;a1&&(e=Array.prototype.slice.call(arguments));var n=t(e);if("object"==typeof n)for(var i=n.length,a=0;a1&&(e=Array.prototype.slice.call(arguments)),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(i)}))}));var s=o,l={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},u={getRgba:d,getHsla:h,getRgb:function(t){var e=d(t);return e&&e.slice(0,3)},getHsl:function(t){var e=h(t);return e&&e.slice(0,3)},getHwb:c,getAlpha:function(t){var e=d(t);if(e)return e[3];if(e=h(t))return e[3];if(e=c(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+v(t[0])+v(t[1])+v(t[2])+(e>=0&&e<1?v(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return f(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:f,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"},percentaString:g,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:p,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return b[t.slice(0,3)]}};function d(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(i){a=(i=i[1])[3];for(var r=0;rn?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,i=void 0===e?.5:e,a=2*i-1,r=this.alpha()-n.alpha(),o=((a*r==-1?a:(a+r)/(1+a*r))+1)/2,s=1-o;return this.rgb(o*this.red()+s*n.red(),o*this.green()+s*n.green(),o*this.blue()+s*n.blue()).alpha(this.alpha()*i+n.alpha()*(1-i))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new y,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},y.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},y.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},y.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i=0;a--)e.call(n,t[a],a);else for(a=0;a=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-C.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*C.easeInBounce(2*t):.5*C.easeOutBounce(2*t-1)+.5}},P={effects:C};S.easingEffects=C;var A=Math.PI,D=A/180,T=2*A,I=A/2,F=A/4,O=2*A/3,L={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2,i/2),s=e+o,l=n+o,u=e+i-o,d=n+a-o;t.moveTo(e,l),se.left-1e-6&&t.xe.top-1e-6&&t.y0&&this.requestAnimationFrame()},advance:function(){for(var t,e,n,i,a=this.animations,r=0;r=n?(H.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},Q=H.options.resolve,tt=["push","pop","shift","splice","unshift"];function et(t,e){var n=t._chartjs;if(n){var i=n.listeners,a=i.indexOf(e);-1!==a&&i.splice(a,1),i.length>0||(tt.forEach((function(e){delete t[e]})),delete t._chartjs)}}var nt=function(t,e){this.initialize(t,e)};H.extend(nt.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements(),n._type=n.getMeta().type},updateIndex:function(t){this.index=t},linkScales:function(){var t=this.getMeta(),e=this.chart,n=e.scales,i=this.getDataset(),a=e.options.scales;null!==t.xAxisID&&t.xAxisID in n&&!i.xAxisID||(t.xAxisID=i.xAxisID||a.xAxes[0].id),null!==t.yAxisID&&t.yAxisID in n&&!i.yAxisID||(t.yAxisID=i.yAxisID||a.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&et(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),i=this.getDataset().data||[],a=n.data;for(t=0,e=i.length;tn&&this.insertElements(n,i-n)},insertElements:function(t,e){for(var n=0;na?(r=a/e.innerRadius,t.arc(o,s,e.innerRadius-a,i+r,n-r,!0)):t.arc(o,s,a,i+Math.PI/2,n-Math.PI/2),t.closePath(),t.clip()}function ot(t,e,n){var i="inner"===e.borderAlign;i?(t.lineWidth=2*e.borderWidth,t.lineJoin="round"):(t.lineWidth=e.borderWidth,t.lineJoin="bevel"),n.fullCircles&&function(t,e,n,i){var a,r=n.endAngle;for(i&&(n.endAngle=n.startAngle+at,rt(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=at,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+at,n.startAngle,!0),a=0;as;)a-=at;for(;a=o&&a<=s,u=r>=n.innerRadius&&r<=n.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t,e=this._chart.ctx,n=this._view,i="inner"===n.borderAlign?.33:0,a={x:n.x,y:n.y,innerRadius:n.innerRadius,outerRadius:Math.max(n.outerRadius-i,0),pixelMargin:i,startAngle:n.startAngle,endAngle:n.endAngle,fullCircles:Math.floor(n.circumference/at)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+at,e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),t=0;tt.x&&(e=bt(e,"left","right")):t.basen?n:i,r:l.right||a<0?0:a>e?e:a,b:l.bottom||r<0?0:r>n?n:r,l:l.left||o<0?0:o>e?e:o}}function yt(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&vt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}N._set("global",{elements:{rectangle:{backgroundColor:pt,borderColor:pt,borderSkipped:"bottom",borderWidth:0}}});var _t=K.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=vt(t),n=e.right-e.left,i=e.bottom-e.top,a=xt(t,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+a.l,y:e.top+a.t,w:n-a.l-a.r,h:i-a.t-a.b}}}(e),i=n.outer,a=n.inner;t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h),i.w===a.w&&i.h===a.h||(t.save(),t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return yt(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return mt(n)?yt(n,t,null):yt(n,null,e)},inXRange:function(t){return yt(this._view,t,null)},inYRange:function(t){return yt(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return mt(n)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return mt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),kt={},wt=st,Mt=dt,St=gt,Ct=_t;kt.Arc=wt,kt.Line=Mt,kt.Point=St,kt.Rectangle=Ct;var Pt=H._deprecated,At=H.valueOrDefault;function Dt(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=H.isNullOrUndef(r)?function(t,e){var n,i,a,r,o=t._length;for(a=1,r=e.length;a0?Math.min(o,Math.abs(i-n)):o,n=i;return o}(e.scale,e.pixels):-1;return H.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}N._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),N._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var Tt=it.extend({dataElementType:kt.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;it.prototype.initialize.apply(n,arguments),(t=n.getMeta()).stack=n.getDataset().stack,t.bar=!0,e=n._getIndexScale().options,Pt("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Pt("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Pt("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Pt("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Pt("bar chart",e.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(t){var e,n,i=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,n=i.length;e=0&&p.min>=0?p.min:p.max,y=void 0===p.start?p.end:p.max>=0&&p.min>=0?p.max-p.min:p.min-p.max,_=g.length;if(v||void 0===v&&void 0!==b)for(i=0;i<_&&(a=g[i]).index!==t;++i)a.stack===b&&(r=void 0===(u=h._parseValue(f[a.index].data[e])).start?u.end:u.min>=0&&u.max>=0?u.max:u.min,(p.min<0&&r<0||p.max>=0&&r>0)&&(x+=r));return o=h.getPixelForValue(x),l=(s=h.getPixelForValue(x+y))-o,void 0!==m&&Math.abs(l)=0&&!c||y<0&&c?o-m:o+m),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var a="flex"===i.barThickness?function(t,e,n){var i,a=e.pixels,r=a[t],o=t>0?a[t-1]:null,s=t=Rt?-zt:b<-Rt?zt:0)+m,y=Math.cos(b),_=Math.sin(b),k=Math.cos(x),w=Math.sin(x),M=b<=0&&x>=0||x>=zt,S=b<=Nt&&x>=Nt||x>=zt+Nt,C=b<=-Nt&&x>=-Nt||x>=Rt+Nt,P=b===-Rt||x>=Rt?-1:Math.min(y,y*p,k,k*p),A=C?-1:Math.min(_,_*p,w,w*p),D=M?1:Math.max(y,y*p,k,k*p),T=S?1:Math.max(_,_*p,w,w*p);u=(D-P)/2,d=(T-A)/2,h=-(D+P)/2,c=-(T+A)/2}for(i=0,a=g.length;i0&&!isNaN(t)?zt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,a,r,o,s,l,u=0,d=this.chart;if(!t)for(e=0,n=d.data.datasets.length;e(u=s>u?s:u)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Lt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Lt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Lt(n.hoverBorderWidth,n.borderWidth)},_getRingWeightOffset:function(t){for(var e=0,n=0;n0&&Ht(l[t-1]._model,s)&&(n.controlPointPreviousX=u(n.controlPointPreviousX,s.left,s.right),n.controlPointPreviousY=u(n.controlPointPreviousY,s.top,s.bottom)),t0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return ae(t,e,{intersect:!1})},point:function(t,e){return ee(t,Qt(e,t))},nearest:function(t,e,n){var i=Qt(e,t);n.axis=n.axis||"xy";var a=ie(n.axis);return ne(t,i,n.intersect,a)},x:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inXRange(i.x)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a},y:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a}}},oe=H.extend;function se(t,e){return H.where(t,(function(t){return t.pos===e}))}function le(t,e){return t.sort((function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i.index-a.index:i.weight-a.weight}))}function ue(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function de(t,e,n){var i,a,r=n.box,o=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?r.height:r.width,t[n.pos]+=n.size,r.getPadding){var s=r.getPadding();o.top=Math.max(o.top,s.top),o.left=Math.max(o.left,s.left),o.bottom=Math.max(o.bottom,s.bottom),o.right=Math.max(o.right,s.right)}if(i=e.outerWidth-ue(o,t,"left","right"),a=e.outerHeight-ue(o,t,"top","bottom"),i!==t.w||a!==t.h){t.w=i,t.h=a;var l=n.horizontal?[i,t.w]:[a,t.h];return!(l[0]===l[1]||isNaN(l[0])&&isNaN(l[1]))}}function he(t,e){var n=e.maxPadding;function i(t){var i={left:0,top:0,right:0,bottom:0};return t.forEach((function(t){i[t]=Math.max(e[t],n[t])})),i}return i(t?["left","right"]:["top","bottom"])}function ce(t,e,n){var i,a,r,o,s,l,u=[];for(i=0,a=t.length;idiv{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}"}))&&ge.default||ge,ve="$chartjs",be="chartjs-size-monitor",xe="chartjs-render-monitor",ye="chartjs-render-animation",_e=["animationstart","webkitAnimationStart"],ke={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function we(t,e){var n=H.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var Me=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function Se(t,e,n){t.addEventListener(e,n,Me)}function Ce(t,e,n){t.removeEventListener(e,n,Me)}function Pe(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Ae(t){var e=document.createElement("div");return e.className=t||"",e}function De(t,e,n){var i,a,r,o,s=t[ve]||(t[ve]={}),l=s.resizer=function(t){var e=Ae(be),n=Ae(be+"-expand"),i=Ae(be+"-shrink");n.appendChild(Ae()),i.appendChild(Ae()),e.appendChild(n),e.appendChild(i),e._reset=function(){n.scrollLeft=1e6,n.scrollTop=1e6,i.scrollLeft=1e6,i.scrollTop=1e6};var a=function(){e._reset(),t()};return Se(n,"scroll",a.bind(n,"expand")),Se(i,"scroll",a.bind(i,"shrink")),e}((i=function(){if(s.resizer){var i=n.options.maintainAspectRatio&&t.parentNode,a=i?i.clientWidth:0;e(Pe("resize",n)),i&&i.clientWidth0){var r=t[0];r.label?n=r.label:r.xLabel?n=r.xLabel:a>0&&r.index-1?t.split("\n"):t}function Ve(t){var e=N.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:ze(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:ze(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:ze(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:ze(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:ze(t.titleFontStyle,e.defaultFontStyle),titleFontSize:ze(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:ze(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:ze(t.footerFontStyle,e.defaultFontStyle),footerFontSize:ze(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function He(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function je(t){return Ee([],We(t))}var qe=K.extend({initialize:function(){this._model=Ve(this._options),this._lastActive=[]},getTitle:function(){var t=this,e=t._options,n=e.callbacks,i=n.beforeTitle.apply(t,arguments),a=n.title.apply(t,arguments),r=n.afterTitle.apply(t,arguments),o=[];return o=Ee(o,We(i)),o=Ee(o,We(a)),o=Ee(o,We(r))},getBeforeBody:function(){return je(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return H.each(t,(function(t){var r={before:[],lines:[],after:[]};Ee(r.before,We(i.beforeLabel.call(n,t,e))),Ee(r.lines,i.label.call(n,t,e)),Ee(r.after,We(i.afterLabel.call(n,t,e))),a.push(r)})),a},getAfterBody:function(){return je(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this,e=t._options.callbacks,n=e.beforeFooter.apply(t,arguments),i=e.footer.apply(t,arguments),a=e.afterFooter.apply(t,arguments),r=[];return r=Ee(r,We(n)),r=Ee(r,We(i)),r=Ee(r,We(a))},update:function(t){var e,n,i,a,r,o,s,l,u,d,h=this,c=h._options,f=h._model,g=h._model=Ve(c),p=h._active,m=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},x={width:f.width,height:f.height},y={x:f.caretX,y:f.caretY};if(p.length){g.opacity=1;var _=[],k=[];y=Be[c.position].call(h,p,h._eventPosition);var w=[];for(e=0,n=p.length;ei.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===d?r+=h:r-="bottom"===d?e.height+h:e.height/2,"center"===d?"left"===u?a+=h:"right"===u&&(a-=h):"left"===u?a-=c:"right"===u&&(a+=c),{x:a,y:r}}(g,x,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.yl.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,x),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=x.width,g.height=x.height,g.caretX=y.x,g.caretY=y.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===c)s=g+m/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+p)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+p-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+m)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n){var i,a,r,o=e.title,s=o.length;if(s){var l=Ne(e.rtl,e.x,e.width);for(t.x=He(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=H.fontString(i,e._titleFontStyle,e._titleFontFamily),r=0;r0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(t.save(),t.globalAlpha=a,this.drawBackground(i,e,t,n),i.y+=e.yPadding,H.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),H.rtl.restoreTextDirection(t,e.textDirection),t.restore())}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],"mouseout"===t.type?n._active=[]:(n._active=n._chart.getElementsAtEventForMode(t,i.mode,i),i.reverse&&n._active.reverse()),(e=!H.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}}),Ue=Be,Ye=qe;Ye.positioners=Ue;var Ge=H.valueOrDefault;function Xe(){return H.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var a,r,o,s=n[t].length;for(e[t]||(e[t]=[]),a=0;a=e[t].length&&e[t].push({}),!e[t][a].type||o.type&&o.type!==e[t][a].type?H.merge(e[t][a],[Re.getScaleDefaults(r),o]):H.merge(e[t][a],o)}else H._merger(t,e,n,i)}})}function Ke(){return H.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){var a=e[t]||Object.create(null),r=n[t];"scales"===t?e[t]=Xe(a,r):"scale"===t?e[t]=H.merge(a,[Re.getScaleDefaults(r.type),r]):H._merger(t,e,n,i)}})}function Ze(t){var e=t.options;H.each(t.scales,(function(e){pe.removeBox(t,e)})),e=Ke(N.global,N[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function $e(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(H.findIndex(t,a)>=0);return i}function Je(t){return"top"===t||"bottom"===t}function Qe(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}N._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var tn=function(t,e){return this.construct(t,e),this};H.extend(tn.prototype,{construct:function(t,e){var n=this;e=function(t){var e=(t=t||Object.create(null)).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=Ke(N.global,N[t.type],t.options||{}),t}(e);var i=Oe.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=H.uid(),n.ctx=i,n.canvas=a,n.config=e,n.width=o,n.height=r,n.aspectRatio=r?o/r:null,n.options=e.options,n._bufferedRender=!1,n._layers=[],n.chart=n,n.controller=n,tn.instances[n.id]=n,Object.defineProperty(n,"data",{get:function(){return n.config.data},set:function(t){n.config.data=t}}),i&&a?(n.initialize(),n.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Le.notify(t,"beforeInit"),H.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Le.notify(t,"afterInit"),t},clear:function(){return H.canvas.clear(this),this},stop:function(){return J.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(H.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:H.getMaximumHeight(i)));if((e.width!==r||e.height!==o)&&(i.width=e.width=r,i.height=e.height=o,i.style.width=r+"px",i.style.height=o+"px",H.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Le.notify(e,"resize",[s]),n.onResize&&n.onResize(e,s),e.stop(),e.update({duration:n.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;H.each(e.xAxes,(function(t,n){t.id||(t.id=$e(e.xAxes,"x-axis-",n))})),H.each(e.yAxes,(function(t,n){t.id||(t.id=$e(e.yAxes,"y-axis-",n))})),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,n=t.scales||{},i=[],a=Object.keys(n).reduce((function(t,e){return t[e]=!1,t}),{});e.scales&&(i=i.concat((e.scales.xAxes||[]).map((function(t){return{options:t,dtype:"category",dposition:"bottom"}})),(e.scales.yAxes||[]).map((function(t){return{options:t,dtype:"linear",dposition:"left"}})))),e.scale&&i.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),H.each(i,(function(e){var i=e.options,r=i.id,o=Ge(i.type,e.dtype);Je(i.position)!==Je(e.dposition)&&(i.position=e.dposition),a[r]=!0;var s=null;if(r in n&&n[r].type===o)(s=n[r]).options=i,s.ctx=t.ctx,s.chart=t;else{var l=Re.getScaleConstructor(o);if(!l)return;s=new l({id:r,type:o,options:i,ctx:t.ctx,chart:t}),n[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)})),H.each(a,(function(t,e){t||delete n[e]})),t.scales=n,Re.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t,e,n=this,i=[],a=n.data.datasets;for(t=0,e=a.length;t=0;--n)this.drawDataset(e[n],t);Le.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Le.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Le.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Le.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Le.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return re.modes.single(this,t)},getElementsAtEvent:function(t){return re.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return re.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=re.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return re.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e.order||0,index:t}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e3?n[2]-n[1]:n[1]-n[0];Math.abs(i)>1&&t!==Math.floor(t)&&(i=t-Math.floor(t));var a=H.log10(Math.abs(i)),r="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=H.log10(Math.abs(t)),s=Math.floor(o)-Math.floor(a);s=Math.max(Math.min(s,20),0),r=t.toExponential(s)}else{var l=-1*Math.floor(a);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(H.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},sn=H.isArray,ln=H.isNullOrUndef,un=H.valueOrDefault,dn=H.valueAtIndexOrDefault;function hn(t,e,n){var i,a=t.getTicks().length,r=Math.min(e,a-1),o=t.getPixelForTick(r),s=t._startPixel,l=t._endPixel;if(!(n&&(i=1===a?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(r-1))/2,(o+=rl+1e-6)))return o}function cn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,p,m,v=n.length,b=[],x=[],y=[],_=0,k=0;for(a=0;ae){for(n=0;n=c||d<=1||!s.isHorizontal()?s.labelRotation=h:(e=(t=s._getLabelSizes()).widest.width,n=t.highest.height-t.highest.offset,i=Math.min(s.maxWidth,s.chart.width-e),e+6>(a=l.offset?s.maxWidth/d:i/(d-1))&&(a=i/(d-(l.offset?.5:1)),r=s.maxHeight-fn(l.gridLines)-u.padding-gn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=H.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/a,1)),Math.asin(Math.min(r/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){H.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){H.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=t.chart,i=t.options,a=i.ticks,r=i.scaleLabel,o=i.gridLines,s=t._isVisible(),l="bottom"===i.position,u=t.isHorizontal();if(u?e.width=t.maxWidth:s&&(e.width=fn(o)+gn(r)),u?s&&(e.height=fn(o)+gn(r)):e.height=t.maxHeight,a.display&&s){var d=mn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,p=h.highest,m=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,x=H.toRadians(t.labelRotation),y=Math.cos(x),_=Math.sin(x),k=_*g.width+y*(p.height-(b?p.offset:0))+(b?0:m);e.height=Math.min(t.maxHeight,e.height+k+v);var w,M,S=t.getPixelForTick(0)-t.left,C=t.right-t.getPixelForTick(t.getTicks().length-1);b?(w=l?y*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):y*f.width+_*f.offset):(w=c.width/2,M=f.width/2),t.paddingLeft=Math.max((w-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-C)*t.width/(t.width-C),0)+3}else{var P=a.mirror?0:g.width+v+m;e.width=Math.min(t.maxWidth,e.width+P),t.paddingTop=c.height/2,t.paddingBottom=f.height/2}}t.handleMargins(),u?(t.width=t._length=n.width-t.margins.left-t.margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=n.height-t.margins.top-t.margins.bottom)},handleMargins:function(){var t=this;t.margins&&(t.margins.left=Math.max(t.paddingLeft,t.margins.left),t.margins.top=Math.max(t.paddingTop,t.margins.top),t.margins.right=Math.max(t.paddingRight,t.margins.right),t.margins.bottom=Math.max(t.paddingBottom,t.margins.bottom))},afterFit:function(){H.callback(this.options.afterFit,[this])},isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(ln(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},_convertTicksToLabels:function(t){var e,n,i,a=this;for(a.ticks=t.map((function(t){return t.value})),a.beforeTickToLabelConversion(),e=a.convertTicksToLabels(t)||a.ticks,a.afterTickToLabelConversion(),n=0,i=t.length;nn-1?null:this.getPixelForDecimal(t*i+(e?i/2:0))},getPixelForDecimal:function(t){return this._reversePixels&&(t=1-t),this._startPixel+t*this._length},getDecimalForPixel:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,i,a,r=this.options.ticks,o=this._length,s=r.maxTicksLimit||o/this._tickSize()+1,l=r.major.enabled?function(t){var e,n,i=[];for(e=0,n=t.length;es)return function(t,e,n){var i,a,r=0,o=e[0];for(n=Math.ceil(n),i=0;iu)return r;return Math.max(u,1)}(l,t,0,s),u>0){for(e=0,n=u-1;e1?(h-d)/(u-1):null,bn(t,i,H.isNullOrUndef(a)?0:d-a,d),bn(t,i,h,H.isNullOrUndef(a)?t.length:h+a),vn(t)}return bn(t,i),vn(t)},_tickSize:function(){var t=this.options.ticks,e=H.toRadians(this.labelRotation),n=Math.abs(Math.cos(e)),i=Math.abs(Math.sin(e)),a=this._getLabelSizes(),r=t.autoSkipPadding||0,o=a?a.widest.width+r:0,s=a?a.highest.height+r:0;return this.isHorizontal()?s*n>o*i?o/n:s/i:s*i=0&&(o=t),void 0!==r&&(t=n.indexOf(r))>=0&&(s=t),e.minIndex=o,e.maxIndex=s,e.min=n[o],e.max=n[s]},buildTicks:function(){var t=this._getLabels(),e=this.minIndex,n=this.maxIndex;this.ticks=0===e&&n===t.length-1?t:t.slice(e,n+1)},getLabelForIndex:function(t,e){var n=this.chart;return n.getDatasetMeta(e).controller._getValueScaleId()===this.id?this.getRightValue(n.data.datasets[e].data[t]):this._getLabels()[t]},_configure:function(){var t=this,e=t.options.offset,n=t.ticks;yn.prototype._configure.call(t),t.isHorizontal()||(t._reversePixels=!t._reversePixels),n&&(t._startValue=t.minIndex-(e?.5:0),t._valueRange=Math.max(n.length-(e?0:1),1))},getPixelForValue:function(t,e,n){var i,a,r,o=this;return _n(e)||_n(n)||(t=o.chart.data.datasets[n].data[e]),_n(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=H.valueOrDefault(i,t),e=-1!==(r=a.indexOf(t))?r:e,isNaN(e)&&(e=t)),o.getPixelForDecimal((e-o._startValue)/o._valueRange)},getPixelForTick:function(t){var e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t],t+this.minIndex)},getValueForPixel:function(t){var e=Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange);return Math.min(Math.max(e,0),this.ticks.length-1)},getBasePixel:function(){return this.bottom}}),wn={position:"bottom"};kn._defaults=wn;var Mn=H.noop,Sn=H.isNullOrUndef;var Cn=yn.extend({getRightValue:function(t){return"string"==typeof t?+t:yn.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=H.sign(t.min),i=H.sign(t.max);n<0&&i<0?t.max=0:n>0&&i>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==r&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this.options.ticks,n=e.stepSize,i=e.maxTicksLimit;return n?t=Math.ceil(this.max/n)-Math.floor(this.min/n)+1:(t=this._computeTickLimit(),i=i||11),i&&(t=Math.min(i,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:Mn,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),i={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:H.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var n,i,a,r,o=[],s=t.stepSize,l=s||1,u=t.maxTicks-1,d=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,p=H.niceNum((g-f)/u/l)*l;if(p<1e-14&&Sn(d)&&Sn(h))return[f,g];(r=Math.ceil(g/p)-Math.floor(f/p))>u&&(p=H.niceNum(r*p/u/l)*l),s||Sn(c)?n=Math.pow(10,H._decimalPlaces(p)):(n=Math.pow(10,c),p=Math.ceil(p*n)/n),i=Math.floor(f/p)*p,a=Math.ceil(g/p)*p,s&&(!Sn(d)&&H.almostWhole(d/p,p/1e3)&&(i=d),!Sn(h)&&H.almostWhole(h/p,p/1e3)&&(a=h)),r=(a-i)/p,r=H.almostEquals(r,Math.round(r),p/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Sn(d)?i:d);for(var m=1;me.length-1?null:this.getPixelForValue(e[t])}}),In=Pn;Tn._defaults=In;var Fn=H.valueOrDefault,On=H.math.log10;var Ln={position:"left",ticks:{callback:on.formatters.logarithmic}};function Rn(t,e){return H.isFinite(t)&&t>=0?t:e}var zn=yn.extend({determineDataLimits:function(){var t,e,n,i,a,r,o=this,s=o.options,l=o.chart,u=l.data.datasets,d=o.isHorizontal();function h(t){return d?t.xAxisID===o.id:t.yAxisID===o.id}o.min=Number.POSITIVE_INFINITY,o.max=Number.NEGATIVE_INFINITY,o.minNotZero=Number.POSITIVE_INFINITY;var c=s.stacked;if(void 0===c)for(t=0;t0){var e=H.min(t),n=H.max(t);o.min=Math.min(o.min,e),o.max=Math.max(o.max,n)}}))}else for(t=0;t0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(On(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:Rn(e.min),max:Rn(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=Fn(t.min,Math.pow(10,Math.floor(On(e.min)))),o=Math.floor(On(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(On(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(On(r)),i=Math.floor(r/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{a.push(r),10===++i&&(i=1,l=++n>=0?1:l),r=Math.round(i*Math.pow(10,n)*l)/l}while(ne.length-1?null:this.getPixelForValue(e[t])},_getFirstTickValue:function(t){var e=Math.floor(On(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;yn.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=Fn(t.options.ticks.fontSize,N.global.defaultFontSize)/t._length),t._startValue=On(e),t._valueOffset=n,t._valueRange=(On(t.max)-On(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(On(t)-e._startValue)/e._valueRange+e._valueOffset),e.getPixelForDecimal(n)},getValueForPixel:function(t){var e=this,n=e.getDecimalForPixel(t);return 0===n&&0===e.min?0:Math.pow(10,e._startValue+(n-e._valueOffset)*e._valueRange)}}),Nn=Ln;zn._defaults=Nn;var Bn=H.valueOrDefault,En=H.valueAtIndexOrDefault,Wn=H.options.resolve,Vn={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:on.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Hn(t){var e=t.ticks;return e.display&&t.display?Bn(e.fontSize,N.global.defaultFontSize)+2*e.backdropPaddingY:0}function jn(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:ta?{start:e-n,end:e}:{start:e,end:e+n}}function qn(t){return 0===t||180===t?"center":t<180?"left":"right"}function Un(t,e,n,i){var a,r,o=n.y+i/2;if(H.isArray(e))for(a=0,r=e.length;a270||t<90)&&(n.y-=e.h)}function Gn(t){return H.isNumber(t)?t:0}var Xn=Cn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Hn(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;H.each(e.data.datasets,(function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);H.each(a.data,(function(e,a){var r=+t.getRightValue(e);isNaN(r)||o.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))}))}})),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Hn(this.options))},convertTicksToLabels:function(){var t=this;Cn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map((function(){var e=H.callback(t.options.pointLabels.callback,arguments,t);return e||0===e?e:""}))},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this.options;t.display&&t.pointLabels.display?function(t){var e,n,i,a=H.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},o={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,u,d=t.chart.data.labels.length;for(e=0;er.r&&(r.r=f.end,o.r=h),g.startr.b&&(r.b=g.end,o.b=h)}t.setReductions(t.drawingArea,r,o)}(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-(i.height-i.paddingTop),0)/Math.cos(n.b);a=Gn(a),r=Gn(r),o=Gn(o),s=Gn(s),i.drawingArea=Math.min(Math.floor(t-(a+r)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-a.paddingTop-i-a.drawingArea;a.xCenter=Math.floor((o+r)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?n+360:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(H.isNullOrUndef(t))return NaN;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(n)*e+this.xCenter,y:Math.sin(n)*e+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(t){var e=this.min,n=this.max;return this.getPointPositionForValue(t||0,this.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},_drawGrid:function(){var t,e,n,i=this,a=i.ctx,r=i.options,o=r.gridLines,s=r.angleLines,l=Bn(s.lineWidth,o.lineWidth),u=Bn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Hn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=H.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s=t.chart.data.labels.length-1;s>=0;s--){var l=0===s?a/2:0,u=t.getPointPosition(s,r+l+5),d=En(i.fontColor,s,N.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=H.toDegrees(h);e.textAlign=qn(c),Yn(c,t._pointLabelSizes[s],u),Un(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&H.each(i.ticks,(function(t,n){0!==n&&(e=i.getDistanceFromCenterForValue(i.ticksAsNumbers[n]),function(t,e,n,i){var a,r=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=En(e.color,i-1),u=En(e.lineWidth,i-1);if((o||s)&&l&&u){if(r.save(),r.strokeStyle=l,r.lineWidth=u,r.setLineDash&&(r.setLineDash(e.borderDash||[]),r.lineDashOffset=e.borderDashOffset||0),r.beginPath(),o)r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{a=t.getPointPosition(0,n),r.moveTo(a.x,a.y);for(var d=1;d=0;t--)e=i.getDistanceFromCenterForValue(r.ticks.reverse?i.min:i.max),n=i.getPointPosition(t,e),a.beginPath(),a.moveTo(i.xCenter,i.yCenter),a.lineTo(n.x,n.y),a.stroke();a.restore()}},_drawLabels:function(){var t=this,e=t.ctx,n=t.options.ticks;if(n.display){var i,a,r=t.getIndexAngle(0),o=H.options._parseFont(n),s=Bn(n.fontColor,N.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",H.each(t.ticks,(function(r,l){(0!==l||n.reverse)&&(i=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),n.showLabelBackdrop&&(a=e.measureText(r).width,e.fillStyle=n.backdropColor,e.fillRect(-a/2-n.backdropPaddingX,-i-o.size/2-n.backdropPaddingY,a+2*n.backdropPaddingX,o.size+2*n.backdropPaddingY)),e.fillStyle=s,e.fillText(r,0,-i))})),e.restore()}},_drawTitle:H.noop}),Kn=Vn;Xn._defaults=Kn;var Zn=H._deprecated,$n=H.options.resolve,Jn=H.valueOrDefault,Qn=Number.MIN_SAFE_INTEGER||-9007199254740991,ti=Number.MAX_SAFE_INTEGER||9007199254740991,ei={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ni=Object.keys(ei);function ii(t,e){return t-e}function ai(t){return H.valueOrDefault(t.time.min,t.ticks.min)}function ri(t){return H.valueOrDefault(t.time.max,t.ticks.max)}function oi(t,e,n,i){var a=function(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(a=t[(i=o+s>>1)-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(n-r[e])/s:0,u=(o[i]-r[i])*l;return r[i]+u}function si(t,e){var n=t._adapter,i=t.options.time,a=i.parser,r=a||i.format,o=e;return"function"==typeof a&&(o=a(o)),H.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),H.isFinite(o)||(o=n.parse(o))),o)}function li(t,e){if(H.isNullOrUndef(e))return null;var n=t.options.time,i=si(t,t.getRightValue(e));return null===i?i:(n.round&&(i=+t._adapter.startOf(i,n.round)),i)}function ui(t,e,n,i){var a,r,o,s=ni.length;for(a=ni.indexOf(t);a=0&&(e[r].major=!0);return e}(t,r,o,n):r}var hi=yn.extend({initialize:function(){this.mergeTicksOptions(),yn.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new rn._date(e.adapters.date);return Zn("time scale",n.format,"time.format","time.parser"),Zn("time scale",n.min,"time.min","ticks.min"),Zn("time scale",n.max,"time.max","ticks.max"),H.mergeIf(n.displayFormats,i.formats()),yn.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),yn.prototype.getRightValue.call(this,t)},determineDataLimits:function(){var t,e,n,i,a,r,o,s=this,l=s.chart,u=s._adapter,d=s.options,h=d.time.unit||"day",c=ti,f=Qn,g=[],p=[],m=[],v=s._getLabels();for(t=0,n=v.length;t1?function(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(a=h;a=a&&n<=r&&d.push(n);return i.min=a,i.max=r,i._unit=l.unit||(s.autoSkip?ui(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ni.length-1;r>=ni.indexOf(n);r--)if(o=ni[r],ei[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ni[n?ni.indexOf(n):0]}(i,d.length,l.minUnit,i.min,i.max)),i._majorUnit=s.major.enabled&&"year"!==i._unit?function(t){for(var e=ni.indexOf(t)+1,n=ni.length;ee&&s=0&&t0?s:1}}),ci={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};hi._defaults=ci;var fi={category:kn,linear:Tn,logarithmic:zn,radialLinear:Xn,time:hi},gi={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};rn._date.override("function"==typeof t?{_id:"moment",formats:function(){return gi},parse:function(e,n){return"string"==typeof e&&"string"==typeof n?e=t(e,n):e instanceof t||(e=t(e)),e.isValid()?e.valueOf():null},format:function(e,n){return t(e).format(n)},add:function(e,n,i){return t(e).add(n,i).valueOf()},diff:function(e,n,i){return t(e).diff(t(n),i)},startOf:function(e,n,i){return e=t(e),"isoWeek"===n?e.isoWeekday(i).valueOf():e.startOf(n).valueOf()},endOf:function(e,n){return t(e).endOf(n).valueOf()},_create:function(e){return t(e)}}:{}),N._set("global",{plugins:{filler:{propagate:!0}}});var pi={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function vi(t){return(t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,a,r,o=t.el._scale,s=o.options,l=o.chart.data.labels.length,u=t.fill,d=[];if(!l)return null;for(e=s.ticks.reverse?o.max:o.min,n=s.ticks.reverse?o.min:o.max,i=o.getPointPositionForValue(0,e),a=0;a0;--r)H.canvas.lineTo(t,n[r],n[r-1],!0);else for(o=n[0].cx,s=n[0].cy,l=Math.sqrt(Math.pow(n[0].x-o,2)+Math.pow(n[0].y-s,2)),r=a-1;r>0;--r)t.arc(o,s,l,n[r].angle,n[r-1].angle,!0)}}function ki(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,p=i.spanGaps,m=[],v=[],b=0,x=0;for(t.beginPath(),o=0,s=g;o=0;--n)(e=l[n].$filler)&&e.visible&&(a=(i=e.el)._view,r=i._children||[],o=e.mapper,s=a.backgroundColor||N.global.defaultColor,o&&s&&r.length&&(H.canvas.clipArea(u,t.chartArea),ki(u,r,o,a,s,i._loop),H.canvas.unclipArea(u)))}},Mi=H.rtl.getRtlAdapter,Si=H.noop,Ci=H.valueOrDefault;function Pi(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}N._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data.datasets,n=t.options.legend||{},i=n.labels&&n.labels.usePointStyle;return t._getSortedDatasetMetas().map((function(n){var a=n.controller.getStyle(i?0:void 0);return{text:e[n.index].label,fillStyle:a.backgroundColor,hidden:!t.isDatasetVisible(n.index),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,rotation:a.rotation,datasetIndex:n.index}}),this)}}},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data.datasets;for(a.setAttribute("class",t.id+"-legend"),e=0,n=r.length;el.width)&&(h+=o+n.padding,d[d.length-(e>0?0:1)]=0),s[e]={left:0,top:0,width:i,height:o},d[d.length-1]+=i+n.padding})),l.height+=h}else{var c=n.padding,f=t.columnWidths=[],g=t.columnHeights=[],p=n.padding,m=0,v=0;H.each(t.legendItems,(function(t,e){var i=Pi(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(p+=m+n.padding,f.push(m),g.push(v),m=0,v=0),m=Math.max(m,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}})),p+=m,f.push(m),g.push(v),l.width+=p}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Si,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=N.global,a=i.defaultColor,r=i.elements.line,o=t.height,s=t.columnHeights,l=t.width,u=t.lineWidths;if(e.display){var d,h=Mi(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Ci(n.fontColor,i.defaultFontColor),g=H.options._parseFont(n),p=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var m=Pi(n,p),v=t.legendHitBoxes,b=function(t,i){switch(e.align){case"start":return n.padding;case"end":return t-i;default:return(t-i+n.padding)/2}},x=t.isHorizontal();d=x?{x:t.left+b(l,u[0]),y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+b(o,s[0]),line:0},H.rtl.overrideTextDirection(t.ctx,e.textDirection);var y=p+n.padding;H.each(t.legendItems,(function(e,i){var f=c.measureText(e.text).width,g=m+p/2+f,_=d.x,k=d.y;h.setWidth(t.minSize.width),x?i>0&&_+g+n.padding>t.left+t.minSize.width&&(k=d.y+=y,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&k+y>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,k=d.y=t.top+b(o,s[d.line]));var w=h.x(_);!function(t,e,i){if(!(isNaN(m)||m<=0)){c.save();var o=Ci(i.lineWidth,r.borderWidth);if(c.fillStyle=Ci(i.fillStyle,a),c.lineCap=Ci(i.lineCap,r.borderCapStyle),c.lineDashOffset=Ci(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Ci(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Ci(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Ci(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=m*Math.SQRT2/2,l=h.xPlus(t,m/2),u=e+p/2;H.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,m),e,m,p),0!==o&&c.strokeRect(h.leftForLtr(t,m),e,m,p);c.restore()}}(w,k,e),v[i].left=h.leftForLtr(w,v[i].width),v[i].top=k,function(t,e,n,i){var a=p/2,r=h.xPlus(t,m+a),o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(h.xPlus(r,i),o),c.stroke())}(w,k,e,f),x?d.x+=g+n.padding:d.y+=y})),H.rtl.restoreTextDirection(t.ctx,e.textDirection)}},_getLegendItemAt:function(t,e){var n,i,a,r=this;if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)for(a=r.legendHitBoxes,n=0;n=(i=a[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return r.legendItems[n];return null},handleEvent:function(t){var e,n=this,i=n.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!i.onHover&&!i.onLeave)return}else{if("click"!==a)return;if(!i.onClick)return}e=n._getLegendItemAt(t.x,t.y),"click"===a?e&&i.onClick&&i.onClick.call(n,t.native,e):(i.onLeave&&e!==n._hoveredItem&&(n._hoveredItem&&i.onLeave.call(n,t.native,n._hoveredItem),n._hoveredItem=e),i.onHover&&e&&i.onHover.call(n,t.native,e))}});function Di(t,e){var n=new Ai({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.legend=n}var Ti={id:"legend",_element:Ai,beforeInit:function(t){var e=t.options.legend;e&&Di(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(H.mergeIf(e,N.global.legend),n?(pe.configure(t,n,e),n.options=e):Di(t,e)):n&&(pe.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Ii=H.noop;N._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Fi=K.extend({initialize:function(t){H.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:Ii,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Ii,beforeSetDimensions:Ii,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Ii,beforeBuildLabels:Ii,buildLabels:Ii,afterBuildLabels:Ii,beforeFit:Ii,fit:function(){var t,e=this,n=e.options,i=e.minSize={},a=e.isHorizontal();n.display?(t=(H.isArray(n.text)?n.text.length:1)*H.options._parseFont(n).lineHeight+2*n.padding,e.width=i.width=a?e.maxWidth:t,e.height=i.height=a?t:e.maxHeight):e.width=i.width=e.height=i.height=0},afterFit:Ii,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=t.options;if(n.display){var i,a,r,o=H.options._parseFont(n),s=o.lineHeight,l=s/2+n.padding,u=0,d=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=H.valueOrDefault(n.fontColor,N.global.defaultFontColor),e.font=o.string,t.isHorizontal()?(a=h+(f-h)/2,r=d+l,i=f-h):(a="left"===n.position?h+l:f-l,r=d+(c-d)/2,i=c-d,u=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(a,r),e.rotate(u),e.textAlign="center",e.textBaseline="middle";var g=n.text;if(H.isArray(g))for(var p=0,m=0;m=0;i--){var a=t[i];if(e(a))return a}},H.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},H.almostEquals=function(t,e,n){return Math.abs(t-e)=t},H.max=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.max(t,e)}),Number.NEGATIVE_INFINITY)},H.min=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.min(t,e)}),Number.POSITIVE_INFINITY)},H.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},H.toRadians=function(t){return t*(Math.PI/180)},H.toDegrees=function(t){return t*(180/Math.PI)},H._decimalPlaces=function(t){if(H.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},H.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},H.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},H.aliasPixel=function(t){return t%2==0?0:.5},H._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},H.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},H.EPSILON=Number.EPSILON||1e-14,H.splineCurveMonotone=function(t){var e,n,i,a,r,o,s,l,u,d=(t||[]).map((function(t){return{model:t._model,deltaK:0,mK:0}})),h=d.length;for(e=0;e0?d[e-1]:null,(a=e0?d[e-1]:null,a=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},H.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},H.niceNum=function(t,e){var n=Math.floor(H.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},H.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},H.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.target||t.srcElement,o=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var l=parseFloat(H.getStyle(r,"padding-left")),u=parseFloat(H.getStyle(r,"padding-top")),d=parseFloat(H.getStyle(r,"padding-right")),h=parseFloat(H.getStyle(r,"padding-bottom")),c=o.right-o.left-l-d,f=o.bottom-o.top-u-h;return{x:n=Math.round((n-o.left-l)/c*r.width/e.currentDevicePixelRatio),y:i=Math.round((i-o.top-u)/f*r.height/e.currentDevicePixelRatio)}},H.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},H.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},H._calculatePadding=function(t,e,n){return(e=H.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},H._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},H.getMaximumWidth=function(t){var e=H._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-H._calculatePadding(e,"padding-left",n)-H._calculatePadding(e,"padding-right",n),a=H.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},H.getMaximumHeight=function(t){var e=H._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-H._calculatePadding(e,"padding-top",n)-H._calculatePadding(e,"padding-bottom",n),a=H.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},H.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},H.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},H.fontString=function(t,e,n){return e+" "+t+"px "+n},H.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var o,s,l,u,d,h=0,c=n.length;for(o=0;on.length){for(o=0;oi&&(i=r),i},H.numberOfLabelLines=function(t){var e=1;return H.each(t,(function(t){H.isArray(t)&&t.length>e&&(e=t.length)})),e},H.color=_?function(t){return t instanceof CanvasGradient&&(t=N.global.defaultColor),_(t)}:function(t){return console.error("Color.js not found!"),t},H.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:H.color(t).saturate(.5).darken(.1).rgbString()}}(),en._adapters=rn,en.Animation=$,en.animationService=J,en.controllers=Jt,en.DatasetController=it,en.defaults=N,en.Element=K,en.elements=kt,en.Interaction=re,en.layouts=pe,en.platform=Oe,en.plugins=Le,en.Scale=yn,en.scaleService=Re,en.Ticks=on,en.Tooltip=Ye,en.helpers.each(fi,(function(t,e){en.scaleService.registerScaleType(e,t,t._defaults)})),Li)Li.hasOwnProperty(Bi)&&en.plugins.register(Li[Bi]);en.platform.initialize();var Ei=en;return"undefined"!=typeof window&&(window.Chart=en),en.Chart=en,en.Legend=Li.legend._element,en.Title=Li.title._element,en.pluginService=en.plugins,en.PluginBase=en.Element.extend({}),en.canvasHelpers=en.helpers.canvas,en.layoutService=en.layouts,en.LinearScaleBase=Cn,en.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],(function(t){en[t]=function(e,n){return new en(e,en.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}})),Ei})); From 9746a8427c82e43b7bf905ccbff4ba8420d0eca5 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 9 May 2021 22:04:14 -0500 Subject: [PATCH 34/67] Use adafruit/Adafruit NeoPixel@~1.8.0 --- ini/features.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ini/features.ini b/ini/features.ini index 6fa74a343f..586af1653f 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -27,7 +27,7 @@ HAS_TMC26X = TMC26XStepper=https://github.com/trinam src_filter=+ HAS_L64XX = Arduino-L6470@0.8.0 src_filter=+ + + + -NEOPIXEL_LED = Adafruit NeoPixel@1.5.0 +NEOPIXEL_LED = adafruit/Adafruit NeoPixel@~1.8.0 src_filter=+ TEMP_.+_IS_MAX31865 = Adafruit MAX31865 library@~1.1.0 USES_LIQUIDCRYSTAL = fmalpartida/LiquidCrystal@1.5.0 From 026431679747ff972be14e8de8433c0d2e20326e Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 11 May 2021 02:59:54 -0500 Subject: [PATCH 35/67] Fix L64xx init for Z4 --- Marlin/src/module/stepper/L64xx.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Marlin/src/module/stepper/L64xx.cpp b/Marlin/src/module/stepper/L64xx.cpp index 3e2bf09446..004e17a3fd 100644 --- a/Marlin/src/module/stepper/L64xx.cpp +++ b/Marlin/src/module/stepper/L64xx.cpp @@ -196,6 +196,9 @@ void L64XX_Marlin::init_to_defaults() { #if AXIS_IS_L64XX(Z3) L6470_INIT_CHIP(Z3); #endif + #if AXIS_IS_L64XX(Z4) + L6470_INIT_CHIP(Z4); + #endif #if AXIS_IS_L64XX(E0) L6470_INIT_CHIP(E0); #endif From e5dc2c53215020cd2c2caeb519a51d4bd430ecc0 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 11 May 2021 08:30:16 -0500 Subject: [PATCH 36/67] Simplify macro expansion with recursion (#21859) --- Marlin/src/core/macros.h | 36 +++----- Marlin/src/core/serial.h | 164 +++++++-------------------------- Marlin/src/module/settings.cpp | 4 +- 3 files changed, 51 insertions(+), 153 deletions(-) diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h index b026af1187..34d9e530ca 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -301,8 +301,12 @@ #define HYPOT(x,y) SQRT(HYPOT2(x,y)) // Use NUM_ARGS(__VA_ARGS__) to get the number of variadic arguments -#define _NUM_ARGS(_,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A,OUT,...) OUT -#define NUM_ARGS(V...) _NUM_ARGS(0,V,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) +#define _NUM_ARGS(_,n,m,l,k,j,i,h,g,f,e,d,c,b,a,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A,OUT,...) OUT +#define NUM_ARGS(V...) _NUM_ARGS(0,V,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) + +// Use TWO_ARGS(__VA_ARGS__) to get whether there are 1, 2, or >2 arguments +#define _TWO_ARGS(_,n,m,l,k,j,i,h,g,f,e,d,c,b,a,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A,OUT,...) OUT +#define TWO_ARGS(V...) _TWO_ARGS(0,V,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,0) #ifdef __cplusplus @@ -414,31 +418,19 @@ #else - #define MIN_2(a,b) ((a)<(b)?(a):(b)) - #define MIN_3(a,V...) MIN_2(a,MIN_2(V)) - #define MIN_4(a,V...) MIN_2(a,MIN_3(V)) - #define MIN_5(a,V...) MIN_2(a,MIN_4(V)) - #define MIN_6(a,V...) MIN_2(a,MIN_5(V)) - #define MIN_7(a,V...) MIN_2(a,MIN_6(V)) - #define MIN_8(a,V...) MIN_2(a,MIN_7(V)) - #define MIN_9(a,V...) MIN_2(a,MIN_8(V)) - #define MIN_10(a,V...) MIN_2(a,MIN_9(V)) #define __MIN_N(N,V...) MIN_##N(V) #define _MIN_N(N,V...) __MIN_N(N,V) - #define _MIN(V...) _MIN_N(NUM_ARGS(V), V) + #define _MIN_N_REF() _MIN_N + #define _MIN(V...) EVAL(_MIN_N(TWO_ARGS(V),V)) + #define MIN_2(a,b) ((a)<(b)?(a):(b)) + #define MIN_3(a,V...) MIN_2(a,DEFER2(_MIN_N_REF)()(TWO_ARGS(V),V)) - #define MAX_2(a,b) ((a)>(b)?(a):(b)) - #define MAX_3(a,V...) MAX_2(a,MAX_2(V)) - #define MAX_4(a,V...) MAX_2(a,MAX_3(V)) - #define MAX_5(a,V...) MAX_2(a,MAX_4(V)) - #define MAX_6(a,V...) MAX_2(a,MAX_5(V)) - #define MAX_7(a,V...) MAX_2(a,MAX_6(V)) - #define MAX_8(a,V...) MAX_2(a,MAX_7(V)) - #define MAX_9(a,V...) MAX_2(a,MAX_8(V)) - #define MAX_10(a,V...) MAX_2(a,MAX_9(V)) #define __MAX_N(N,V...) MAX_##N(V) #define _MAX_N(N,V...) __MAX_N(N,V) - #define _MAX(V...) _MAX_N(NUM_ARGS(V), V) + #define _MAX_N_REF() _MAX_N + #define _MAX(V...) EVAL(_MAX_N(TWO_ARGS(V),V)) + #define MAX_2(a,b) ((a)>(b)?(a):(b)) + #define MAX_3(a,V...) MAX_2(a,DEFER2(_MAX_N_REF)()(TWO_ARGS(V),V)) #endif diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h index 5406bb3a7d..c8024f4b8c 100644 --- a/Marlin/src/core/serial.h +++ b/Marlin/src/core/serial.h @@ -182,139 +182,45 @@ inline void SERIAL_FLUSHTX() { SERIAL_IMPL.flushTX(); } // Print a single PROGMEM string to serial void serialprintPGM(PGM_P str); -// SERIAL_ECHOPAIR / SERIAL_ECHOPAIR_P is used to output a key value pair. The key must be a string and the value can be anything -// Print up to 12 pairs of values. Odd elements auto-wrapped in PSTR(). -#define __SEP_N(N,V...) _SEP_##N(V) -#define _SEP_N(N,V...) __SEP_N(N,V) -#define _SEP_1(PRE) SERIAL_ECHOPGM(PRE) -#define _SEP_2(PRE,V) serial_echopair_PGM(PSTR(PRE),V) -#define _SEP_3(a,b,c) do{ _SEP_2(a,b); SERIAL_ECHOPGM(c); }while(0) -#define _SEP_4(a,b,V...) do{ _SEP_2(a,b); _SEP_2(V); }while(0) -#define _SEP_5(a,b,V...) do{ _SEP_2(a,b); _SEP_3(V); }while(0) -#define _SEP_6(a,b,V...) do{ _SEP_2(a,b); _SEP_4(V); }while(0) -#define _SEP_7(a,b,V...) do{ _SEP_2(a,b); _SEP_5(V); }while(0) -#define _SEP_8(a,b,V...) do{ _SEP_2(a,b); _SEP_6(V); }while(0) -#define _SEP_9(a,b,V...) do{ _SEP_2(a,b); _SEP_7(V); }while(0) -#define _SEP_10(a,b,V...) do{ _SEP_2(a,b); _SEP_8(V); }while(0) -#define _SEP_11(a,b,V...) do{ _SEP_2(a,b); _SEP_9(V); }while(0) -#define _SEP_12(a,b,V...) do{ _SEP_2(a,b); _SEP_10(V); }while(0) -#define _SEP_13(a,b,V...) do{ _SEP_2(a,b); _SEP_11(V); }while(0) -#define _SEP_14(a,b,V...) do{ _SEP_2(a,b); _SEP_12(V); }while(0) -#define _SEP_15(a,b,V...) do{ _SEP_2(a,b); _SEP_13(V); }while(0) -#define _SEP_16(a,b,V...) do{ _SEP_2(a,b); _SEP_14(V); }while(0) -#define _SEP_17(a,b,V...) do{ _SEP_2(a,b); _SEP_15(V); }while(0) -#define _SEP_18(a,b,V...) do{ _SEP_2(a,b); _SEP_16(V); }while(0) -#define _SEP_19(a,b,V...) do{ _SEP_2(a,b); _SEP_17(V); }while(0) -#define _SEP_20(a,b,V...) do{ _SEP_2(a,b); _SEP_18(V); }while(0) -#define _SEP_21(a,b,V...) do{ _SEP_2(a,b); _SEP_19(V); }while(0) -#define _SEP_22(a,b,V...) do{ _SEP_2(a,b); _SEP_20(V); }while(0) -#define _SEP_23(a,b,V...) do{ _SEP_2(a,b); _SEP_21(V); }while(0) -#define _SEP_24(a,b,V...) do{ _SEP_2(a,b); _SEP_22(V); }while(0) +// +// SERIAL_ECHOPAIR... macros are used to output string-value pairs. +// -#define SERIAL_ECHOPAIR(V...) _SEP_N(NUM_ARGS(V),V) +// Print up to 20 pairs of values. Odd elements must be literal strings. +#define __SEP_N(N,V...) _SEP_##N(V) +#define _SEP_N(N,V...) __SEP_N(N,V) +#define _SEP_N_REF() _SEP_N +#define _SEP_1(s) SERIAL_ECHOPGM(s); +#define _SEP_2(s,v) serial_echopair_PGM(PSTR(s),v); +#define _SEP_3(s,v,V...) _SEP_2(s,v); DEFER2(_SEP_N_REF)()(TWO_ARGS(V),V); +#define SERIAL_ECHOPAIR(V...) do{ EVAL(_SEP_N(TWO_ARGS(V),V)); }while(0) -// Print up to 12 pairs of values. Odd elements must be PSTR pointers. -#define __SEP_N_P(N,V...) _SEP_##N##_P(V) -#define _SEP_N_P(N,V...) __SEP_N_P(N,V) -#define _SEP_1_P(PRE) serialprintPGM(PRE) -#define _SEP_2_P(PRE,V) serial_echopair_PGM(PRE,V) -#define _SEP_3_P(a,b,c) do{ _SEP_2_P(a,b); serialprintPGM(c); }while(0) -#define _SEP_4_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_2_P(V); }while(0) -#define _SEP_5_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_3_P(V); }while(0) -#define _SEP_6_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_4_P(V); }while(0) -#define _SEP_7_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_5_P(V); }while(0) -#define _SEP_8_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_6_P(V); }while(0) -#define _SEP_9_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_7_P(V); }while(0) -#define _SEP_10_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_8_P(V); }while(0) -#define _SEP_11_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_9_P(V); }while(0) -#define _SEP_12_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_10_P(V); }while(0) -#define _SEP_13_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_11_P(V); }while(0) -#define _SEP_14_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_12_P(V); }while(0) -#define _SEP_15_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_13_P(V); }while(0) -#define _SEP_16_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_14_P(V); }while(0) -#define _SEP_17_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_15_P(V); }while(0) -#define _SEP_18_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_16_P(V); }while(0) -#define _SEP_19_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_17_P(V); }while(0) -#define _SEP_20_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_18_P(V); }while(0) -#define _SEP_21_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_19_P(V); }while(0) -#define _SEP_22_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_20_P(V); }while(0) -#define _SEP_23_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_21_P(V); }while(0) -#define _SEP_24_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_22_P(V); }while(0) +// Print up to 20 pairs of values followed by newline. Odd elements must be literal strings. +#define __SELP_N(N,V...) _SELP_##N(V) +#define _SELP_N(N,V...) __SELP_N(N,V) +#define _SELP_N_REF() _SELP_N +#define _SELP_1(s) SERIAL_ECHOLNPGM(s); +#define _SELP_2(s,v) serial_echopair_PGM(PSTR(s),v); SERIAL_EOL(); +#define _SELP_3(s,v,V...) _SEP_2(s,v); DEFER2(_SELP_N_REF)()(TWO_ARGS(V),V); +#define SERIAL_ECHOLNPAIR(V...) do{ EVAL(_SELP_N(TWO_ARGS(V),V)); }while(0) -// SERIAL_ECHOPAIR_P is used to output a key value pair. Unlike SERIAL_ECHOPAIR, the key must be a PGM string already and the value can be anything -#define SERIAL_ECHOPAIR_P(V...) _SEP_N_P(NUM_ARGS(V),V) +// Print up to 20 pairs of values. Odd elements must be PSTR pointers. +#define __SEP_N_P(N,V...) _SEP_##N##_P(V) +#define _SEP_N_P(N,V...) __SEP_N_P(N,V) +#define _SEP_N_P_REF() _SEP_N_P +#define _SEP_1_P(s) serialprintPGM(s); +#define _SEP_2_P(s,v) serial_echopair_PGM(s,v); +#define _SEP_3_P(s,v,V...) _SEP_2_P(s,v); DEFER(_SEP_N_P_REF)()(TWO_ARGS(V),V); +#define SERIAL_ECHOPAIR_P(V...) do{ EVAL(_SEP_N_P(TWO_ARGS(V),V)); }while(0) -// Print up to 12 pairs of values followed by newline -#define __SELP_N(N,V...) _SELP_##N(V) -#define _SELP_N(N,V...) __SELP_N(N,V) -#define _SELP_1(PRE) SERIAL_ECHOLNPGM(PRE) -#define _SELP_2(PRE,V) do{ serial_echopair_PGM(PSTR(PRE),V); SERIAL_EOL(); }while(0) -#define _SELP_3(a,b,c) do{ _SEP_2(a,b); SERIAL_ECHOLNPGM(c); }while(0) -#define _SELP_4(a,b,V...) do{ _SEP_2(a,b); _SELP_2(V); }while(0) -#define _SELP_5(a,b,V...) do{ _SEP_2(a,b); _SELP_3(V); }while(0) -#define _SELP_6(a,b,V...) do{ _SEP_2(a,b); _SELP_4(V); }while(0) -#define _SELP_7(a,b,V...) do{ _SEP_2(a,b); _SELP_5(V); }while(0) -#define _SELP_8(a,b,V...) do{ _SEP_2(a,b); _SELP_6(V); }while(0) -#define _SELP_9(a,b,V...) do{ _SEP_2(a,b); _SELP_7(V); }while(0) -#define _SELP_10(a,b,V...) do{ _SEP_2(a,b); _SELP_8(V); }while(0) -#define _SELP_11(a,b,V...) do{ _SEP_2(a,b); _SELP_9(V); }while(0) -#define _SELP_12(a,b,V...) do{ _SEP_2(a,b); _SELP_10(V); }while(0) -#define _SELP_13(a,b,V...) do{ _SEP_2(a,b); _SELP_11(V); }while(0) -#define _SELP_14(a,b,V...) do{ _SEP_2(a,b); _SELP_12(V); }while(0) -#define _SELP_15(a,b,V...) do{ _SEP_2(a,b); _SELP_13(V); }while(0) -#define _SELP_16(a,b,V...) do{ _SEP_2(a,b); _SELP_14(V); }while(0) -#define _SELP_17(a,b,V...) do{ _SEP_2(a,b); _SELP_15(V); }while(0) -#define _SELP_18(a,b,V...) do{ _SEP_2(a,b); _SELP_16(V); }while(0) -#define _SELP_19(a,b,V...) do{ _SEP_2(a,b); _SELP_17(V); }while(0) -#define _SELP_20(a,b,V...) do{ _SEP_2(a,b); _SELP_18(V); }while(0) -#define _SELP_21(a,b,V...) do{ _SEP_2(a,b); _SELP_19(V); }while(0) -#define _SELP_22(a,b,V...) do{ _SEP_2(a,b); _SELP_20(V); }while(0) -#define _SELP_23(a,b,V...) do{ _SEP_2(a,b); _SELP_21(V); }while(0) -#define _SELP_24(a,b,V...) do{ _SEP_2(a,b); _SELP_22(V); }while(0) -#define _SELP_25(a,b,V...) do{ _SEP_2(a,b); _SELP_23(V); }while(0) -#define _SELP_26(a,b,V...) do{ _SEP_2(a,b); _SELP_24(V); }while(0) -#define _SELP_27(a,b,V...) do{ _SEP_2(a,b); _SELP_25(V); }while(0) -#define _SELP_28(a,b,V...) do{ _SEP_2(a,b); _SELP_26(V); }while(0) -#define _SELP_29(a,b,V...) do{ _SEP_2(a,b); _SELP_27(V); }while(0) -#define _SELP_30(a,b,V...) do{ _SEP_2(a,b); _SELP_28(V); }while(0) // Eat two args, pass the rest up - -#define SERIAL_ECHOLNPAIR(V...) _SELP_N(NUM_ARGS(V),V) - -// Print up to 12 pairs of values followed by newline -#define __SELP_N_P(N,V...) _SELP_##N##_P(V) -#define _SELP_N_P(N,V...) __SELP_N_P(N,V) -#define _SELP_1_P(PRE) serialprintPGM(PRE) -#define _SELP_2_P(PRE,V) do{ serial_echopair_PGM(PRE,V); SERIAL_EOL(); }while(0) -#define _SELP_3_P(a,b,c) do{ _SEP_2_P(a,b); serialprintPGM(c); }while(0) -#define _SELP_4_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_2_P(V); }while(0) -#define _SELP_5_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_3_P(V); }while(0) -#define _SELP_6_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_4_P(V); }while(0) -#define _SELP_7_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_5_P(V); }while(0) -#define _SELP_8_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_6_P(V); }while(0) -#define _SELP_9_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_7_P(V); }while(0) -#define _SELP_10_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_8_P(V); }while(0) -#define _SELP_11_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_9_P(V); }while(0) -#define _SELP_12_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_10_P(V); }while(0) -#define _SELP_13_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_11_P(V); }while(0) -#define _SELP_14_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_12_P(V); }while(0) -#define _SELP_15_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_13_P(V); }while(0) -#define _SELP_16_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_14_P(V); }while(0) -#define _SELP_17_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_15_P(V); }while(0) -#define _SELP_18_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_16_P(V); }while(0) -#define _SELP_19_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_17_P(V); }while(0) -#define _SELP_20_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_18_P(V); }while(0) -#define _SELP_21_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_19_P(V); }while(0) -#define _SELP_22_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_20_P(V); }while(0) -#define _SELP_23_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_21_P(V); }while(0) -#define _SELP_24_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_22_P(V); }while(0) -#define _SELP_25_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_23_P(V); }while(0) -#define _SELP_26_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_24_P(V); }while(0) -#define _SELP_27_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_25_P(V); }while(0) -#define _SELP_28_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_26_P(V); }while(0) -#define _SELP_29_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_27_P(V); }while(0) -#define _SELP_30_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_28_P(V); }while(0) // Eat two args, pass the rest up - -#define SERIAL_ECHOLNPAIR_P(V...) _SELP_N_P(NUM_ARGS(V),V) +// Print up to 20 pairs of values followed by newline. Odd elements must be PSTR pointers. +#define __SELP_N_P(N,V...) _SELP_##N##_P(V) +#define _SELP_N_P(N,V...) __SELP_N_P(N,V) +#define _SELP_N_P_REF() _SELP_N_P +#define _SELP_1_P(s) { serialprintPGM(s); SERIAL_EOL(); } +#define _SELP_2_P(s,v) { serial_echopair_PGM(s,v); SERIAL_EOL(); } +#define _SELP_3_P(s,v,V...) { _SEP_2_P(s,v); DEFER(_SELP_N_P_REF)()(TWO_ARGS(V),V); } +#define SERIAL_ECHOLNPAIR_P(V...) do{ EVAL(_SELP_N_P(TWO_ARGS(V),V)); }while(0) #ifdef AllowDifferentTypeInList diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index 07253c117a..35b55c82f9 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -3880,8 +3880,8 @@ void MarlinSettings::reset() { say_M603(forReplay); SERIAL_ECHOLNPAIR("L", LINEAR_UNIT(fc_settings[0].load_length), " U", LINEAR_UNIT(fc_settings[0].unload_length)); #else - #define _ECHO_603(N) do{ say_M603(forReplay); SERIAL_ECHOLNPAIR("T" STRINGIFY(N) " L", LINEAR_UNIT(fc_settings[N].load_length), " U", LINEAR_UNIT(fc_settings[N].unload_length)); }while(0); - REPEAT(EXTRUDERS, _ECHO_603) + auto echo_603 = [](const bool f, const uint8_t n) { say_M603(f); SERIAL_ECHOLNPAIR("T", n, " L", LINEAR_UNIT(fc_settings[n].load_length), " U", LINEAR_UNIT(fc_settings[n].unload_length)); }; + LOOP_L_N(i, EXTRUDERS) echo_603(forReplay, i); #endif #endif From a42760d38a65c58178af7840ba57298cd0b7d31a Mon Sep 17 00:00:00 2001 From: Victor Oliveira Date: Tue, 11 May 2021 12:44:54 -0300 Subject: [PATCH 37/67] BTT SKR Mini E3 for HAL/STM32 (#21488) --- .github/workflows/test-builds.yml | 1 + Marlin/src/HAL/STM32/HAL.cpp | 6 + Marlin/src/HAL/STM32F1/HAL.cpp | 2 +- Marlin/src/pins/pins.h | 10 +- .../stm32f1/pins_BTT_SKR_MINI_E3_common.h | 13 +- .../PlatformIO/scripts/stm32_bootloader.py | 7 +- .../variants/MARLIN_F103Rx/PeripheralPins.c | 423 ++++++++++++++++++ .../variants/MARLIN_F103Rx/PinNamesVar.h | 30 ++ .../variants/MARLIN_F103Rx/ldscript.ld | 200 +++++++++ .../variants/MARLIN_F103Rx/variant.cpp | 152 +++++++ .../variants/MARLIN_F103Rx/variant.h | 161 +++++++ buildroot/tests/STM32F103RC_btt_USB_stm32 | 17 + buildroot/tests/STM32F103RC_btt_stm32 | 20 + ini/stm32f1.ini | 50 +++ 14 files changed, 1082 insertions(+), 10 deletions(-) create mode 100755 buildroot/share/PlatformIO/variants/MARLIN_F103Rx/PeripheralPins.c create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Rx/PinNamesVar.h create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Rx/ldscript.ld create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Rx/variant.cpp create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_F103Rx/variant.h create mode 100755 buildroot/tests/STM32F103RC_btt_USB_stm32 create mode 100755 buildroot/tests/STM32F103RC_btt_stm32 diff --git a/.github/workflows/test-builds.yml b/.github/workflows/test-builds.yml index 6fdd7d67bc..979f56cb6a 100644 --- a/.github/workflows/test-builds.yml +++ b/.github/workflows/test-builds.yml @@ -72,6 +72,7 @@ jobs: # STM32 (ST) Environments + - STM32F103RC_btt_stm32 - STM32F407VE_black - STM32F401VE_STEVAL - BIGTREE_BTT002 diff --git a/Marlin/src/HAL/STM32/HAL.cpp b/Marlin/src/HAL/STM32/HAL.cpp index 3bb12fd9e0..e09b52f7db 100644 --- a/Marlin/src/HAL/STM32/HAL.cpp +++ b/Marlin/src/HAL/STM32/HAL.cpp @@ -96,6 +96,12 @@ void HAL_init() { #if HAS_SD_HOST_DRIVE MSC_SD_init(); // Enable USB SD card access #endif + + #if PIN_EXISTS(USB_CONNECT) + OUT_WRITE(USB_CONNECT_PIN, !USB_CONNECT_INVERTING); // USB clear connection + delay(1000); // Give OS time to notice + WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING); + #endif } // HAL idle task diff --git a/Marlin/src/HAL/STM32F1/HAL.cpp b/Marlin/src/HAL/STM32F1/HAL.cpp index 2efea4f001..dcfdc88555 100644 --- a/Marlin/src/HAL/STM32F1/HAL.cpp +++ b/Marlin/src/HAL/STM32F1/HAL.cpp @@ -293,7 +293,7 @@ void HAL_init() { #if PIN_EXISTS(USB_CONNECT) OUT_WRITE(USB_CONNECT_PIN, !USB_CONNECT_INVERTING); // USB clear connection delay(1000); // Give OS time to notice - OUT_WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING); + WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING); #endif TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the minimal serial handler } diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index d38dc595f2..2a70e571af 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -511,15 +511,15 @@ #elif MB(MKS_ROBIN_E3P) #include "stm32f1/pins_MKS_ROBIN_E3P.h" // STM32F1 env:mks_robin_e3p #elif MB(BTT_SKR_MINI_V1_1) - #include "stm32f1/pins_BTT_SKR_MINI_V1_1.h" // STM32F1 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB + #include "stm32f1/pins_BTT_SKR_MINI_V1_1.h" // STM32F1 env:STM32F103RC_btt_stm32 env:STM32F103RC_btt_512K_stm32 env:STM32F103RC_btt_USB_stm32 env:STM32F103RC_btt_512K_USB_stm32 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB #elif MB(BTT_SKR_MINI_E3_V1_0) - #include "stm32f1/pins_BTT_SKR_MINI_E3_V1_0.h" // STM32F1 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB + #include "stm32f1/pins_BTT_SKR_MINI_E3_V1_0.h" // STM32F1 env:STM32F103RC_btt_stm32 env:STM32F103RC_btt_512K_stm32 env:STM32F103RC_btt_USB_stm32 env:STM32F103RC_btt_512K_USB_stm32 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB #elif MB(BTT_SKR_MINI_E3_V1_2) - #include "stm32f1/pins_BTT_SKR_MINI_E3_V1_2.h" // STM32F1 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB + #include "stm32f1/pins_BTT_SKR_MINI_E3_V1_2.h" // STM32F1 env:STM32F103RC_btt_stm32 env:STM32F103RC_btt_512K_stm32 env:STM32F103RC_btt_USB_stm32 env:STM32F103RC_btt_512K_USB_stm32 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB #elif MB(BTT_SKR_MINI_E3_V2_0) - #include "stm32f1/pins_BTT_SKR_MINI_E3_V2_0.h" // STM32F1 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB + #include "stm32f1/pins_BTT_SKR_MINI_E3_V2_0.h" // STM32F1 env:STM32F103RC_btt_stm32 env:STM32F103RC_btt_512K_stm32 env:STM32F103RC_btt_USB_stm32 env:STM32F103RC_btt_512K_USB_stm32 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB #elif MB(BTT_SKR_MINI_MZ_V1_0) - #include "stm32f1/pins_BTT_SKR_MINI_MZ_V1_0.h" // STM32F1 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB + #include "stm32f1/pins_BTT_SKR_MINI_MZ_V1_0.h" // STM32F1 env:STM32F103RC_btt_stm32 env:STM32F103RC_btt_512K_stm32 env:STM32F103RC_btt_USB_stm32 env:STM32F103RC_btt_512K_USB_stm32 env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB #elif MB(BTT_SKR_E3_DIP) #include "stm32f1/pins_BTT_SKR_E3_DIP.h" // STM32F1 env:STM32F103RE_btt env:STM32F103RE_btt_USB env:STM32F103RC_btt env:STM32F103RC_btt_512K env:STM32F103RC_btt_USB env:STM32F103RC_btt_512K_USB #elif MB(BTT_SKR_CR6) diff --git a/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h index bab662d1be..58adc5853a 100644 --- a/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h +++ b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h @@ -21,7 +21,7 @@ */ #pragma once -#if NOT_TARGET(TARGET_STM32F1) +#if NOT_TARGET(__STM32F1__, STM32F1) #error "Oops! Select an STM32F1 board in 'Tools > Board.'" #endif @@ -279,5 +279,14 @@ #error "SD CUSTOM_CABLE is not compatible with SKR Mini E3." #endif -#define ONBOARD_SPI_DEVICE 1 // SPI1 +#define ONBOARD_SPI_DEVICE 1 // SPI1 -> used only by HAL/STM32F1... #define ONBOARD_SD_CS_PIN PA4 // Chip select for "System" SD card + +#define CUSTOM_SPI_PINS // TODO: needed because is the only way to set SPI for SD on STM32 (for now) +#if ENABLED(CUSTOM_SPI_PINS) + #define ENABLE_SPI1 + #define SDSS ONBOARD_SD_CS_PIN + #define SD_SCK_PIN PA5 + #define SD_MISO_PIN PA6 + #define SD_MOSI_PIN PA7 +#endif diff --git a/buildroot/share/PlatformIO/scripts/stm32_bootloader.py b/buildroot/share/PlatformIO/scripts/stm32_bootloader.py index 4e7d2d9c07..b2b5daadb6 100644 --- a/buildroot/share/PlatformIO/scripts/stm32_bootloader.py +++ b/buildroot/share/PlatformIO/scripts/stm32_bootloader.py @@ -19,9 +19,12 @@ def noencrypt(source, target, env): # if 'offset' in board.get("build").keys(): LD_FLASH_OFFSET = board.get("build.offset") - marlin.relocate_vtab(LD_FLASH_OFFSET) + # Flash size + maximum_flash_size = int(board.get("upload.maximum_size") / 1024) + marlin.replace_define('STM32_FLASH_SIZE', maximum_flash_size) + # Get upload.maximum_ram_size (defined by /buildroot/share/PlatformIO/boards/VARIOUS.json) maximum_ram_size = board.get("upload.maximum_ram_size") @@ -35,6 +38,6 @@ if 'offset' in board.get("build").keys(): # Only copy the file if there's no encrypt # board_keys = board.get("build").keys() -if 'firmware' in board_keys and not 'encrypt' in board_keys: +if 'firmware' in board_keys and ('encrypt' not in board_keys or board.get("build.encrypt") == 'No'): import marlin marlin.add_post_action(noencrypt) diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/PeripheralPins.c b/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/PeripheralPins.c new file mode 100755 index 0000000000..56ae00b41b --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/PeripheralPins.c @@ -0,0 +1,423 @@ +/* + ******************************************************************************* + * Copyright (c) 2020, STMicroelectronics + * All rights reserved. + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + * Automatically generated from STM32F103R(F-G)Tx.xml + */ +#include "Arduino.h" +#include "PeripheralPins.h" + +/* ===== + * Note: Commented lines are alternative possibilities which are not used per default. + * If you change them, you will have to know what you do + * ===== + */ + +//*** ADC *** + +#ifdef HAL_ADC_MODULE_ENABLED +WEAK const PinMap PinMap_ADC[] = { + {PA_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC1_IN0 + // {PA_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC2_IN0 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC3_IN0 +#endif + {PA_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC1_IN1 + // {PA_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC2_IN1 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC3_IN1 +#endif + {PA_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2 + // {PA_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC2_IN2 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC3_IN2 +#endif + {PA_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 + // {PA_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC2_IN3 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC3_IN3 +#endif + {PA_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4 + // {PA_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC2_IN4 + {PA_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5 + // {PA_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC2_IN5 + {PA_6, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6 + // {PA_6, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC2_IN6 + {PA_7, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7 + // {PA_7, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC2_IN7 + {PB_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8 + // {PB_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC2_IN8 + {PB_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC1_IN9 + // {PB_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC2_IN9 + {PC_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC1_IN10 + // {PC_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC2_IN10 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC3_IN10 +#endif + {PC_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC1_IN11 + // {PC_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC2_IN11 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC3_IN11 +#endif + {PC_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC1_IN12 + // {PC_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC2_IN12 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC3_IN12 +#endif + {PC_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC1_IN13 + // {PC_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC2_IN13 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC3_IN13 +#endif + {PC_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC1_IN14 + // {PC_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC2_IN14 + {PC_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC1_IN15 + // {PC_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC2_IN15 + {NC, NP, 0} +}; +#endif + +//*** DAC *** + +#if defined(STM32F103xE) || defined(STM32F103xG) +#ifdef HAL_DAC_MODULE_ENABLED +WEAK const PinMap PinMap_DAC[] = { + {PA_4, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC_OUT1 + {PA_5, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC_OUT2 + {NC, NP, 0} +}; +#endif +#endif + +//*** I2C *** + +#ifdef HAL_I2C_MODULE_ENABLED +WEAK const PinMap PinMap_I2C_SDA[] = { + {PB_7, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, + {PB_9, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_I2C1_ENABLE)}, +#if defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + {PB_11, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, +#endif + {NC, NP, 0} +}; +#endif + +#ifdef HAL_I2C_MODULE_ENABLED +WEAK const PinMap PinMap_I2C_SCL[] = { + {PB_6, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, + {PB_8, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_I2C1_ENABLE)}, +#if defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + {PB_10, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, AFIO_NONE)}, +#endif + {NC, NP, 0} +}; +#endif + +//*** PWM *** + +#ifdef HAL_TIM_MODULE_ENABLED +WEAK const PinMap PinMap_PWM[] = { + {PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM2_CH1 + // {PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 1, 0)}, // TIM2_CH1 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_0, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM5_CH1 +#endif + {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM2_CH2 + // {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 2, 0)}, // TIM2_CH2 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_1, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM5_CH2 +#endif + {PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM2_CH3 + // {PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 3, 0)}, // TIM2_CH3 +#if defined(STM32F103xG) + // {PA_2, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM5_CH3 +#endif +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PA_2, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM9_CH1 +#endif + // {PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 4, 0)}, // TIM2_CH4 +#if defined(STM32F103xE) || defined(STM32F103xG) + {PA_3, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM5_CH4 +#else + {PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM2_CH4 +#endif +#if defined(STM32F103xG) + // {PA_3, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM9_CH2 +#endif + {PA_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM3_CH1 +#if defined(STM32F103xG) + // {PA_6, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM13_CH1 +#endif + // {PA_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM3_CH2 +#if defined(STM32F103xE) || defined(STM32F103xG) + {PA_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 1)}, // TIM8_CH1N +#else + {PA_7, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 1, 1)}, // TIM1_CH1N +#endif +#if defined(STM32F103xG) + // {PA_7, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM14_CH1 +#endif + {PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM1_CH1 + // {PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 1, 0)}, // TIM1_CH1 + {PA_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM1_CH2 + // {PA_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 2, 0)}, // TIM1_CH2 + {PA_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM1_CH3 + // {PA_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 3, 0)}, // TIM1_CH3 + {PA_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM1_CH4 + // {PA_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 4, 0)}, // TIM1_CH4 + {PA_15, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 1, 0)}, // TIM2_CH1 + // {PA_15, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 1, 0)}, // TIM2_CH1 + // {PB_0, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 2, 1)}, // TIM1_CH2N + {PB_0, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM3_CH3 + // {PB_0, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 3, 0)}, // TIM3_CH3 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PB_0, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 1)}, // TIM8_CH2N +#endif + {PB_1, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM1_PARTIAL, 3, 1)}, // TIM1_CH3N + // {PB_1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM3_CH4 + // {PB_1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 4, 0)}, // TIM3_CH4 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PB_1, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 1)}, // TIM8_CH3N +#endif + {PB_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_1, 2, 0)}, // TIM2_CH2 + // {PB_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 2, 0)}, // TIM2_CH2 + {PB_4, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 1, 0)}, // TIM3_CH1 + {PB_5, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_PARTIAL, 2, 0)}, // TIM3_CH2 +#if defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + {PB_6, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM4_CH1 + {PB_7, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM4_CH2 + {PB_8, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM4_CH3 + {PB_9, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM4_CH4 +#endif +#if defined(STM32F103xG) + // {PB_8, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM10_CH1 +#endif +#if defined(STM32F103xG) + // {PB_9, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM11_CH1 +#endif + {PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 3, 0)}, // TIM2_CH3 + // {PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 3, 0)}, // TIM2_CH3 + {PB_11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_PARTIAL_2, 4, 0)}, // TIM2_CH4 + // {PB_11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM2_ENABLE, 4, 0)}, // TIM2_CH4 + {PB_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 1)}, // TIM1_CH1N + {PB_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 1)}, // TIM1_CH2N +#if defined(STM32F103xG) + // {PB_14, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM12_CH1 +#endif + {PB_15, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 1)}, // TIM1_CH3N +#if defined(STM32F103xG) + // {PB_15, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM12_CH2 +#endif + {PC_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 1, 0)}, // TIM3_CH1 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_6, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 1, 0)}, // TIM8_CH1 +#endif + {PC_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 2, 0)}, // TIM3_CH2 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 2, 0)}, // TIM8_CH2 +#endif +#if defined(STM32F103xE) || defined(STM32F103xG) + {PC_8, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 3, 0)}, // TIM8_CH3 +#else + {PC_8, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 3, 0)}, // TIM3_CH3 +#endif + {PC_9, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_TIM3_ENABLE, 4, 0)}, // TIM3_CH4 +#if defined(STM32F103xE) || defined(STM32F103xG) + // {PC_9, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE, 4, 0)}, // TIM8_CH4 +#endif + {NC, NP, 0} +}; +#endif + +//*** SERIAL *** + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_TX[] = { + {PA_2, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PA_9, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_6, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART1_ENABLE)}, +#if defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + {PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#endif +#if defined(STM32F103xE) || defined(STM32F103xG) + {PC_10, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#endif +#if defined(STM32F103xB) + {PC_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, +#endif +#if defined(STM32F103xE) || defined(STM32F103xG) + {PC_12, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#endif + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_RX[] = { + {PA_3, USART2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, + {PA_10, USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, + {PB_7, USART1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART1_ENABLE)}, +#if defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + {PB_11, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, +#endif +#if defined(STM32F103xE) || defined(STM32F103xG) + {PC_11, UART4, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, +#endif +#if defined(STM32F103xB) + {PC_11, USART3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, +#endif +#if defined(STM32F103xE) || defined(STM32F103xG) + {PD_2, UART5, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, AFIO_NONE)}, +#endif + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_RTS[] = { + {PA_1, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PA_12, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + {PB_14, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_14, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, +#endif + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +WEAK const PinMap PinMap_UART_CTS[] = { + {PA_0, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PA_11, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + {PB_13, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, + {PB_13, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_USART3_PARTIAL)}, +#endif + {NC, NP, 0} +}; +#endif + +//*** SPI *** + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_MOSI[] = { + {PA_7, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xE) || defined(STM32F103xG) + {PB_5, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#else + {PB_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, +#endif +#if defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + {PB_15, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#endif + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_MISO[] = { + {PA_6, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xE) || defined(STM32F103xG) + {PB_4, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#else + {PB_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, +#endif +#if defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + {PB_14, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#endif + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_SCLK[] = { + {PA_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xE) || defined(STM32F103xG) + {PB_3, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#else + {PB_3, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, +#endif +#if defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + {PB_13, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#endif + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +WEAK const PinMap PinMap_SPI_SSEL[] = { + {PA_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#if defined(STM32F103xE) || defined(STM32F103xG) + {PA_15, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#else + {PA_15, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_SPI1_ENABLE)}, +#endif +#if defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + {PB_12, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, +#endif + {NC, NP, 0} +}; +#endif + +//*** CAN *** + +#ifdef HAL_CAN_MODULE_ENABLED +WEAK const PinMap PinMap_CAN_RD[] = { + {PA_11, CAN1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_NONE)}, + {PB_8, CAN1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_CAN1_2)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_CAN_MODULE_ENABLED +WEAK const PinMap PinMap_CAN_TD[] = { + {PA_12, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)}, + {PB_9, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_CAN1_2)}, + {NC, NP, 0} +}; +#endif + +//*** No ETHERNET *** + +//*** No QUADSPI *** + +//*** USB *** + +#ifdef HAL_PCD_MODULE_ENABLED +WEAK const PinMap PinMap_USB[] = { + {PA_11, USB, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_NONE)}, // USB_DM + {PA_12, USB, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, AFIO_NONE)}, // USB_DP + {NC, NP, 0} +}; +#endif + +//*** No USB_OTG_FS *** + +//*** No USB_OTG_HS *** + +//*** SD *** + +#if defined(STM32F103xE) || defined(STM32F103xG) +#ifdef HAL_SD_MODULE_ENABLED +WEAK const PinMap PinMap_SD[] = { + {PB_8, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D4 + {PB_9, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D5 + {PC_6, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D6 + {PC_7, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D7 + {PC_8, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D0 + {PC_9, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D1 + {PC_10, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D2 + {PC_11, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, AFIO_NONE)}, // SDIO_D3 + {PC_12, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)}, // SDIO_CK + {PD_2, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)}, // SDIO_CMD + {NC, NP, 0} +}; +#endif +#endif diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/PinNamesVar.h b/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/PinNamesVar.h new file mode 100644 index 0000000000..d9e759f5d0 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/PinNamesVar.h @@ -0,0 +1,30 @@ +/* SYS_WKUP */ +#ifdef PWR_WAKEUP_PIN1 + SYS_WKUP1 = PA_0, +#endif +#ifdef PWR_WAKEUP_PIN2 + SYS_WKUP2 = NC, +#endif +#ifdef PWR_WAKEUP_PIN3 + SYS_WKUP3 = NC, +#endif +#ifdef PWR_WAKEUP_PIN4 + SYS_WKUP4 = NC, +#endif +#ifdef PWR_WAKEUP_PIN5 + SYS_WKUP5 = NC, +#endif +#ifdef PWR_WAKEUP_PIN6 + SYS_WKUP6 = NC, +#endif +#ifdef PWR_WAKEUP_PIN7 + SYS_WKUP7 = NC, +#endif +#ifdef PWR_WAKEUP_PIN8 + SYS_WKUP8 = NC, +#endif +/* USB */ +#ifdef USBCON + USB_DM = PA_11, + USB_DP = PA_12, +#endif \ No newline at end of file diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/ldscript.ld b/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/ldscript.ld new file mode 100644 index 0000000000..80bb1d2bb7 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/ldscript.ld @@ -0,0 +1,200 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** Author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for STM32F103R(8/B/C/ETx Device from STM32F1 series +** 64/128/256/512Kbytes FLASH +** 20/20/48/64Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2019 STMicroelectronics

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** 3. Neither the name of STMicroelectronics nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20000000 + LD_MAX_DATA_SIZE; /* end of "RAM" Ram type memory */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = LD_MAX_DATA_SIZE + FLASH (rx) : ORIGIN = 0x8000000 + LD_FLASH_OFFSET, LENGTH = LD_MAX_SIZE - LD_FLASH_OFFSET +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/variant.cpp b/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/variant.cpp new file mode 100644 index 0000000000..4d815a34d7 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/variant.cpp @@ -0,0 +1,152 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "pins_arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const PinName digitalPin[] = { + PA_0, + PA_1, + PA_2, + PA_3, + PA_4, + PA_5, + PA_6, + PA_7, + PA_8, + PA_9, // RXD + PA_10, // TXD + PA_11, // USB D- + PA_12, // USB D+ + PA_13, // JTDI + PA_14, // JTCK + PA_15, + PB_0, + PB_1, + PB_2, + PB_3, // JTDO + PB_4, // JTRST + PB_5, + PB_6, + PB_7, + PB_8, + PB_9, + PB_10, + PB_11, // LED + PB_12, + PB_13, + PB_14, + PB_15, + PC_0, + PC_1, + PC_2, + PC_3, + PC_4, + PC_5, + PC_6, + PC_7, + PC_8, + PC_9, + PC_10, + PC_11, + PC_12, + PC_13, + PC_14, // OSC32_1 + PC_15, // OSC32_2 + PD_0, // OSCIN + PD_1, // OSCOUT + PD_2 +}; + +// Analog (Ax) pin number array +const uint32_t analogInputPin[] = { + 0, // A0, PA0 + 1, // A1, PA1 + 2, // A2, PA2 + 3, // A3, PA3 + 4, // A4, PA4 + 5, // A5, PA5 + 6, // A6, PA6 + 7, // A7, PA7 + 16, // A8, PB0 + 17, // A9, PB1 + 32, // A10, PC0 + 33, // A11, PC1 + 34, // A12, PC2 + 35, // A13, PC3 + 36, // A14, PC4 + 37 // A15, PC5 +}; + +#ifdef __cplusplus +} +#endif + +// ---------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief System Clock Configuration + * @param None + * @retval None + */ +WEAK void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {}; + + /* Initializes the CPU, AHB and APB busses clocks */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + Error_Handler(); + } + /* Initializes the CPU, AHB and APB busses clocks */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK + | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { + Error_Handler(); + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_USB; + PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { + Error_Handler(); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/variant.h b/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/variant.h new file mode 100644 index 0000000000..7dcbb793d0 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_F103Rx/variant.h @@ -0,0 +1,161 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_ARDUINO_STM32_ +#define _VARIANT_ARDUINO_STM32_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + + +// * = F103R8-B-C-D-E-F-G +// ** = F103RC-D-E-F-G +// | DIGITAL | ANALOG | USART | TWI | SPI | SPECIAL | +// |---------|----------------|--------------------------|-----------|-----------------------|-----------| +#define PA0 PIN_A0 // | 0 | A0 | | | | | +#define PA1 PIN_A1 // | 1 | A1 | | | | | +#define PA2 PIN_A2 // | 2 | A2 | USART2_TX | | | | +#define PA3 PIN_A3 // | 2 | A2, DAC_OUT1** | USART2_RX | | | | +#define PA4 PIN_A4 // | 4 | A4, DAC_OUT2** | | | SPI1_SS | | +#define PA5 PIN_A5 // | 5 | A5 | | | SPI1_SCK | | +#define PA6 PIN_A6 // | 6 | A6 | | | SPI1_MISO | | +#define PA7 PIN_A7 // | 7 | A7 | | | SPI1_MOSI | | +#define PA8 8 // | 8 | | | | | | +#define PA9 9 // | 9 | | USART1_TX | | | | +#define PA10 10 // | 10 | | USART1_RX | | | | +#define PA11 11 // | 11 | | | | | USB_DM | +#define PA12 12 // | 12 | | | | | USB_DP | +#define PA13 13 // | 13 | | | | | SWD_SWDIO | +#define PA14 14 // | 14 | | | | | SWD_SWCLK | +#define PA15 15 // | 15 | | | | SPI1_SS/SPI3_SS** | | +// |---------|----------------|--------------------------|-----------|-----------------------|-----------| +#define PB0 PIN_A8 // | 16 | A8 | | | | | +#define PB1 PIN_A9 // | 17 | A9 | | | | | +#define PB2 18 // | 18 | | | | | BOOT1 | +#define PB3 19 // | 19 | | | | SPI1_SCK/SPI3_SCK** | | +#define PB4 20 // | 20 | | | | SPI1_MISO/SPI3_MISO** | | +#define PB5 21 // | 21 | | | | SPI1_MOSI/SPI3_MOSI** | | +#define PB6 22 // | 22 | | USART1_TX | TWI1_SCL | | | +#define PB7 23 // | 23 | | USART1_RX | TWI1_SDA | | | +#define PB8 24 // | 24 | | | TWI1_SCL | | | +#define PB9 25 // | 25 | | | TWI1_SDA | | | +#define PB10 26 // | 26 | | USART3_TX* | TWI2_SCL* | | | +#define PB11 27 // | 27 | | USART3_RX* | TWI2_SDA* | | | +#define PB12 28 // | 28 | | | | SPI2_SS* | | +#define PB13 29 // | 29 | | | | SPI2_SCK* | | +#define PB14 30 // | 30 | | | | SPI2_MISO* | | +#define PB15 31 // | 31 | | | | SPI2_MOSI* | | +// |---------|----------------|--------------------------|-----------|-----------------------|-----------| +#define PC0 PIN_A10 // | 32 | A10 | | | | | +#define PC1 PIN_A11 // | 33 | A11 | | | | | +#define PC2 PIN_A12 // | 34 | A12 | | | | | +#define PC3 PIN_A13 // | 35 | A13 | | | | | +#define PC4 PIN_A14 // | 36 | A14 | | | | | +#define PC5 PIN_A15 // | 37 | A15 | | | | | +#define PC6 38 // | 38 | | | | | | +#define PC7 39 // | 39 | | | | | | +#define PC8 40 // | 40 | | | | | | +#define PC9 41 // | 41 | | | | | | +#define PC10 42 // | 42 | | USART3_TX*/UART4_TX** | | | | +#define PC11 43 // | 43 | | USART3_RX*/UART4_RX** | | | | +#define PC12 44 // | 44 | | UART5_TX** | | | | +#define PC13 45 // | 45 | | | | | | +#define PC14 46 // | 46 | | | | | OSC32_IN | +#define PC15 47 // | 47 | | | | | OSC32_OUT | +// |---------|----------------|--------------------------|-----------|-----------------------|-----------| +#define PD0 48 // | 48 | | | | | OSC_IN | +#define PD1 49 // | 48 | | | | | OSC_OUT | +#define PD2 50 // | 50 | | UART5_RX** | | | | +// |---------|----------------|--------------------------|-----------|-----------------------|-----------| + +// This must be a literal +#define NUM_DIGITAL_PINS 51 +// This must be a literal with a value less than or equal to to MAX_ANALOG_INPUTS +#define NUM_ANALOG_INPUTS 16 + +// On-board LED pin number +#ifndef LED_BUILTIN +#define LED_BUILTIN PB11 +#endif +#define LED_GREEN LED_BUILTIN + +// On-board user button +#ifndef USER_BTN +#define USER_BTN PC13 +#endif + +// Override default Arduino configuration +// SPI Definitions +#define PIN_SPI_SS PA4 +#define PIN_SPI_MOSI PA7 +#define PIN_SPI_MISO PA6 +#define PIN_SPI_SCK PA5 + +// I2C Definitions +#define PIN_WIRE_SDA PB7 +#define PIN_WIRE_SCL PB6 + +// Timer Definitions +#ifndef TIMER_TONE + #define TIMER_TONE TIM3 +#endif +#ifndef TIMER_SERVO + #define TIMER_SERVO TIM2 +#endif +// UART Definitions +// Define here Serial instance number to map on Serial generic name +#define SERIAL_UART_INSTANCE 1 + +// Default pin used for 'Serial1' instance +#define PIN_SERIAL_RX PA10 +#define PIN_SERIAL_TX PA9 + +/* Extra HAL modules */ +#if defined(STM32F103xE) || defined(STM32F103xG) +#define HAL_DAC_MODULE_ENABLED +#endif + +#ifdef __cplusplus +} // extern "C" +#endif +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + // These serial port names are intended to allow libraries and architecture-neutral + // sketches to automatically default to the correct port name for a particular type + // of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, + // the first hardware serial port whose RX/TX pins are not dedicated to another use. + // + // SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor + // + // SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial + // + // SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library + // + // SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. + // + // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX + // pins are NOT connected to anything by default. + #define SERIAL_PORT_MONITOR Serial + #define SERIAL_PORT_HARDWARE Serial1 +#endif + +#endif /* _VARIANT_ARDUINO_STM32_ */ diff --git a/buildroot/tests/STM32F103RC_btt_USB_stm32 b/buildroot/tests/STM32F103RC_btt_USB_stm32 new file mode 100755 index 0000000000..8381de0ea6 --- /dev/null +++ b/buildroot/tests/STM32F103RC_btt_USB_stm32 @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F103RC BigTreeTech (SKR Mini v1.1) +# + +# exit on first failure +set -e + +# +# Build with the default configurations +# +restore_configs +opt_set MOTHERBOARD BOARD_BTT_SKR_MINI_V1_1 SERIAL_PORT 1 SERIAL_PORT_2 -1 +exec_test $1 $2 "BigTreeTech SKR Mini v1.1 - Basic Configuration" "$3" + +# clean up +restore_configs diff --git a/buildroot/tests/STM32F103RC_btt_stm32 b/buildroot/tests/STM32F103RC_btt_stm32 new file mode 100755 index 0000000000..e76060aee8 --- /dev/null +++ b/buildroot/tests/STM32F103RC_btt_stm32 @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F103RC BigTreeTech (SKR Mini E3) +# + +# exit on first failure +set -e + +# +# Build with the default configurations +# +restore_configs +opt_set MOTHERBOARD BOARD_BTT_SKR_MINI_E3_V1_0 SERIAL_PORT 1 SERIAL_PORT_2 -1 \ + X_DRIVER_TYPE TMC2209 Y_DRIVER_TYPE TMC2209 Z_DRIVER_TYPE TMC2209 E0_DRIVER_TYPE TMC2209 +opt_enable PINS_DEBUGGING Z_IDLE_HEIGHT + +exec_test $1 $2 "BigTreeTech SKR Mini E3 1.0 - Basic Config with TMC2209 HW Serial" "$3" + +# clean up +restore_configs diff --git a/ini/stm32f1.ini b/ini/stm32f1.ini index 7283adda4b..6a234bdc97 100644 --- a/ini/stm32f1.ini +++ b/ini/stm32f1.ini @@ -143,6 +143,56 @@ build_flags = ${env:STM32F103RC_btt_512K.build_flags} -DUSE_USB_COMPOSITE lib_deps = ${env:STM32F103RC_btt_512K.lib_deps} USBComposite for STM32F1@0.91 +# +# STM32 HAL version of STM32F103RC_btt envs +# + +[env:STM32F103RC_stm32] +platform = ${common_stm32.platform} +extends = common_stm32 +board = genericSTM32F103RC +monitor_speed = 115200 +board_build.core = stm32 +board_build.variant = MARLIN_F103Rx +board_build.ldscript = ldscript.ld +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py + buildroot/share/PlatformIO/scripts/stm32_bootloader.py + +[env:STM32F103RC_btt_stm32] +platform = ${common_stm32.platform} +extends = env:STM32F103RC_stm32 +build_flags = ${common_stm32.build_flags} -DDEBUG_LEVEL=0 -DTIMER_SERVO=TIM5 +board_build.offset = 0x7000 +board_build.encrypt = No +board_build.firmware = firmware.bin +board_upload.offset_address = 0x08007000 + +[env:STM32F103RC_btt_USB_stm32] +extends = env:STM32F103RC_btt_stm32 +platform = ${common_stm32.platform} +platform_packages = framework-arduinoststm32@https://github.com/rhapsodyv/Arduino_Core_STM32/archive/usb-host-msc-cdc-msc.zip +build_unflags = ${common_stm32.build_unflags} -DUSBD_USE_CDC +build_flags = ${env:STM32F103RC_btt_stm32.build_flags} ${env:stm32_flash_drive.build_flags} + -DUSBCON + -DUSE_USBHOST_HS + -DUSBD_IRQ_PRIO=5 + -DUSBD_IRQ_SUBPRIO=6 + -DUSE_USB_HS_IN_FS + -DUSBD_USE_CDC_MSC + +[env:STM32F103RC_btt_512K_stm32] +platform = ${common_stm32.platform} +extends = env:STM32F103RC_btt_stm32 +board_upload.maximum_size = 524288 +build_flags = ${env:STM32F103RC_btt_stm32.build_flags} -DLD_MAX_DATA_SIZE=524288 -DSTM32_FLASH_SIZE=512 + +[env:STM32F103RC_btt_512K_USB_stm32] +platform = ${common_stm32.platform} +extends = env:STM32F103RC_btt_USB_stm32 +board_upload.maximum_size = 524288 +build_flags = ${env:STM32F103RC_btt_USB_stm32.build_flags} -DLD_MAX_DATA_SIZE=524288 -DSTM32_FLASH_SIZE=512 + # # STM32F103RE # From 398ce22c2ed16629ead07d8154f1d7f127adfbfc Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 11 May 2021 04:05:18 -0500 Subject: [PATCH 38/67] :art: Better error message for bad array sizes --- Marlin/src/inc/SanityCheck.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index c9aebe89ad..cac54cd1aa 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -2804,23 +2804,30 @@ constexpr float sanity_arr_1[] = DEFAULT_AXIS_STEPS_PER_UNIT, sanity_arr_3[] = DEFAULT_MAX_ACCELERATION; #define _ARR_TEST(N,I) (sanity_arr_##N[_MIN(I,int(COUNT(sanity_arr_##N))-1)] > 0) +#if HAS_MULTI_EXTRUDER + #define _EXTRA_NOTE " (Did you forget to enable DISTINCT_E_FACTORS?)" +#elif EXTRUDERS == 0 + #define _EXTRA_NOTE " (Note: EXTRUDERS is set to 0.)" +#else + #define _EXTRA_NOTE "" +#endif static_assert(COUNT(sanity_arr_1) >= XYZE, "DEFAULT_AXIS_STEPS_PER_UNIT requires X, Y, Z and E elements."); -static_assert(COUNT(sanity_arr_1) <= XYZE_N, "DEFAULT_AXIS_STEPS_PER_UNIT has too many elements. (Did you forget to enable DISTINCT_E_FACTORS?)"); +static_assert(COUNT(sanity_arr_1) <= XYZE_N, "DEFAULT_AXIS_STEPS_PER_UNIT has too many elements." _EXTRA_NOTE); static_assert( _ARR_TEST(1,0) && _ARR_TEST(1,1) && _ARR_TEST(1,2) && _ARR_TEST(1,3) && _ARR_TEST(1,4) && _ARR_TEST(1,5) && _ARR_TEST(1,6) && _ARR_TEST(1,7) && _ARR_TEST(1,8), "DEFAULT_AXIS_STEPS_PER_UNIT values must be positive."); static_assert(COUNT(sanity_arr_2) >= XYZE, "DEFAULT_MAX_FEEDRATE requires X, Y, Z and E elements."); -static_assert(COUNT(sanity_arr_2) <= XYZE_N, "DEFAULT_MAX_FEEDRATE has too many elements. (Did you forget to enable DISTINCT_E_FACTORS?)"); +static_assert(COUNT(sanity_arr_2) <= XYZE_N, "DEFAULT_MAX_FEEDRATE has too many elements." _EXTRA_NOTE); static_assert( _ARR_TEST(2,0) && _ARR_TEST(2,1) && _ARR_TEST(2,2) && _ARR_TEST(2,3) && _ARR_TEST(2,4) && _ARR_TEST(2,5) && _ARR_TEST(2,6) && _ARR_TEST(2,7) && _ARR_TEST(2,8), "DEFAULT_MAX_FEEDRATE values must be positive."); static_assert(COUNT(sanity_arr_3) >= XYZE, "DEFAULT_MAX_ACCELERATION requires X, Y, Z and E elements."); -static_assert(COUNT(sanity_arr_3) <= XYZE_N, "DEFAULT_MAX_ACCELERATION has too many elements. (Did you forget to enable DISTINCT_E_FACTORS?)"); +static_assert(COUNT(sanity_arr_3) <= XYZE_N, "DEFAULT_MAX_ACCELERATION has too many elements." _EXTRA_NOTE); static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) && _ARR_TEST(3,3) && _ARR_TEST(3,4) && _ARR_TEST(3,5) && _ARR_TEST(3,6) && _ARR_TEST(3,7) && _ARR_TEST(3,8), @@ -2863,6 +2870,7 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #endif #undef _ARR_TEST +#undef _EXTRA_NOTE #if BOTH(CNC_COORDINATE_SYSTEMS, NO_WORKSPACE_OFFSETS) #error "CNC_COORDINATE_SYSTEMS is incompatible with NO_WORKSPACE_OFFSETS." From 390878e78af3a0f07e2a1b2e784fc882e22edbd4 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 11 May 2021 04:01:21 -0500 Subject: [PATCH 39/67] :art: Additional utility macros --- Marlin/src/core/macros.h | 38 ++++++++++++++++++++++ Marlin/src/gcode/feature/trinamic/M122.cpp | 3 +- Marlin/src/inc/Conditionals_LCD.h | 4 +-- Marlin/src/module/temperature.cpp | 2 +- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h index 34d9e530ca..566087b76b 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -237,6 +237,38 @@ memcpy(&a[0],&b[0],_MIN(sizeof(a),sizeof(b))); \ }while(0) +#define CODE_9( A,B,C,D,E,F,G,H,I,...) A; B; C; D; E; F; G; H; I +#define CODE_8( A,B,C,D,E,F,G,H,...) A; B; C; D; E; F; G; H +#define CODE_7( A,B,C,D,E,F,G,...) A; B; C; D; E; F; G +#define CODE_6( A,B,C,D,E,F,...) A; B; C; D; E; F +#define CODE_5( A,B,C,D,E,...) A; B; C; D; E +#define CODE_4( A,B,C,D,...) A; B; C; D +#define CODE_3( A,B,C,...) A; B; C +#define CODE_2( A,B,...) A; B +#define CODE_1( A,...) A +#define _CODE_N(N,V...) CODE_##N(V) +#define CODE_N(N,V...) _CODE_N(N,V) + +#define GANG_16(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) A B C D E F G H I J K L M N O P +#define GANG_15(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) A B C D E F G H I J K L M N O +#define GANG_14(A,B,C,D,E,F,G,H,I,J,K,L,M,N,...) A B C D E F G H I J K L M N +#define GANG_13(A,B,C,D,E,F,G,H,I,J,K,L,M...) A B C D E F G H I J K L M +#define GANG_12(A,B,C,D,E,F,G,H,I,J,K,L...) A B C D E F G H I J K L +#define GANG_11(A,B,C,D,E,F,G,H,I,J,K,...) A B C D E F G H I J K +#define GANG_10(A,B,C,D,E,F,G,H,I,J,...) A B C D E F G H I J +#define GANG_9( A,B,C,D,E,F,G,H,I,...) A B C D E F G H I +#define GANG_8( A,B,C,D,E,F,G,H,...) A B C D E F G H +#define GANG_7( A,B,C,D,E,F,G,...) A B C D E F G +#define GANG_6( A,B,C,D,E,F,...) A B C D E F +#define GANG_5( A,B,C,D,E,...) A B C D E +#define GANG_4( A,B,C,D,...) A B C D +#define GANG_3( A,B,C,...) A B C +#define GANG_2( A,B,...) A B +#define GANG_1( A,...) A +#define _GANG_N(N,V...) GANG_##N(V) +#define GANG_N(N,V...) _GANG_N(N,V) +#define GANG_N_1(N,K) _GANG_N(N,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K) + // Macros for initializing arrays #define LIST_16(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P #define LIST_15(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O @@ -254,10 +286,13 @@ #define LIST_3( A,B,C,...) A,B,C #define LIST_2( A,B,...) A,B #define LIST_1( A,...) A +#define LIST_0(...) #define _LIST_N(N,V...) LIST_##N(V) #define LIST_N(N,V...) _LIST_N(N,V) +#define LIST_N_1(N,K) _LIST_N(N,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K) #define ARRAY_N(N,V...) { _LIST_N(N,V) } +#define ARRAY_N_1(N,K) { LIST_N_1(N,K) } #define _JOIN_1(O) (O) #define JOIN_N(N,C,V...) (DO(JOIN,C,LIST_N(N,V))) @@ -465,6 +500,9 @@ #define ADD8(N) ADD4(ADD4(N)) #define ADD9(N) ADD4(ADD5(N)) #define ADD10(N) ADD5(ADD5(N)) +#define SUM(A,B) _CAT(ADD,A)(B) +#define DOUBLE_(n) ADD##n(n) +#define DOUBLE(n) DOUBLE_(n) // Macros for subtracting #define DEC_0 0 diff --git a/Marlin/src/gcode/feature/trinamic/M122.cpp b/Marlin/src/gcode/feature/trinamic/M122.cpp index 429638665f..d007044ea3 100644 --- a/Marlin/src/gcode/feature/trinamic/M122.cpp +++ b/Marlin/src/gcode/feature/trinamic/M122.cpp @@ -32,7 +32,8 @@ * M122: Debug TMC drivers */ void GcodeSuite::M122() { - xyze_bool_t print_axis = { false, false, false, false }; + xyze_bool_t print_axis = ARRAY_N_1(NUM_AXIS, false); + bool print_all = true; LOOP_XYZE(i) if (parser.seen(axis_codes[i])) { print_axis[i] = true; print_all = false; } diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index ed86c1bf65..42349b955e 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -617,9 +617,9 @@ // Helper macros for extruder and hotend arrays #define HOTEND_LOOP() for (int8_t e = 0; e < HOTENDS; e++) #define ARRAY_BY_EXTRUDERS(V...) ARRAY_N(EXTRUDERS, V) -#define ARRAY_BY_EXTRUDERS1(v1) ARRAY_BY_EXTRUDERS(v1, v1, v1, v1, v1, v1, v1, v1) +#define ARRAY_BY_EXTRUDERS1(v1) ARRAY_N_1(EXTRUDERS, v1) #define ARRAY_BY_HOTENDS(V...) ARRAY_N(HOTENDS, V) -#define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1, v1, v1, v1, v1) +#define ARRAY_BY_HOTENDS1(v1) ARRAY_N_1(HOTENDS, v1) #if ENABLED(SWITCHING_EXTRUDER) && (DISABLED(SWITCHING_NOZZLE) || SWITCHING_EXTRUDER_SERVO_NR != SWITCHING_NOZZLE_SERVO_NR) #define DO_SWITCH_EXTRUDER 1 diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 72d801652f..03c0195085 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -313,7 +313,7 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, #endif #if ENABLED(ADAPTIVE_FAN_SLOWING) - uint8_t Temperature::fan_speed_scaler[FAN_COUNT] = ARRAY_N(FAN_COUNT, 128, 128, 128, 128, 128, 128, 128, 128); + uint8_t Temperature::fan_speed_scaler[FAN_COUNT] = ARRAY_N_1(FAN_COUNT, 128); #endif /** From 0c8a53e507fa792b114a89fe6902f4efe4ed2fe8 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 11 May 2021 10:47:32 -0500 Subject: [PATCH 40/67] :art: Misc. code cleanup --- Marlin/src/core/serial.h | 4 ++-- Marlin/src/feature/dac/dac_mcp4728.cpp | 2 +- Marlin/src/feature/joystick.cpp | 7 +------ Marlin/src/gcode/motion/M290.cpp | 2 +- Marlin/src/module/delta.cpp | 2 +- Marlin/src/module/settings.cpp | 8 ++++---- Marlin/src/module/stepper.h | 2 +- Marlin/src/module/tool_change.cpp | 5 +---- 8 files changed, 12 insertions(+), 20 deletions(-) diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h index c8024f4b8c..5c08be5c92 100644 --- a/Marlin/src/core/serial.h +++ b/Marlin/src/core/serial.h @@ -210,7 +210,7 @@ void serialprintPGM(PGM_P str); #define _SEP_N_P_REF() _SEP_N_P #define _SEP_1_P(s) serialprintPGM(s); #define _SEP_2_P(s,v) serial_echopair_PGM(s,v); -#define _SEP_3_P(s,v,V...) _SEP_2_P(s,v); DEFER(_SEP_N_P_REF)()(TWO_ARGS(V),V); +#define _SEP_3_P(s,v,V...) _SEP_2_P(s,v); DEFER2(_SEP_N_P_REF)()(TWO_ARGS(V),V); #define SERIAL_ECHOPAIR_P(V...) do{ EVAL(_SEP_N_P(TWO_ARGS(V),V)); }while(0) // Print up to 20 pairs of values followed by newline. Odd elements must be PSTR pointers. @@ -219,7 +219,7 @@ void serialprintPGM(PGM_P str); #define _SELP_N_P_REF() _SELP_N_P #define _SELP_1_P(s) { serialprintPGM(s); SERIAL_EOL(); } #define _SELP_2_P(s,v) { serial_echopair_PGM(s,v); SERIAL_EOL(); } -#define _SELP_3_P(s,v,V...) { _SEP_2_P(s,v); DEFER(_SELP_N_P_REF)()(TWO_ARGS(V),V); } +#define _SELP_3_P(s,v,V...) { _SEP_2_P(s,v); DEFER2(_SELP_N_P_REF)()(TWO_ARGS(V),V); } #define SERIAL_ECHOLNPAIR_P(V...) do{ EVAL(_SELP_N_P(TWO_ARGS(V),V)); }while(0) #ifdef AllowDifferentTypeInList diff --git a/Marlin/src/feature/dac/dac_mcp4728.cpp b/Marlin/src/feature/dac/dac_mcp4728.cpp index 4f33c4e050..2b57037d99 100644 --- a/Marlin/src/feature/dac/dac_mcp4728.cpp +++ b/Marlin/src/feature/dac/dac_mcp4728.cpp @@ -66,7 +66,7 @@ uint8_t MCP4728::analogWrite(const uint8_t channel, const uint16_t value) { } /** - * Write all input resistor values to EEPROM using SequencialWrite method. + * Write all input resistor values to EEPROM using SequentialWrite method. * This will update both input register and EEPROM value * This will also write current Vref, PowerDown, Gain settings to EEPROM */ diff --git a/Marlin/src/feature/joystick.cpp b/Marlin/src/feature/joystick.cpp index 3dca2eb2e9..2cc61ec5a3 100644 --- a/Marlin/src/feature/joystick.cpp +++ b/Marlin/src/feature/joystick.cpp @@ -164,12 +164,7 @@ Joystick joystick; xyz_float_t move_dist{0}; float hypot2 = 0; LOOP_XYZ(i) if (norm_jog[i]) { - move_dist[i] = seg_time * norm_jog[i] * - #if ENABLED(EXTENSIBLE_UI) - manual_feedrate_mm_s[i]; - #else - planner.settings.max_feedrate_mm_s[i]; - #endif + move_dist[i] = seg_time * norm_jog[i] * TERN(EXTENSIBLE_UI, manual_feedrate_mm_s, planner.settings.max_feedrate_mm_s)[i]; hypot2 += sq(move_dist[i]); } diff --git a/Marlin/src/gcode/motion/M290.cpp b/Marlin/src/gcode/motion/M290.cpp index 7cfab8d2db..7e5a017783 100644 --- a/Marlin/src/gcode/motion/M290.cpp +++ b/Marlin/src/gcode/motion/M290.cpp @@ -82,7 +82,7 @@ void GcodeSuite::M290() { const float offs = constrain(parser.value_axis_units(Z_AXIS), -2, 2); babystep.add_mm(Z_AXIS, offs); #if ENABLED(BABYSTEP_ZPROBE_OFFSET) - if (!parser.seen('P') || parser.value_bool()) mod_probe_offset(offs); + if (parser.boolval('P', true)) mod_probe_offset(offs); #endif } #endif diff --git a/Marlin/src/module/delta.cpp b/Marlin/src/module/delta.cpp index eb42bd1946..1be3df220f 100644 --- a/Marlin/src/module/delta.cpp +++ b/Marlin/src/module/delta.cpp @@ -271,7 +271,7 @@ void home_delta() { // Do this here all at once for Delta, because // XYZ isn't ABC. Applying this per-tower would // give the impression that they are the same. - LOOP_XYZ(i) set_axis_is_at_home((AxisEnum)i); + LOOP_ABC(i) set_axis_is_at_home((AxisEnum)i); sync_plan_position(); diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index 35b55c82f9..9d65bbb744 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -1072,7 +1072,7 @@ void MarlinSettings::postprocess() { { _FIELD_TEST(tmc_stepper_current); - tmc_stepper_current_t tmc_stepper_current = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + tmc_stepper_current_t tmc_stepper_current{0}; #if HAS_TRINAMIC_CONFIG #if AXIS_IS_TMC(X) @@ -1134,7 +1134,7 @@ void MarlinSettings::postprocess() { _FIELD_TEST(tmc_hybrid_threshold); #if ENABLED(HYBRID_THRESHOLD) - tmc_hybrid_threshold_t tmc_hybrid_threshold = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + tmc_hybrid_threshold_t tmc_hybrid_threshold{0}; #if AXIS_HAS_STEALTHCHOP(X) tmc_hybrid_threshold.X = stepperX.get_pwm_thrs(); #endif @@ -1538,7 +1538,7 @@ void MarlinSettings::postprocess() { EEPROM_READ(dummyf); #endif #else - for (uint8_t q = 4; q--;) EEPROM_READ(dummyf); + for (uint8_t q = XYZE; q--;) EEPROM_READ(dummyf); #endif EEPROM_READ(TERN(CLASSIC_JERK, dummyf, planner.junction_deviation_mm)); @@ -2256,7 +2256,7 @@ void MarlinSettings::postprocess() { const xyz_float_t &backlash_distance_mm = backlash.distance_mm; const uint8_t &backlash_correction = backlash.correction; #else - float backlash_distance_mm[XYZ]; + xyz_float_t backlash_distance_mm; uint8_t backlash_correction; #endif #if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM) diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index ca1781fb9c..bbe8df146f 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -250,7 +250,7 @@ class Stepper { #ifndef PWM_MOTOR_CURRENT #define PWM_MOTOR_CURRENT DEFAULT_PWM_MOTOR_CURRENT #endif - #define MOTOR_CURRENT_COUNT 3 + #define MOTOR_CURRENT_COUNT XYZ #elif HAS_MOTOR_CURRENT_SPI static constexpr uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT; #define MOTOR_CURRENT_COUNT COUNT(Stepper::digipot_count) diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 0c5673b31c..559caa7f98 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -113,10 +113,7 @@ void move_extruder_servo(const uint8_t e) { planner.synchronize(); - #if EXTRUDERS & 1 - if (e < EXTRUDERS - 1) - #endif - { + if ((EXTRUDERS & 1) && e < EXTRUDERS - 1) { MOVE_SERVO(_SERVO_NR(e), servo_angles[_SERVO_NR(e)][e & 1]); safe_delay(500); } From 5353a1ed1a5081783aad3870dd8af23483aa5437 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Wed, 12 May 2021 01:01:39 +0000 Subject: [PATCH 41/67] [cron] Bump distribution date (2021-05-12) --- Marlin/src/inc/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 7e63f30775..0ba593fde0 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2021-05-11" + #define STRING_DISTRIBUTION_DATE "2021-05-12" #endif /** From 0d629c80c7e218cbe07a85ba0d9bfeb49feb65c6 Mon Sep 17 00:00:00 2001 From: vyacheslav-shubin Date: Wed, 12 May 2021 10:17:06 +0300 Subject: [PATCH 42/67] =?UTF-8?q?=F0=9F=A9=B9=20G60-G61=20Save=20E=20posit?= =?UTF-8?q?ion=20(#21810)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/gcode/feature/pause/G60.cpp | 5 +-- Marlin/src/gcode/feature/pause/G61.cpp | 47 +++++++++++++++++++------- Marlin/src/module/motion.cpp | 2 +- Marlin/src/module/motion.h | 2 +- 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/Marlin/src/gcode/feature/pause/G60.cpp b/Marlin/src/gcode/feature/pause/G60.cpp index 6f695b99a9..670ea2a58b 100644 --- a/Marlin/src/gcode/feature/pause/G60.cpp +++ b/Marlin/src/gcode/feature/pause/G60.cpp @@ -48,10 +48,11 @@ void GcodeSuite::G60() { #if ENABLED(SAVED_POSITIONS_DEBUG) const xyze_pos_t &pos = stored_position[slot]; - DEBUG_ECHOPAIR_F(STR_SAVED_POS " S", slot); + DEBUG_ECHOPAIR(STR_SAVED_POS " S", slot); DEBUG_ECHOPAIR_F(" : X", pos.x); DEBUG_ECHOPAIR_F_P(SP_Y_STR, pos.y); - DEBUG_ECHOLNPAIR_F_P(SP_Z_STR, pos.z); + DEBUG_ECHOPAIR_F_P(SP_Z_STR, pos.z); + DEBUG_ECHOLNPAIR_F_P(SP_E_STR, pos.e); #endif } diff --git a/Marlin/src/gcode/feature/pause/G61.cpp b/Marlin/src/gcode/feature/pause/G61.cpp index 9d5dcc060a..bb11464902 100644 --- a/Marlin/src/gcode/feature/pause/G61.cpp +++ b/Marlin/src/gcode/feature/pause/G61.cpp @@ -27,6 +27,10 @@ #include "../../../module/planner.h" #include "../../gcode.h" #include "../../../module/motion.h" +#include "../../../module/planner.h" + +#define DEBUG_OUT ENABLED(SAVED_POSITIONS_DEBUG) +#include "../../../core/debug_out.h" /** * G61: Return to saved position @@ -34,11 +38,16 @@ * F - Feedrate (optional) for the move back. * S - Slot # (0-based) to restore from (default 0). * X Y Z - Axes to restore. At least one is required. + * E - Restore extruder position + * + * If XYZE are not given, default restore uses the smart blocking move. */ void GcodeSuite::G61(void) { const uint8_t slot = parser.byteval('S'); + #define SYNC_E(POINT) planner.set_e_position_mm((destination.e = current_position.e = (POINT))) + #if SAVED_POSITIONS < 256 if (slot >= SAVED_POSITIONS) { SERIAL_ERROR_MSG(STR_INVALID_POS_SLOT STRINGIFY(SAVED_POSITIONS)); @@ -47,25 +56,37 @@ void GcodeSuite::G61(void) { #endif // No saved position? No axes being restored? - if (!TEST(saved_slots[slot >> 3], slot & 0x07) || !parser.seen("XYZ")) return; - - SERIAL_ECHOPAIR(STR_RESTORING_POS " S", slot); - LOOP_XYZ(i) { - destination[i] = parser.seen(XYZ_CHAR(i)) - ? stored_position[slot][i] + parser.value_axis_units((AxisEnum)i) - : current_position[i]; - SERIAL_CHAR(' ', XYZ_CHAR(i)); - SERIAL_ECHO_F(destination[i]); - } - SERIAL_EOL(); + if (!TEST(saved_slots[slot >> 3], slot & 0x07)) return; // Apply any given feedrate over 0.0 feedRate_t saved_feedrate = feedrate_mm_s; const float fr = parser.linearval('F'); if (fr > 0.0) feedrate_mm_s = MMM_TO_MMS(fr); - // Move to the saved position - prepare_line_to_destination(); + if (!parser.seen_axis()) { + DEBUG_ECHOLNPGM("Default position restore"); + do_blocking_move_to(stored_position[slot], feedrate_mm_s); + SYNC_E(stored_position[slot].e); + } + else { + if (parser.seen("XYZ")) { + DEBUG_ECHOPAIR(STR_RESTORING_POS " S", slot); + LOOP_XYZ(i) { + destination[i] = parser.seen(XYZ_CHAR(i)) + ? stored_position[slot][i] + parser.value_axis_units((AxisEnum)i) + : current_position[i]; + DEBUG_CHAR(' ', XYZ_CHAR(i)); + DEBUG_ECHO_F(destination[i]); + } + DEBUG_EOL(); + // Move to the saved position + prepare_line_to_destination(); + } + if (parser.seen_test('E')) { + DEBUG_ECHOLNPAIR(STR_RESTORING_POS " S", slot, " E", current_position.e, "=>", stored_position[slot].e); + SYNC_E(stored_position[slot].e); + } + } feedrate_mm_s = saved_feedrate; } diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 7c0f8f404a..6ca8dc054c 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -102,7 +102,7 @@ xyze_pos_t destination; // {0} // G60/G61 Position Save and Return #if SAVED_POSITIONS uint8_t saved_slots[(SAVED_POSITIONS + 7) >> 3]; - xyz_pos_t stored_position[SAVED_POSITIONS]; + xyze_pos_t stored_position[SAVED_POSITIONS]; #endif // The active extruder (tool). Set with T command. diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index 647b3af52a..c734fbdf34 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -45,7 +45,7 @@ extern xyze_pos_t current_position, // High-level current tool position // G60/G61 Position Save and Return #if SAVED_POSITIONS extern uint8_t saved_slots[(SAVED_POSITIONS + 7) >> 3]; - extern xyz_pos_t stored_position[SAVED_POSITIONS]; + extern xyze_pos_t stored_position[SAVED_POSITIONS]; #endif // Scratch space for a cartesian result From 10a1ff1622271bcbbb90dbe48a3e2e047ed2c9a2 Mon Sep 17 00:00:00 2001 From: ellensp Date: Wed, 12 May 2021 19:18:44 +1200 Subject: [PATCH 43/67] Fix compile error (#21877) --- Marlin/src/gcode/feature/trinamic/M122.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/gcode/feature/trinamic/M122.cpp b/Marlin/src/gcode/feature/trinamic/M122.cpp index d007044ea3..c338e48df4 100644 --- a/Marlin/src/gcode/feature/trinamic/M122.cpp +++ b/Marlin/src/gcode/feature/trinamic/M122.cpp @@ -32,7 +32,7 @@ * M122: Debug TMC drivers */ void GcodeSuite::M122() { - xyze_bool_t print_axis = ARRAY_N_1(NUM_AXIS, false); + xyze_bool_t print_axis = ARRAY_N_1(XYZE, false); bool print_all = true; LOOP_XYZE(i) if (parser.seen(axis_codes[i])) { print_axis[i] = true; print_all = false; } From de77dbedf1091e401942739b56e2145d1b37790f Mon Sep 17 00:00:00 2001 From: Elton Law Date: Wed, 12 May 2021 03:21:55 -0400 Subject: [PATCH 44/67] =?UTF-8?q?=F0=9F=90=9B=20Fix=20G5=20IJ=20with=20Mot?= =?UTF-8?q?ion=20Mode=20(#21858)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/gcode/parser.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp index 7e75783b7a..896ff273cd 100644 --- a/Marlin/src/gcode/parser.cpp +++ b/Marlin/src/gcode/parser.cpp @@ -216,10 +216,9 @@ void GCodeParser::parse(char *p) { break; #if ENABLED(GCODE_MOTION_MODES) - #if ENABLED(ARC_SUPPORT) - case 'I' ... 'J': - if (motion_mode_codenum != 2 && motion_mode_codenum != 3) return; - #endif + case 'I' ... 'J': + if (motion_mode_codenum != 5 && \ + TERN1(ARC_SUPPORT, motion_mode_codenum != 2 && motion_mode_codenum != 3)) return; case 'Q': if (motion_mode_codenum != 5) return; case 'X' ... 'Z': case 'E' ... 'F': From 3734e8e02f2ad0f2f717798a264dd879eba0fc81 Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Wed, 12 May 2021 01:26:19 -0700 Subject: [PATCH 45/67] =?UTF-8?q?=E2=9C=A8=20BigTreeTech=20Octopus=20board?= =?UTF-8?q?=20(STM32F446ZET6)=20(#21826)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/core/boards.h | 30 +- Marlin/src/pins/pins.h | 6 +- .../src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h | 522 ++++++++++++++++++ .../boards/marlin_BigTree_Octopus_v1.json | 35 ++ .../PeripheralPins.c | 392 +++++++++++++ .../MARLIN_BIGTREE_OCTOPUS_V1_0/PinNamesVar.h | 30 + .../hal_conf_extra.h | 53 ++ .../MARLIN_BIGTREE_OCTOPUS_V1_0/ldscript.ld | 187 +++++++ .../MARLIN_BIGTREE_OCTOPUS_V1_0/variant.cpp | 239 ++++++++ .../MARLIN_BIGTREE_OCTOPUS_V1_0/variant.h | 216 ++++++++ ini/stm32f4.ini | 25 +- 11 files changed, 1718 insertions(+), 17 deletions(-) create mode 100644 Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h create mode 100644 buildroot/share/PlatformIO/boards/marlin_BigTree_Octopus_v1.json create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/PeripheralPins.c create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/PinNamesVar.h create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/hal_conf_extra.h create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/ldscript.ld create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/variant.cpp create mode 100644 buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/variant.h diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h index e32789e744..20aeac654d 100644 --- a/Marlin/src/core/boards.h +++ b/Marlin/src/core/boards.h @@ -370,20 +370,22 @@ #define BOARD_BTT_SKR_V2_0_REV_A 4211 // BigTreeTech SKR v2.0 Rev A (STM32F407VGT6) #define BOARD_BTT_SKR_V2_0_REV_B 4212 // BigTreeTech SKR v2.0 Rev B (STM32F407VGT6) #define BOARD_BTT_GTR_V1_0 4213 // BigTreeTech GTR v1.0 (STM32F407IGT) -#define BOARD_LERDGE_K 4214 // Lerdge K (STM32F407ZG) -#define BOARD_LERDGE_S 4215 // Lerdge S (STM32F407VE) -#define BOARD_LERDGE_X 4216 // Lerdge X (STM32F407VE) -#define BOARD_VAKE403D 4217 // VAkE 403D (STM32F446VET6) -#define BOARD_FYSETC_S6 4218 // FYSETC S6 (STM32F446VET6) -#define BOARD_FYSETC_S6_V2_0 4219 // FYSETC S6 v2.0 (STM32F446VET6) -#define BOARD_FYSETC_SPIDER 4220 // FYSETC Spider (STM32F446VET6) -#define BOARD_FLYF407ZG 4221 // FLYF407ZG (STM32F407ZG) -#define BOARD_MKS_ROBIN2 4222 // MKS_ROBIN2 (STM32F407ZE) -#define BOARD_MKS_ROBIN_PRO_V2 4223 // MKS Robin Pro V2 (STM32F407VE) -#define BOARD_MKS_ROBIN_NANO_V3 4224 // MKS Robin Nano V3 (STM32F407VG) -#define BOARD_ANET_ET4 4225 // ANET ET4 V1.x (STM32F407VGT6) -#define BOARD_ANET_ET4P 4226 // ANET ET4P V1.x (STM32F407VGT6) -#define BOARD_FYSETC_CHEETAH_V20 4227 // FYSETC Cheetah V2.0 +#define BOARD_BTT_OCTOPUS_V1_0 4214 // BigTreeTech Octopus v1.0 (STM32F446ZET6) +#define BOARD_LERDGE_K 4215 // Lerdge K (STM32F407ZG) +#define BOARD_LERDGE_S 4216 // Lerdge S (STM32F407VE) +#define BOARD_LERDGE_X 4217 // Lerdge X (STM32F407VE) +#define BOARD_VAKE403D 4218 // VAkE 403D (STM32F446VET6) +#define BOARD_FYSETC_S6 4219 // FYSETC S6 (STM32F446VET6) +#define BOARD_FYSETC_S6_V2_0 4220 // FYSETC S6 v2.0 (STM32F446VET6) +#define BOARD_FYSETC_SPIDER 4221 // FYSETC Spider (STM32F446VET6) +#define BOARD_FLYF407ZG 4222 // FLYF407ZG (STM32F407ZG) +#define BOARD_MKS_ROBIN2 4223 // MKS_ROBIN2 (STM32F407ZE) +#define BOARD_MKS_ROBIN_PRO_V2 4224 // MKS Robin Pro V2 (STM32F407VE) +#define BOARD_MKS_ROBIN_NANO_V3 4225 // MKS Robin Nano V3 (STM32F407VG) +#define BOARD_ANET_ET4 4226 // ANET ET4 V1.x (STM32F407VGT6) +#define BOARD_ANET_ET4P 4227 // ANET ET4P V1.x (STM32F407VGT6) +#define BOARD_FYSETC_CHEETAH_V20 4228 // FYSETC Cheetah V2.0 + // // ARM Cortex M7 diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index 2a70e571af..a8ed35b009 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -600,6 +600,8 @@ #include "stm32f4/pins_BTT_SKR_V2_0_REV_A.h" // STM32F4 env:BIGTREE_SKR_2 #elif MB(BTT_SKR_V2_0_REV_B) #include "stm32f4/pins_BTT_SKR_V2_0_REV_B.h" // STM32F4 env:BIGTREE_SKR_2 +#elif MB(BTT_OCTOPUS_V1_0) + #include "stm32f4/pins_BTT_OCTOPUS_V1_0.h" // STM32F4 env:BIGTREE_OCTOPUS_V1_0 env:BIGTREE_OCTOPUS_V1_0_USB #elif MB(LERDGE_K) #include "stm32f4/pins_LERDGE_K.h" // STM32F4 env:LERDGEK env:LERDGEK_usb_flash_drive #elif MB(LERDGE_S) @@ -722,7 +724,7 @@ #error "BOARD_BIQU_SKR_V1_1 has been renamed BOARD_BTT_SKR_V1_1. Please update your configuration." #elif MB(BIGTREE_SKR_V1_1) #error "BOARD_BIGTREE_SKR_V1_1 has been renamed BOARD_BTT_SKR_V1_1. Please update your configuration." - #elif MB(BIGTREE_SKR_V2_2) + #elif MB(BIGTREE_SKR_V1_2) #error "BOARD_BIGTREE_SKR_V1_2 has been renamed BOARD_BTT_SKR_V1_2. Please update your configuration." #elif MB(BIGTREE_SKR_V1_3) #error "BOARD_BIGTREE_SKR_V1_3 has been renamed BOARD_BTT_SKR_V1_3. Please update your configuration." @@ -757,7 +759,7 @@ #elif MB(RAMPS_LONGER3D_LK4PRO) #error "BOARD_RAMPS_LONGER3D_LK4PRO is now BOARD_LONGER3D_LKx_PRO. Please update your configuration." #elif MB(BTT_SKR_V2_0) - #error "BTT_SKR_V2_0 is now BTT_SKR_V2_0_REV_A or BTT_SKR_V2_0_REV_B. Please update your configuration." + #error "BTT_SKR_V2_0 is now BTT_SKR_V2_0_REV_A or BTT_SKR_V2_0_REV_B. See https://bit.ly/3t5d9JQ for more information. Please update your configuration." #else #error "Unknown MOTHERBOARD value set in Configuration.h" #endif diff --git a/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h b/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h new file mode 100644 index 0000000000..9f3a141ab0 --- /dev/null +++ b/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h @@ -0,0 +1,522 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "env_validate.h" + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "BTT OCTOPUS V1.0" +#endif + +// Onboard I2C EEPROM +#define I2C_EEPROM +#define MARLIN_EEPROM_SIZE 0x8000 // 32KB (24C32A) +#define I2C_SCL_PIN PB8 +#define I2C_SDA_PIN PB9 + +// USB Flash Drive support +#define HAS_OTG_USB_HOST_SUPPORT + +// +// Servos +#define SERVO0_PIN PB6 + +// +// Misc. Functions +// +#define LED_PIN PA13 + +// +// Trinamic Stallguard pins +// +#define X_DIAG_PIN PG6 // X-STOP +#define Y_DIAG_PIN PG9 // Y-STOP +#define Z_DIAG_PIN PG10 // Z-STOP +#define Z2_DIAG_PIN PG11 // Z2-STOP +#define E0_DIAG_PIN PG12 // E0DET +#define E1_DIAG_PIN PG13 // E1DET +#define E2_DIAG_PIN PG14 // E2DET +#define E3_DIAG_PIN PG15 // E3DET + +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN PB7 +#endif + +// +// Limit Switches +// +#ifdef X_STALL_SENSITIVITY + #define X_STOP_PIN X_DIAG_PIN + #if X_HOME_DIR < 0 + #define X_MAX_PIN E0_DIAG_PIN // E0DET + #else + #define X_MIN_PIN E0_DIAG_PIN // E0DET + #endif +#elif ENABLED(X_DUAL_ENDSTOPS) + #ifndef X_MIN_PIN + #define X_MIN_PIN X_DIAG_PIN // X-STOP + #endif + #ifndef X_MAX_PIN + #define X_MAX_PIN E0_DIAG_PIN // E0DET + #endif +#else + #define X_STOP_PIN X_DIAG_PIN // X-STOP +#endif + +#ifdef Y_STALL_SENSITIVITY + #define Y_STOP_PIN Y_DIAG_PIN + #if Y_HOME_DIR < 0 + #define Y_MAX_PIN E1_DIAG_PIN // E1DET + #else + #define Y_MIN_PIN E1_DIAG_PIN // E1DET + #endif +#elif ENABLED(Y_DUAL_ENDSTOPS) + #ifndef Y_MIN_PIN + #define Y_MIN_PIN Y_DIAG_PIN // Y-STOP + #endif + #ifndef Y_MAX_PIN + #define Y_MAX_PIN E1_DIAG_PIN // E1DET + #endif +#else + #define Y_STOP_PIN Y_DIAG_PIN // Y-STOP +#endif + +#ifdef Z_STALL_SENSITIVITY + #define Z_STOP_PIN Z_DIAG_PIN + #if Z_HOME_DIR < 0 + #define Z_MAX_PIN E2_DIAG_PIN // PWRDET + #else + #define Z_MIN_PIN E2_DIAG_PIN // PWRDET + #endif +#elif ENABLED(Z_MULTI_ENDSTOPS) + #ifndef Z_MIN_PIN + #define Z_MIN_PIN Z_DIAG_PIN // Z-STOP + #endif + #ifndef Z_MAX_PIN + #define Z_MAX_PIN E2_DIAG_PIN // PWRDET + #endif +#else + #define Z_STOP_PIN Z_DIAG_PIN // Z-STOP +#endif + +// +// Filament Runout Sensor +// +#define FIL_RUNOUT_PIN PG12 // E0DET +#define FIL_RUNOUT2_PIN PG13 // E1DET +#define FIL_RUNOUT3_PIN PG14 // E2DET +#define FIL_RUNOUT4_PIN PG15 // E3DET + +// +// Power Supply Control +// +#ifndef PS_ON_PIN + #define PS_ON_PIN PE11 // PS-ON +#endif + +// +// Power Loss Detection +// +#ifndef POWER_LOSS_PIN + #define POWER_LOSS_PIN PC0 // PWRDET +#endif + +// +// NeoPixel LED +// +#ifndef NEOPIXEL_PIN + #define NEOPIXEL_PIN PB0 +#endif + +// +// Steppers +// +#define X_STEP_PIN PF13 // MOTOR 0 +#define X_DIR_PIN PF12 +#define X_ENABLE_PIN PF14 +#ifndef X_CS_PIN + #define X_CS_PIN PC4 +#endif + +#define Y_STEP_PIN PG0 // MOTOR 1 +#define Y_DIR_PIN PG1 +#define Y_ENABLE_PIN PF15 +#ifndef Y_CS_PIN + #define Y_CS_PIN PD11 +#endif + +#define Z_STEP_PIN PF11 // MOTOR 2 +#define Z_DIR_PIN PG3 +#define Z_ENABLE_PIN PG5 +#ifndef Z_CS_PIN + #define Z_CS_PIN PC6 +#endif + +#define Z2_STEP_PIN PG4 // MOTOR 3 +#define Z2_DIR_PIN PC1 +#define Z2_ENABLE_PIN PA0 +#ifndef Z2_CS_PIN + #define Z2_CS_PIN PC7 +#endif + +#define E0_STEP_PIN PF9 // MOTOR 4 +#define E0_DIR_PIN PF10 +#define E0_ENABLE_PIN PG2 +#ifndef E0_CS_PIN + #define E0_CS_PIN PF2 +#endif + +#define E1_STEP_PIN PC13 // MOTOR 5 +#define E1_DIR_PIN PF0 +#define E1_ENABLE_PIN PF1 +#ifndef E1_CS_PIN + #define E1_CS_PIN PE4 +#endif + +#define E2_STEP_PIN PE2 // MOTOR 6 +#define E2_DIR_PIN PE3 +#define E2_ENABLE_PIN PD4 +#ifndef E2_CS_PIN + + #define E2_CS_PIN PE1 +#endif + +#define E3_STEP_PIN PE6 // MOTOR 7 +#define E3_DIR_PIN PA14 +#define E3_ENABLE_PIN PE0 +#ifndef E3_CS_PIN + #define E3_CS_PIN PD3 +#endif + +// +// Temperature Sensors +// +#define TEMP_BED_PIN PF3 // TB +#if TEMP_SENSOR_0 == 20 + #define TEMP_0_PIN PF8 // PT100 Connector +#else + #define TEMP_0_PIN PF4 // TH0 +#endif +#define TEMP_1_PIN PF5 // TH1 +#define TEMP_2_PIN PF6 // TH2 +#define TEMP_3_PIN PF7 // TH3 + +// +// Heaters / Fans +// +#define HEATER_BED_PIN PA1 // Hotbed +#define HEATER_0_PIN PA2 // Heater0 +#define HEATER_1_PIN PA3 // Heater1 +#define HEATER_2_PIN PB10 // Heater2 +#define HEATER_3_PIN PB11 // Heater3 + +#define FAN_PIN PA8 // Fan0 +#define FAN1_PIN PE5 // Fan1 +#define FAN2_PIN PD12 // Fan2 +#define FAN3_PIN PD13 // Fan3 +#define FAN4_PIN PD14 // Fan4 +#define FAN5_PIN PD15 // Fan5 + +// +// SD Support +// +#ifndef SDCARD_CONNECTION + #if HAS_WIRED_LCD + #define SDCARD_CONNECTION LCD + #else + #define SDCARD_CONNECTION ONBOARD + #endif +#endif + +// +// Software SPI pins for TMC2130 stepper drivers +// +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI PA7 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO PA6 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK PA5 + #endif +#endif + +#if HAS_TMC_UART + /** + * TMC2208/TMC2209 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 PC4 + #define X_SERIAL_RX_PIN PC4 + + #define Y_SERIAL_TX_PIN PD11 + #define Y_SERIAL_RX_PIN PD11 + + #define Z_SERIAL_TX_PIN PC6 + #define Z_SERIAL_RX_PIN PC6 + + #define Z2_SERIAL_TX_PIN PC7 + #define Z2_SERIAL_RX_PIN PC7 + + #define E0_SERIAL_TX_PIN PF2 + #define E0_SERIAL_RX_PIN PF2 + + #define E1_SERIAL_TX_PIN PE4 + #define E1_SERIAL_RX_PIN PE4 + + #define E2_SERIAL_TX_PIN PE1 + #define E2_SERIAL_RX_PIN PE1 + + #define E3_SERIAL_TX_PIN PD3 + #define E3_SERIAL_RX_PIN PD3 + + // Reduce baud rate to improve software serial reliability + #define TMC_BAUD_RATE 19200 +#endif + +/** + * ______ ______ + * NC | 1 2 | GND 5V | 1 2 | GND + * RESET | 3 4 | PC15 (SD_DETECT) (LCD_D7) PE15 | 3 4 | PE14 (LCD_D6) + * (MOSI) PA7 | 5 6 PB1 (BTN_EN2) (LCD_D5) PE13 | 5 6 PE12 (LCD_D4) + * (SD_SS) PA4 | 7 8 | PB2 (BTN_EN1) (LCD_RS) PE10 | 7 8 | PE9 (LCD_EN) + * (SCK) PA5 | 9 10 | PA6 (MISO) (BTN_ENC) PE7 | 9 10 | PE8 (BEEPER) + * ------ ----- + * EXP2 EXP1 + */ + +#define EXP1_03_PIN PE15 +#define EXP1_04_PIN PE14 +#define EXP1_05_PIN PE13 +#define EXP1_06_PIN PE12 +#define EXP1_07_PIN PE10 +#define EXP1_08_PIN PE9 +#define EXP1_09_PIN PE7 +#define EXP1_10_PIN PE8 + +#define EXP2_03_PIN -1 +#define EXP2_04_PIN PC15 +#define EXP2_05_PIN PA7 +#define EXP2_06_PIN PB2 +#define EXP2_07_PIN PA4 +#define EXP2_08_PIN PB1 +#define EXP2_09_PIN PA5 +#define EXP2_10_PIN PA6 + +// +// Onboard SD card +// Must use soft SPI because Marlin's default hardware SPI is tied to LCD's EXP2 +// +#if SD_CONNECTION_IS(ONBOARD) + #define SDIO_SUPPORT // Use SDIO for onboard SD + #define SD_DETECT_PIN PC14 +#elif SD_CONNECTION_IS(LCD) + + #define CUSTOM_SPI_PINS + #define SDSS PA4 + #define SD_SS_PIN SDSS + #define SD_SCK_PIN PA5 + #define SD_MISO_PIN PA6 + #define SD_MOSI_PIN PA7 + #define SD_DETECT_PIN PC15 + +#elif SD_CONNECTION_IS(CUSTOM_CABLE) + #error "CUSTOM_CABLE is not a supported SDCARD_CONNECTION for this board" +#endif + +#if ENABLED(BTT_MOTOR_EXPANSION) + /** + * ______ ______ + * NC | 1 2 | GND NC | 1 2 | GND + * NC | 3 4 | M1EN M2EN | 3 4 | M3EN + * M1STP | 5 6 M1DIR M1RX | 5 6 M1DIAG + * M2DIR | 7 8 | M2STP M2RX | 7 8 | M2DIAG + * M3DIR | 9 10 | M3STP M3RX | 9 10 | M3DIAG + * ------ ------ + * EXP2 EXP1 + */ + + // M1 on Driver Expansion Module + #define E4_STEP_PIN EXP2_05_PIN + #define E4_DIR_PIN EXP2_06_PIN + #define E4_ENABLE_PIN EXP2_04_PIN + #define E4_DIAG_PIN EXP1_06_PIN + #define E4_CS_PIN EXP1_05_PIN + #if HAS_TMC_UART + #define E4_SERIAL_TX_PIN EXP1_05_PIN + #define E4_SERIAL_RX_PIN EXP1_05_PIN + #endif + + // M2 on Driver Expansion Module + #define E5_STEP_PIN EXP2_08_PIN + #define E5_DIR_PIN EXP2_07_PIN + #define E5_ENABLE_PIN EXP1_03_PIN + #define E5_DIAG_PIN EXP1_08_PIN + #define E5_CS_PIN EXP1_07_PIN + #if HAS_TMC_UART + #define E5_SERIAL_TX_PIN EXP1_07_PIN + #define E5_SERIAL_RX_PIN EXP1_07_PIN + #endif + + // M3 on Driver Expansion Module + #define E6_STEP_PIN EXP2_10_PIN + #define E6_DIR_PIN EXP2_09_PIN + #define E6_ENABLE_PIN EXP1_04_PIN + #define E6_DIAG_PIN EXP1_10_PIN + #define E6_CS_PIN EXP1_09_PIN + #if HAS_TMC_UART + #define E6_SERIAL_TX_PIN EXP1_09_PIN + #define E6_SERIAL_RX_PIN EXP1_09_PIN + #endif + +#endif // BTT_MOTOR_EXPANSION + +// +// LCDs and Controllers +// +#if IS_TFTGLCD_PANEL + + #if ENABLED(TFTGLCD_PANEL_SPI) + #define TFTGLCD_CS EXP2_08_PIN + #endif + +#elif HAS_WIRED_LCD + + #define BEEPER_PIN EXP1_10_PIN + #define BTN_ENC EXP1_09_PIN + + #if ENABLED(CR10_STOCKDISPLAY) + + #define LCD_PINS_RS EXP1_04_PIN + + #define BTN_EN1 EXP1_08_PIN + #define BTN_EN2 EXP1_06_PIN + + #define LCD_PINS_ENABLE EXP1_03_PIN + #define LCD_PINS_D4 EXP1_05_PIN + + // CR10_STOCKDISPLAY default timing is too fast + #undef BOARD_ST7920_DELAY_1 + #undef BOARD_ST7920_DELAY_2 + #undef BOARD_ST7920_DELAY_3 + + #else + + #define LCD_PINS_RS EXP1_07_PIN + + #define BTN_EN1 EXP2_08_PIN + #define BTN_EN2 EXP2_06_PIN + + #define LCD_PINS_ENABLE EXP1_08_PIN + #define LCD_PINS_D4 EXP1_06_PIN + + #if ENABLED(FYSETC_MINI_12864) + #define DOGLCD_CS EXP1_08_PIN + #define DOGLCD_A0 EXP1_07_PIN + //#define LCD_BACKLIGHT_PIN -1 + #define LCD_RESET_PIN EXP1_06_PIN // Must be high or open for LCD to operate normally. + #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) + #ifndef RGB_LED_R_PIN + #define RGB_LED_R_PIN EXP1_05_PIN + #endif + #ifndef RGB_LED_G_PIN + #define RGB_LED_G_PIN EXP1_04_PIN + #endif + #ifndef RGB_LED_B_PIN + #define RGB_LED_B_PIN EXP1_03_PIN + #endif + #elif ENABLED(FYSETC_MINI_12864_2_1) + #define NEOPIXEL_PIN EXP1_05_PIN + #endif + #endif // !FYSETC_MINI_12864 + + #if IS_ULTIPANEL + #define LCD_PINS_D5 EXP1_05_PIN + #define LCD_PINS_D6 EXP1_04_PIN + #define LCD_PINS_D7 EXP1_03_PIN + + #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) + #define BTN_ENC_EN LCD_PINS_D7 // Detect the presence of the encoder + #endif + + #endif + + #endif +#endif // HAS_WIRED_LCD + +// Alter timing for graphical display +#if HAS_MARLINUI_U8GLIB + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 DELAY_NS(96) + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 DELAY_NS(48) + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 DELAY_NS(600) + #endif +#endif + +// +// WIFI +// + +/** + * ------- + * GND | 9 | | 8 | 3.3V + * (ESP-CS) PB12 | 10 | | 7 | PB15 (ESP-MOSI) + * 3.3V | 11 | | 6 | PB14 (ESP-MISO) + * (ESP-IO0) PD7 | 12 | | 5 | PB13 (ESP-CLK) + * (ESP-IO4) PD10 | 13 | | 4 | NC + * NC | 14 | | 3 | PE15 (ESP-EN) + * (ESP-RX) PD8 | 15 | | 2 | NC + * (ESP-TX) PD9 | 16 | | 1 | PE14 (ESP-RST) + * ------- + * WIFI + */ +#define ESP_WIFI_MODULE_COM 3 // Must also set either SERIAL_PORT or SERIAL_PORT_2 to this +#define ESP_WIFI_MODULE_BAUDRATE BAUDRATE // Must use same BAUDRATE as SERIAL_PORT & SERIAL_PORT_2 +#define ESP_WIFI_MODULE_RESET_PIN PG7 +#define ESP_WIFI_MODULE_ENABLE_PIN PG8 +#define ESP_WIFI_MODULE_GPIO0_PIN PD7 +#define ESP_WIFI_MODULE_GPIO4_PIN PD10 diff --git a/buildroot/share/PlatformIO/boards/marlin_BigTree_Octopus_v1.json b/buildroot/share/PlatformIO/boards/marlin_BigTree_Octopus_v1.json new file mode 100644 index 0000000000..a583b5783f --- /dev/null +++ b/buildroot/share/PlatformIO/boards/marlin_BigTree_Octopus_v1.json @@ -0,0 +1,35 @@ +{ + "build": { + "cpu": "cortex-m4", + "extra_flags": "-DSTM32F446xx", + "f_cpu": "180000000L", + "mcu": "stm32f446zet6", + "variant": "MARLIN_BIGTREE_OCTOPUS_V1_0" + }, + "connectivity": [ + "can" + ], + "debug": { + "jlink_device": "STM32F446ZE", + "openocd_target": "stm32f4x", + "svd_path": "STM32F446x.svd" + }, + "frameworks": [ + "arduino", + "stm32cube" + ], + "name": "STM32F446ZE (128k RAM. 512k Flash)", + "upload": { + "maximum_ram_size": 131072, + "maximum_size": 524288, + "protocol": "stlink", + "protocols": [ + "jlink", + "stlink", + "blackmagic", + "serial" + ] + }, + "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html", + "vendor": "Generic" +} diff --git a/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/PeripheralPins.c b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/PeripheralPins.c new file mode 100644 index 0000000000..75bbd1cf20 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/PeripheralPins.c @@ -0,0 +1,392 @@ +/* + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "Arduino.h" +#include "PeripheralPins.h" + +// ===== +// Note: Commented lines are alternative possibilities which are not used per default. +// If you change them, you will have to know what you do +// ===== + + +//*** ADC *** + +#ifdef HAL_ADC_MODULE_ENABLED +const PinMap PinMap_ADC[] = { + {PA_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 + {PA_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC2_IN4 + {PC_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC1_IN10 + {PC_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC1_IN11 + {PC_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC1_IN12 + {PC_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC1_IN13 + {PC_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC1_IN14 + {PF_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC3_IN9 TH_0 + {PF_4, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC3_IN14 TH_1 + {PF_5, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC3_IN15 TH_2 + {PF_6, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC3_IN4 TH_3 + {PF_7, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC3_IN5 EXP_13 + {PF_8, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC3_IN6 PT100 + {NC, NP, 0} + + // {PA_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC1_IN0 + // {PA_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC2_IN0 + // {PA_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC3_IN0 + // {PA_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC1_IN1 + // {PA_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC2_IN1 + // {PA_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC3_IN1 + // {PA_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2 + // {PA_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC2_IN2 + // {PA_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC3_IN2 + // {PA_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC2_IN3 + // {PA_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC3_IN3 + //{PA_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4 + // {PA_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5 + // {PA_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC2_IN5 + // {PA_6, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6 + // {PA_6, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC2_IN6 + // {PA_7, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7 + // {PA_7, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC2_IN7 + // {PB_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8 + // {PB_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC2_IN8 + // {PB_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC1_IN9 + // {PB_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC2_IN9 + // {PC_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC2_IN10 + // {PC_0, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC3_IN10 + // {PC_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC2_IN11 + // {PC_1, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC3_IN11 + // {PC_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC2_IN12 + // {PC_2, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC3_IN12 + // {PC_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC2_IN13 + // {PC_3, ADC3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC3_IN13 + // {PC_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC2_IN14 + // {PC_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC1_IN15 + // {PC_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC2_IN15 + +}; +#endif + +//*** DAC *** + +#ifdef HAL_DAC_MODULE_ENABLED +const PinMap PinMap_DAC[] = { + // {PA_4, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC_OUT1 + // {PA_5, DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC_OUT2 - LD2 + {NC, NP, 0} +}; +#endif + +//*** I2C *** + +#ifdef HAL_I2C_MODULE_ENABLED +const PinMap PinMap_I2C_SDA[] = { + // {PB_3, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + // {PB_4, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, + // {PB_7, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + {PB_9, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + // {PC_7, FMPI2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_FMPI2C1)}, + // {PC_9, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, + // {PC_12, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_I2C_MODULE_ENABLED +const PinMap PinMap_I2C_SCL[] = { + // {PA_8, I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)}, + // {PB_6, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + {PB_8, I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, + // {PB_10, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)}, + // {PC_6, FMPI2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_FMPI2C1)}, + {NC, NP, 0} +}; +#endif + +//*** PWM *** + +#ifdef HAL_TIM_MODULE_ENABLED +const PinMap PinMap_PWM[] = { + {PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + // {PA_0, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 1, 0)}, // TIM5_CH1 + // {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 + {PA_1, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 2, 0)}, // TIM5_CH2 + // {PA_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 - STLink Tx + // {PA_2, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 3, 0)}, // TIM5_CH3 - STLink Tx + // {PA_2, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1 - STLink Tx + // {PA_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 - STLink Rx + // {PA_3, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 4, 0)}, // TIM5_CH4 - STLink Rx + // {PA_3, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 2, 0)}, // TIM9_CH2 - STLink Rx + {PA_5, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + // {PA_5, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N + {PA_6, TIM13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1 + // {PA_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 + //{PA_7, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1 + // {PA_7, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N + // {PA_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 + // {PA_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N + {PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 + {PA_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2 + {PA_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 + {PA_11, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4 + {PA_15, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + // {PB_0, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N + // {PB_0, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3 + {PB_0, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // Fan0, TIM8_CH2N + // {PB_1, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N + // {PB_1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 + {PB_1, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // Fan1, TIM8_CH3N + {PB_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // Fan2, TIM2_CH4 + {PB_3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // E0 Heater, TIM2_CH2 + {PB_4, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // E1 Heater, TIM3_CH1 + {PB_5, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // LED G, TIM3_CH2 + {PB_6, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // LED R, TIM4_CH1 + {PB_7, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // LED B, TIM4_CH2 + // {PB_8, TIM10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1 + // {PB_8, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 + {PB_8, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 3, 0)}, // TIM4_CH3 + {PB_9, TIM11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 + // {PB_9, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 + // {PB_9, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 + {PB_10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 + {PB_13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N + {PB_14, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 1, 0)}, // TIM12_CH1 + // {PB_14, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N + // {PB_14, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N + {PB_15, TIM12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 2, 0)}, // TIM12_CH2 + // {PB_15, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N + // {PB_15, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N + {PC_6, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1 + // {PC_6, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 0)}, // TIM8_CH1 + // {PC_7, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2 + {PC_7, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 0)}, // TIM8_CH2 + {PC_8, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3 + // {PC_8, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 0)}, // TIM8_CH3 + // {PC_9, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 + {PC_9, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 4, 0)}, // TIM8_CH4 + {PD_12, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1 BED + {PD_13, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2 + {PD_14, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 3, 0)}, // TIM4_CH3 HEATER1 + {PD_15, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 + {PE_5, TIM9, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1 FAN1 + {PE_9, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 + {PE_10, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N + {NC, NP, 0} +}; +#endif + +//*** SERIAL *** + +#ifdef HAL_UART_MODULE_ENABLED +const PinMap PinMap_UART_TX[] = { + // {PA_0, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + // {PA_2, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + {PA_9, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + {PD_8, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + // {PB_6, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + // {PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + // {PC_6, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + // {PC_10, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + //{PC_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + // {PC_12, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +const PinMap PinMap_UART_RX[] = { + // {PA_1, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + // {PA_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + {PA_10, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + {PD_9, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + // {PB_7, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + // {PC_5, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + // {PC_7, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, + // {PC_11, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + //{PC_11, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + // {PD_2, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +const PinMap PinMap_UART_RTS[] = { + // {PA_1, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + // {PA_12, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + // {PA_15, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + // {PB_14, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + // {PC_8, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_UART5)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_UART_MODULE_ENABLED +const PinMap PinMap_UART_CTS[] = { + // {PA_0, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, + // {PA_11, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, + // {PB_0, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, + // {PB_13, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, + // {PC_9, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_UART5)}, + {NC, NP, 0} +}; +#endif + +//*** SPI *** + +#ifdef HAL_SPI_MODULE_ENABLED +const PinMap PinMap_SPI_MOSI[] = { + {PA_7, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + // {PB_0, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_SPI3)}, + // {PB_2, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_SPI3)}, + // {PB_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + // {PB_5, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + // {PB_15, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + // {PC_1, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_SPI2)}, + // {PC_1, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI3)}, + // {PC_3, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + // {PC_12, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +const PinMap PinMap_SPI_MISO[] = { + {PA_6, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + // {PB_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + // {PB_4, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + // {PB_14, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + // {PC_2, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + // {PC_11, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +const PinMap PinMap_SPI_SCLK[] = { + {PA_5, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + // {PA_9, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + // {PB_3, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + // {PB_3, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + // {PB_10, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + // {PB_13, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + // {PC_7, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + // {PC_10, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +const PinMap PinMap_SPI_SSEL[] = { + {PA_4, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + // {PA_4, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + // {PA_15, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, + // {PA_15, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, + // {PB_4, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_SPI2)}, + // {PB_9, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + // {PB_12, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, + {NC, NP, 0} +}; +#endif + +//*** CAN *** + +#ifdef HAL_CAN_MODULE_ENABLED +const PinMap PinMap_CAN_RD[] = { + // {PA_11, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + // {PB_5, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + // {PB_8, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + // {PB_12, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + {NC, NP, 0} +}; +#endif + +#ifdef HAL_CAN_MODULE_ENABLED +const PinMap PinMap_CAN_TD[] = { + // {PA_12, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + // {PB_6, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + // {PB_9, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, + // {PB_13, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, + {NC, NP, 0} +}; +#endif + +//*** ETHERNET *** + +//*** No Ethernet *** + +//*** QUADSPI *** + +#ifdef HAL_QSPI_MODULE_ENABLED +const PinMap PinMap_QUADSPI[] = { + // {PA_1, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3 + // {PB_2, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK + // {PB_6, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS + // {PC_9, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0 + // {PC_10, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1 + // {PC_11, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS + {NC, NP, 0} +}; +#endif + +//*** USB *** + +#ifdef HAL_PCD_MODULE_ENABLED +const PinMap PinMap_USB_OTG_FS[] = { + // {PA_8, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_SOF + // {PA_9, USB_OTG_FS, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)}, // USB_OTG_FS_VBUS + // {PA_10, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_ID + {PA_11, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_DM + {PA_12, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_DP + {NC, NP, 0} +}; +#endif + +#ifdef HAL_PCD_MODULE_ENABLED +const PinMap PinMap_USB_OTG_HS[] = { + {NC, NP, 0} +}; + + +#ifdef HAL_SD_MODULE_ENABLED +WEAK const PinMap PinMap_SD[] = { + // {PB_8, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_SDIO)}, // SDIO_D4 + // {PB_9, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_SDIO)}, // SDIO_D5 + // {PC_6, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_SDIO)}, // SDIO_D6 + // {PC_7, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_SDIO)}, // SDIO_D7 + {PC_8, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_SDIO)}, // SDIO_D0 + {PC_9, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_SDIO)}, // SDIO_D1 + {PC_10, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_SDIO)}, // SDIO_D2 + {PC_11, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_SDIO)}, // SDIO_D3 + {PC_12, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_SDIO)}, // SDIO_CK + {PD_2, SDIO, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_SDIO)}, // SDIO_CMD + {NC, NP, 0} +}; +#endif +#endif + + diff --git a/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/PinNamesVar.h b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/PinNamesVar.h new file mode 100644 index 0000000000..bff3f21349 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/PinNamesVar.h @@ -0,0 +1,30 @@ +/* SYS_WKUP */ +#ifdef PWR_WAKEUP_PIN1 + SYS_WKUP1 = PA_0, /* SYS_WKUP0 */ +#endif +#ifdef PWR_WAKEUP_PIN2 + SYS_WKUP2 = NC, +#endif +#ifdef PWR_WAKEUP_PIN3 + SYS_WKUP3 = NC, +#endif +#ifdef PWR_WAKEUP_PIN4 + SYS_WKUP4 = NC, +#endif +#ifdef PWR_WAKEUP_PIN5 + SYS_WKUP5 = NC, +#endif +#ifdef PWR_WAKEUP_PIN6 + SYS_WKUP6 = NC, +#endif +#ifdef PWR_WAKEUP_PIN7 + SYS_WKUP7 = NC, +#endif +#ifdef PWR_WAKEUP_PIN8 + SYS_WKUP8 = NC, +#endif +/* USB */ +#ifdef USBCON + USB_OTG_FS_DM = PA_11, + USB_OTG_FS_DP = PA_12, +#endif diff --git a/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/hal_conf_extra.h b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/hal_conf_extra.h new file mode 100644 index 0000000000..da974b1ba7 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/hal_conf_extra.h @@ -0,0 +1,53 @@ +#pragma once + +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +#define HAL_CRC_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +//#define HAL_RTC_MODULE_ENABLED Real Time Clock...do we use it? +#define HAL_SPI_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_USART_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +//#define HAL_UART_MODULE_ENABLED // by default +//#define HAL_PCD_MODULE_ENABLED // Since STM32 v3.10700.191028 this is automatically added if any type of USB is enabled (as in Arduino IDE) +#define HAL_SD_MODULE_ENABLED + +//#undef HAL_SD_MODULE_ENABLED +#undef HAL_DAC_MODULE_ENABLED +#undef HAL_FLASH_MODULE_ENABLED +#undef HAL_CAN_MODULE_ENABLED +#undef HAL_CAN_LEGACY_MODULE_ENABLED +#undef HAL_CEC_MODULE_ENABLED +#undef HAL_CRYP_MODULE_ENABLED +#undef HAL_DCMI_MODULE_ENABLED +#undef HAL_DMA2D_MODULE_ENABLED +#undef HAL_ETH_MODULE_ENABLED +#undef HAL_NAND_MODULE_ENABLED +#undef HAL_NOR_MODULE_ENABLED +#undef HAL_PCCARD_MODULE_ENABLED +#undef HAL_SRAM_MODULE_ENABLED +#undef HAL_SDRAM_MODULE_ENABLED +#undef HAL_HASH_MODULE_ENABLED +#undef HAL_EXTI_MODULE_ENABLED +#undef HAL_SMBUS_MODULE_ENABLED +#undef HAL_I2S_MODULE_ENABLED +#undef HAL_IWDG_MODULE_ENABLED +#undef HAL_LTDC_MODULE_ENABLED +#undef HAL_DSI_MODULE_ENABLED +#undef HAL_QSPI_MODULE_ENABLED +#undef HAL_RNG_MODULE_ENABLED +#undef HAL_SAI_MODULE_ENABLED +#undef HAL_IRDA_MODULE_ENABLED +#undef HAL_SMARTCARD_MODULE_ENABLED +#undef HAL_WWDG_MODULE_ENABLED +//#undef HAL_HCD_MODULE_ENABLED +#undef HAL_FMPI2C_MODULE_ENABLED +#undef HAL_SPDIFRX_MODULE_ENABLED +#undef HAL_DFSDM_MODULE_ENABLED +#undef HAL_LPTIM_MODULE_ENABLED +#undef HAL_MMC_MODULE_ENABLED diff --git a/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/ldscript.ld b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/ldscript.ld new file mode 100644 index 0000000000..5ced01158f --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/ldscript.ld @@ -0,0 +1,187 @@ +/* +***************************************************************************** +** + +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32F407VETx Device with +** 512KByte FLASH, 128KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2014 Ac6

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** 3. Neither the name of Ac6 nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200;; /* required amount of heap */ +_Min_Stack_Size = 0x400;; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x8008000, LENGTH = 512K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text ALIGN(4): + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata ALIGN(4): + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /*_siccmram = LOADADDR(.ccmram);*/ + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(4); + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/variant.cpp b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/variant.cpp new file mode 100644 index 0000000000..5ed098aab9 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/variant.cpp @@ -0,0 +1,239 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "pins_arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Pin number +const PinName digitalPin[] = { + PA_0, //D0 + PA_1, //D1 + PA_2, //D2 + PA_3, //D3 + PA_4, //D4 + PA_5, //D5 + PA_6, //D6 + PA_7, //D7 + PA_8, //D8 + PA_9, //D9 + PA_10, //D10 + PA_11, //D11 + PA_12, //D12 + PA_13, //D13 + PA_14, //D14 + PA_15, //D15 + PB_0, //D16 + PB_1, //D17 + PB_2, //D18 + PB_3, //D19 + PB_4, //D20 + PB_5, //D21 + PB_6, //D22 + PB_7, //D23 + PB_8, //D24 + PB_9, //D25 + PB_10, //D26 + PB_11, //D27 + PB_12, //D28 + PB_13, //D29 + PB_14, //D30 + PB_15, //D31 + PC_0, //D32 + PC_1, //D33 + PC_2, //D34 + PC_3, //D35 + PC_4, //D36 + PC_5, //D37 + PC_6, //D38 + PC_7, //D39 + PC_8, //D40 + PC_9, //D41 + PC_10, //D42 + PC_11, //D43 + PC_12, //D44 + PC_13, //D45 + PC_14, //D46 + PC_15, //D47 + PD_0, //D48 + PD_1, //D49 + PD_2, //D50 + PD_3, //D51 + PD_4, //D52 + PD_5, //D53 + PD_6, //D54 + PD_7, //D55 + PD_8, //D56 + PD_9, //D57 + PD_10, //D58 + PD_11, //D59 + PD_12, //D60 + PD_13, //D61 + PD_14, //D62 + PD_15, //D63 + PE_0, //D64 + PE_1, //D65 + PE_2, //D66 + PE_3, //D67 + PE_4, //D68 + PE_5, //D69 + PE_6, //D70 + PE_7, //D71 + PE_8, //D72 + PE_9, //D73 + PE_10, //D74 + PE_11, //D75 + PE_12, //D76 + PE_13, //D77 + PE_14, //D78 + PE_15, //D79 + PF_0, //D80 + PF_1, //D81 + PF_2, //D82 + PF_3, //D83 + PF_4, //D84 + PF_5, //D85 + PF_6, //D86 + PF_7, //D87 + PF_8, //D88 + PF_9, //D89 + PF_10, //D90 + PF_11, //D91 + PF_12, //D92 + PF_13, //D93 + PF_14, //D94 + PF_15, //D95 + PG_0, //D96 + PG_1, //D97 + PG_2, //D98 + PG_3, //D99 + PG_4, //D100 + PG_5, //D101 + PG_6, //D102 + PG_7, //D103 + PG_8, //D104 + PG_9, //D105 + PG_10, //D106 + PG_11, //D107 + PG_12, //D108 + PG_13, //D109 + PG_14, //D110 + PG_15, //D111 + + //Duplicated ADC Pins + PA_3, //D112/A0 + PA_4, //D113/A1 + PC_0, //D114/A2 + PC_1, //D115/A3 + PC_2, //D116/A4 + PC_3, //D117/A5 + PC_4, //D118/A6 + PF_3, //D119/A16 - 1:FSMC_A3 2:ADC3_IN9 + PF_4, //D120/A17 - 1:FSMC_A4 2:ADC3_IN14 + PF_5, //D121/A18 - 1:FSMC_A5 2:ADC3_IN15 + PF_6, //D122/A19 - 1:TIM10_CH1 2:ADC3_IN4 + PF_7, //D123/A20 - 1:TIM11_CH1 2:ADC3_IN5 + PF_8, //D124/A20 - 1:TIM11_CH1 2:ADC3_IN6 +}; + +#ifdef __cplusplus +} +#endif + +// ---------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow : + * System Clock source = PLL (HSE) + * SYSCLK(Hz) = 180000000 + * HCLK(Hz) = 180000000 + * AHB Prescaler = 1 + * APB1 Prescaler = 4 + * APB2 Prescaler = 2 + * HSE Frequency(Hz) = 12000000 + * PLL_M = 6 + * PLL_N = 180 + * PLL_P = 2 + * PLL_Q = 7 + * VDD(V) = 3.3 + * Main regulator output voltage = Scale1 mode + * Flash Latency(WS) = 5 + * @param None + * @retval None + */ +WEAK void SystemClock_Config(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + +#ifdef HAL_PWR_MODULE_ENABLED + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); +#endif + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 6; + RCC_OscInitStruct.PLL.PLLN = 180; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + RCC_OscInitStruct.PLL.PLLR = 2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + HAL_PWREx_EnableOverDrive(); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | + RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLRCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CLK48; + PeriphClkInitStruct.PLLSAI.PLLSAIM = 6; + PeriphClkInitStruct.PLLSAI.PLLSAIN = 96; + PeriphClkInitStruct.PLLSAI.PLLSAIQ = 2; + PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV4; + PeriphClkInitStruct.PLLSAIDivQ = 1; + PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48CLKSOURCE_PLLSAIP; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); +} + +#ifdef __cplusplus +} +#endif diff --git a/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/variant.h b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/variant.h new file mode 100644 index 0000000000..4305c81a45 --- /dev/null +++ b/buildroot/share/PlatformIO/variants/MARLIN_BIGTREE_OCTOPUS_V1_0/variant.h @@ -0,0 +1,216 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_ARDUINO_STM32_ +#define _VARIANT_ARDUINO_STM32_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +#define PA0 0 //D0 +#define PA1 1 //D1 +#define PA2 2 //D2 +#define PA3 3 //D3 +#define PA4 4 //D4 +#define PA5 5 //D5 +#define PA6 6 //D6 +#define PA7 7 //D7 +#define PA8 8 //D8 +#define PA9 9 //D9 +#define PA10 10 //D10 +#define PA11 11 //D11 +#define PA12 12 //D12 +#define PA13 13 //D13 +#define PA14 14 //D14 +#define PA15 15 //D15 +#define PB0 16 //D16 +#define PB1 17 //D17 +#define PB2 18 //D18 +#define PB3 19 //D19 +#define PB4 20 //D20 +#define PB5 21 //D21 +#define PB6 22 //D22 +#define PB7 23 //D23 +#define PB8 24 //D24 +#define PB9 25 //D25 +#define PB10 26 //D26 +#define PB11 27 //D27 +#define PB12 28 //D28 +#define PB13 29 //D29 +#define PB14 30 //D30 +#define PB15 31 //D31 +#define PC0 32 //D32 +#define PC1 33 //D33 +#define PC2 34 //D34 +#define PC3 35 //D35 +#define PC4 36 //D36 +#define PC5 37 //D37 +#define PC6 38 //D38 +#define PC7 39 //D39 +#define PC8 40 //D40 +#define PC9 41 //D41 +#define PC10 42 //D42 +#define PC11 43 //D43 +#define PC12 44 //D44 +#define PC13 45 //D45 +#define PC14 46 //D46 +#define PC15 47 //D47 +#define PD0 48 //D48 +#define PD1 49 //D49 +#define PD2 50 //D50 +#define PD3 51 //D51 +#define PD4 52 //D52 +#define PD5 53 //D53 +#define PD6 54 //D54 +#define PD7 55 //D55 +#define PD8 56 //D56 +#define PD9 57 //D57 +#define PD10 58 //D58 +#define PD11 59 //D59 +#define PD12 60 //D60 +#define PD13 61 //D61 +#define PD14 62 //D62 +#define PD15 63 //D63 +#define PE0 64 //D64 +#define PE1 65 //D65 +#define PE2 66 //D66 +#define PE3 67 //D67 +#define PE4 68 //D68 +#define PE5 69 //D69 +#define PE6 70 //D70 +#define PE7 71 //D71 +#define PE8 72 //D72 +#define PE9 73 //D73 +#define PE10 74 //D74 +#define PE11 75 //D75 +#define PE12 76 //D76 +#define PE13 77 //D77 +#define PE14 78 //D78 +#define PE15 79 //D79 +#define PF0 80 //D64 +#define PF1 81 //D65 +#define PF2 82 //D66 +#define PF3 83 //D67 +#define PF4 84 //D68 +#define PF5 85 //D69 +#define PF6 86 //D70 +#define PF7 87 //D71 +#define PF8 88 //D72 +#define PF9 89 //D73 +#define PF10 90 //D74 +#define PF11 91 //D75 +#define PF12 92 //D76 +#define PF13 93 //D77 +#define PF14 94 //D78 +#define PF15 95 //D79 +#define PG0 96 //D64 +#define PG1 97 //D65 +#define PG2 98 //D66 +#define PG3 99 //D67 +#define PG4 100 //D68 +#define PG5 101 //D69 +#define PG6 102 //D70 +#define PG7 103 //D71 +#define PG8 104 //D72 +#define PG9 105 //D73 +#define PG10 106 //D74 +#define PG11 107 //D75 +#define PG12 108 //D76 +#define PG13 109 //D77 +#define PG14 110 //D78 +#define PG15 111 //D79 + +// This must be a literal with the same value as PEND +#define NUM_DIGITAL_PINS 125 +// This must be a literal with a value less than or equal to to MAX_ANALOG_INPUTS +#define NUM_ANALOG_INPUTS 13 +#define NUM_ANALOG_FIRST 112 + +//#define ADC_RESOLUTION 12 + +// PWM resolution +//#define PWM_RESOLUTION 12 +#define PWM_FREQUENCY 20000 // >= 20 Khz => inaudible noise for fans +#define PWM_MAX_DUTY_CYCLE 255 + +// SPI Definitions +#define PIN_SPI_SS PA4 +#define PIN_SPI_MOSI PA7 +#define PIN_SPI_MISO PA6 +#define PIN_SPI_SCK PA5 + +// I2C Definitions +#define PIN_WIRE_SDA PB9 +#define PIN_WIRE_SCL PB8 + +// Timer Definitions +// Do not use timer used by PWM pin. See PinMap_PWM. +#define TIMER_TONE TIM6 +#define TIMER_SERVO TIM5 +#define TIMER_SERIAL TIM7 + +// UART Definitions +//#define SERIAL_UART_INSTANCE 1 // Connected to EXP3 header +/* Enable Serial 3 */ +#define HAVE_HWSERIAL1 +#define HAVE_HWSERIAL3 + +// Default pin used for 'Serial' instance (ex: ST-Link) +// Mandatory for Firmata +#define PIN_SERIAL_RX PA10 +#define PIN_SERIAL_TX PA9 + +/* HAL configuration */ +#define HSE_VALUE 12000000U + +#define FLASH_PAGE_SIZE (4U * 1024U) + +#ifdef __cplusplus +} // extern "C" +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_HARDWARE_OPEN Serial +#endif + +#endif /* _VARIANT_ARDUINO_STM32_ */ diff --git a/ini/stm32f4.ini b/ini/stm32f4.ini index 62038332b3..5d6d291182 100644 --- a/ini/stm32f4.ini +++ b/ini/stm32f4.ini @@ -228,7 +228,7 @@ extra_scripts = ${common.extra_scripts} pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py # -# Bigtreetech SKR V2.0 (STM32F407VGT6 ARM Cortex-M4) with USB Flash Drive Support +# BigTreeTech SKR V2.0 (STM32F407VGT6 ARM Cortex-M4) with USB Flash Drive Support # [env:BIGTREE_SKR_2] platform = ${common_stm32.platform} @@ -247,6 +247,29 @@ build_flags = ${stm_flash_drive.build_flags} -DUSE_USBHOST_HS -DUSE_USB_HS_IN_FS -DUSBD_IRQ_PRIO=5 -DUSBD_IRQ_SUBPRIO=6 -DHSE_VALUE=8000000U -DHAL_SD_MODULE_ENABLED +# +# BigTreeTech Octopus V1.0 (STM32F446ZET6 ARM Cortex-M4) +# +[env:BIGTREE_OCTOPUS_V1_0] +platform = ${common_stm32.platform} +extends = common_stm32 +board = marlin_BigTree_octopus_v1 +extra_scripts = ${common.extra_scripts} + pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py +build_flags = ${common_stm32.build_flags} + -DSTM32F446_5VX -DVECT_TAB_OFFSET=0x8000 -DUSE_USB_HS_IN_FS + +# +# BigTreeTech Octopus V1.0 (STM32F446ZET6 ARM Cortex-M4) with USB Flash Drive Support +# +[env:BIGTREE_OCTOPUS_V1_0_USB] +extends = env:BIGTREE_OCTOPUS_V1_0 +platform_packages = ${stm_flash_drive.platform_packages} +#build_unflags = -DUSBCON -DUSBD_USE_CDC +build_flags = ${stm_flash_drive.build_flags} + -DSTM32F446_5VX -DVECT_TAB_OFFSET=0x8000 + -DUSBCON -DUSE_USBHOST_HS -DUSBD_IRQ_PRIO=5 -DUSBD_IRQ_SUBPRIO=6 -DUSE_USB_HS_IN_FS -DUSBD_USE_CDC_MSC + # # Lerdge base # From 75dadcc6696239cc092ecfff264260041c52169a Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 12 May 2021 02:51:25 -0500 Subject: [PATCH 46/67] =?UTF-8?q?=F0=9F=93=9D=20Fix=20version=20reference?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/Serial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Serial.md b/docs/Serial.md index 15c0480bb0..f51b902723 100644 --- a/docs/Serial.md +++ b/docs/Serial.md @@ -5,7 +5,7 @@ While many provide a Arduino-like Serial class, it's not all of them, and the di Moreover, many platform have intrinsic needs about serial port (like forwarding the output on multiple serial port, providing a *serial-like* telnet server, mixing USB-based serial port with SD card emulation) that are difficult to handle cleanly in the other platform serial logic. -Starting with version `2.0.9`, Marlin provides a common interface for its serial needs. +Starting with version 2.0.8, Marlin provides a common interface for its serial needs. ## Common interface From 175fac8fe87cd527e3670bafb51fec6d372f56ac Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Wed, 12 May 2021 15:48:24 -0700 Subject: [PATCH 47/67] Always Invert Octopus Onboard SD Detect Pin (#21882) --- Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h b/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h index 9f3a141ab0..dce3018d64 100644 --- a/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h +++ b/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h @@ -349,6 +349,8 @@ // #if SD_CONNECTION_IS(ONBOARD) #define SDIO_SUPPORT // Use SDIO for onboard SD + #undef SD_DETECT_STATE + #define SD_DETECT_STATE HIGH #define SD_DETECT_PIN PC14 #elif SD_CONNECTION_IS(LCD) From b3804fb277ad402d5a50adb65ec4739016e75d8d Mon Sep 17 00:00:00 2001 From: Victor Oliveira Date: Wed, 12 May 2021 19:57:43 -0300 Subject: [PATCH 48/67] minor multi volume config typo (#21880) --- Marlin/Configuration_adv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 3ec45f3f46..47a844101f 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1486,8 +1486,8 @@ #if ENABLED(MULTI_VOLUME) #define VOLUME_SD_ONBOARD #define VOLUME_USB_FLASH_DRIVE - #define DEFAULT_VOLUME SD_ONBOARD - #define DEFAULT_SHARED_VOLUME USB_FLASH_DRIVE + #define DEFAULT_VOLUME SV_SD_ONBOARD + #define DEFAULT_SHARED_VOLUME SV_USB_FLASH_DRIVE #endif #endif // SDSUPPORT From c8f9a3261071af8bd138d1e6694a0f28216b2bf6 Mon Sep 17 00:00:00 2001 From: Victor Oliveira Date: Wed, 12 May 2021 20:10:31 -0300 Subject: [PATCH 49/67] Update Robin Pro TFT Pins (#21879) --- Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h | 34 ++++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h index 10e1633124..ed0e0f3aea 100644 --- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h @@ -43,7 +43,7 @@ // // Note: MKS Robin board is using SPI2 interface. // -#define SPI_DEVICE 2 +#define SPI_DEVICE 2 // // Servos @@ -188,7 +188,7 @@ // SD Card // #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD + #define SDCARD_CONNECTION ONBOARD #endif #if SD_CONNECTION_IS(LCD) @@ -210,12 +210,16 @@ * If the screen stays white, disable 'LCD_RESET_PIN' * to let the bootloader init the screen. */ -#if HAS_FSMC_GRAPHICAL_TFT - #define FSMC_CS_PIN PD7 // NE4 - #define FSMC_RS_PIN PD11 // A0 +#if HAS_FSMC_TFT + #define FSMC_CS_PIN PD7 // NE4 + #define FSMC_RS_PIN PD11 // A0 + #define TFT_CS_PIN FSMC_CS_PIN + #define TFT_RS_PIN FSMC_RS_PIN #define LCD_RESET_PIN PF6 #define LCD_BACKLIGHT_PIN PD13 + #define TFT_RESET_PIN LCD_RESET_PIN + #define TFT_BACKLIGHT_PIN LCD_BACKLIGHT_PIN #if NEED_TOUCH_PINS #define TOUCH_CS_PIN PA7 @@ -251,7 +255,8 @@ #define DOGLCD_SCK PB13 #define DOGLCD_MOSI PB15 - #else // !MKS_MINI_12864 && !ENDER2_STOCKDISPLAY + #else + // !MKS_MINI_12864 && !ENDER2_STOCKDISPLAY #define LCD_PINS_D4 PF14 #if IS_ULTIPANEL @@ -260,7 +265,7 @@ #define LCD_PINS_D7 PF13 #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) - #define BTN_ENC_EN LCD_PINS_D7 // Detect the presence of the encoder + #define BTN_ENC_EN LCD_PINS_D7 // Detect the presence of the encoder #endif #endif @@ -270,11 +275,20 @@ #endif #ifndef BOARD_ST7920_DELAY_1 - #define BOARD_ST7920_DELAY_1 DELAY_NS(125) + #define BOARD_ST7920_DELAY_1 DELAY_NS(125) #endif #ifndef BOARD_ST7920_DELAY_2 - #define BOARD_ST7920_DELAY_2 DELAY_NS(125) + #define BOARD_ST7920_DELAY_2 DELAY_NS(125) #endif #ifndef BOARD_ST7920_DELAY_3 - #define BOARD_ST7920_DELAY_3 DELAY_NS(125) + #define BOARD_ST7920_DELAY_3 DELAY_NS(125) +#endif + +#define HAS_SPI_FLASH 1 +#if HAS_SPI_FLASH + #define SPI_FLASH_SIZE 0x1000000 // 16MB + #define W25QXX_CS_PIN PB12 // Flash chip-select + #define W25QXX_MOSI_PIN PB15 + #define W25QXX_MISO_PIN PB14 + #define W25QXX_SCK_PIN PB13 #endif From eb7f75461a7751105bb18e67581df79e2f9131ad Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 12 May 2021 19:44:21 -0500 Subject: [PATCH 50/67] Clean up hasty PR --- Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h | 27 ++++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h index ed0e0f3aea..2f318dde42 100644 --- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h @@ -43,7 +43,7 @@ // // Note: MKS Robin board is using SPI2 interface. // -#define SPI_DEVICE 2 +#define SPI_DEVICE 2 // // Servos @@ -188,7 +188,7 @@ // SD Card // #ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD + #define SDCARD_CONNECTION ONBOARD #endif #if SD_CONNECTION_IS(LCD) @@ -211,15 +211,15 @@ * to let the bootloader init the screen. */ #if HAS_FSMC_TFT - #define FSMC_CS_PIN PD7 // NE4 - #define FSMC_RS_PIN PD11 // A0 - #define TFT_CS_PIN FSMC_CS_PIN - #define TFT_RS_PIN FSMC_RS_PIN + #define FSMC_CS_PIN PD7 // NE4 + #define FSMC_RS_PIN PD11 // A0 + #define TFT_CS_PIN FSMC_CS_PIN + #define TFT_RS_PIN FSMC_RS_PIN #define LCD_RESET_PIN PF6 #define LCD_BACKLIGHT_PIN PD13 - #define TFT_RESET_PIN LCD_RESET_PIN - #define TFT_BACKLIGHT_PIN LCD_BACKLIGHT_PIN + #define TFT_RESET_PIN LCD_RESET_PIN + #define TFT_BACKLIGHT_PIN LCD_BACKLIGHT_PIN #if NEED_TOUCH_PINS #define TOUCH_CS_PIN PA7 @@ -255,8 +255,7 @@ #define DOGLCD_SCK PB13 #define DOGLCD_MOSI PB15 - #else - // !MKS_MINI_12864 && !ENDER2_STOCKDISPLAY + #else // !MKS_MINI_12864 && !ENDER2_STOCKDISPLAY #define LCD_PINS_D4 PF14 #if IS_ULTIPANEL @@ -265,7 +264,7 @@ #define LCD_PINS_D7 PF13 #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) - #define BTN_ENC_EN LCD_PINS_D7 // Detect the presence of the encoder + #define BTN_ENC_EN LCD_PINS_D7 // Detect the presence of the encoder #endif #endif @@ -284,10 +283,10 @@ #define BOARD_ST7920_DELAY_3 DELAY_NS(125) #endif -#define HAS_SPI_FLASH 1 +#define HAS_SPI_FLASH 1 #if HAS_SPI_FLASH - #define SPI_FLASH_SIZE 0x1000000 // 16MB - #define W25QXX_CS_PIN PB12 // Flash chip-select + #define SPI_FLASH_SIZE 0x1000000 // 16MB + #define W25QXX_CS_PIN PB12 // Flash chip-select #define W25QXX_MOSI_PIN PB15 #define W25QXX_MISO_PIN PB14 #define W25QXX_SCK_PIN PB13 From 75f76cbf26d0acb8beb7698e2cee8621d4ca40a7 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Thu, 13 May 2021 01:06:32 +0000 Subject: [PATCH 51/67] [cron] Bump distribution date (2021-05-13) --- Marlin/src/inc/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 0ba593fde0..23c3de8510 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2021-05-12" + #define STRING_DISTRIBUTION_DATE "2021-05-13" #endif /** From 69473daa3d5fb0d30a6d4ddfa17e8d4ee278c14c Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Thu, 13 May 2021 01:14:37 -0500 Subject: [PATCH 52/67] =?UTF-8?q?=F0=9F=94=A7=20Improve=20SD=5FDETECT=5FST?= =?UTF-8?q?ATE=20default=20(#21885)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/inc/Conditionals_post.h | 23 ++++++++----------- Marlin/src/inc/SanityCheck.h | 7 ++++++ .../src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h | 7 ++++-- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index c237e6edd9..ec6e66d35a 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -330,11 +330,6 @@ */ #if ENABLED(SDSUPPORT) - // Extender cable doesn't support SD_DETECT_PIN - #if ENABLED(NO_SD_DETECT) - #undef SD_DETECT_PIN - #endif - #if HAS_SD_HOST_DRIVE && SD_CONNECTION_IS(ONBOARD) // // The external SD card is not used. Hardware SPI is used to access the card. @@ -345,18 +340,20 @@ #define HAS_SHARED_MEDIA 1 #endif - #if PIN_EXISTS(SD_DETECT) - #if HAS_LCD_MENU && (SD_CONNECTION_IS(LCD) || !defined(SDCARD_CONNECTION)) - #undef SD_DETECT_STATE - #if ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) - #define SD_DETECT_STATE HIGH - #endif - #endif - #ifndef SD_DETECT_STATE + // Set SD_DETECT_STATE based on hardware if not overridden + #if PIN_EXISTS(SD_DETECT) && !defined(SD_DETECT_STATE) + #if BOTH(HAS_LCD_MENU, ELB_FULL_GRAPHIC_CONTROLLER) && (SD_CONNECTION_IS(LCD) || !defined(SDCARD_CONNECTION)) + #define SD_DETECT_STATE HIGH + #else #define SD_DETECT_STATE LOW #endif #endif + // Extender cable doesn't support SD_DETECT_PIN + #if ENABLED(NO_SD_DETECT) + #undef SD_DETECT_PIN + #endif + #if DISABLED(USB_FLASH_DRIVE_SUPPORT) || BOTH(MULTI_VOLUME, VOLUME_SD_ONBOARD) #if ENABLED(SDIO_SUPPORT) #define NEED_SD2CARD_SDIO 1 diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index cac54cd1aa..0034c74c09 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -760,6 +760,13 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "LIGHTWEIGHT_UI requires a U8GLIB_ST7920-based display." #endif +/** + * SD Card Settings + */ +#if ALL(SDSUPPORT, ELB_FULL_GRAPHIC_CONTROLLER, HAS_LCD_MENU) && PIN_EXISTS(SD_DETECT) && SD_DETECT_STATE != HIGH && (SD_CONNECTION_IS(LCD) || !defined(SDCARD_CONNECTION)) + #error "SD_DETECT_STATE must be set HIGH for SD on the ELB_FULL_GRAPHIC_CONTROLLER." +#endif + /** * SD File Sorting */ diff --git a/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h b/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h index dce3018d64..8c16c2df29 100644 --- a/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h +++ b/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h @@ -349,8 +349,11 @@ // #if SD_CONNECTION_IS(ONBOARD) #define SDIO_SUPPORT // Use SDIO for onboard SD - #undef SD_DETECT_STATE - #define SD_DETECT_STATE HIGH + #ifndef SD_DETECT_STATE + #define SD_DETECT_STATE HIGH + #elif SD_DETECT_STATE == LOW + #error "BOARD_BTT_OCTOPUS_V1_0 onboard SD requires SD_DETECT_STATE set to HIGH." + #endif #define SD_DETECT_PIN PC14 #elif SD_CONNECTION_IS(LCD) From e72fe0ad142a3e36b1369cbc98b996b09cdef4bd Mon Sep 17 00:00:00 2001 From: FilippoR Date: Thu, 13 May 2021 17:56:49 +0200 Subject: [PATCH 53/67] fix compilation for home hon top (#21894) --- Marlin/src/feature/powerloss.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 552f1d9009..3764af13d0 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -380,12 +380,11 @@ void PrintJobRecovery::resume() { float z_now = z_raised; // If Z homing goes to max then just move back to the "raised" position - gcode.process_subcommands_now_P(PSTR( - "G28R0\n" // Home all axes (no raise) - "G1Z%sF1200" // Move Z down to (raised) height - ), - dtostrf(z_now, 1, 3, str_1) - ); + sprintf_P(cmd, PSTR( + "G28R0\n" // Home all axes (no raise) + "G1Z%sF1200" // Move Z down to (raised) height + ), dtostrf(z_now, 1, 3, str_1)); + gcode.process_subcommands_now(cmd); #else From 9336517258805bf6826bbe2403d4b5ba0b49977f Mon Sep 17 00:00:00 2001 From: "Alexander D. Kanevskiy" Date: Thu, 13 May 2021 23:10:48 +0300 Subject: [PATCH 54/67] Fix compilation failure in M1001 (#21897) --- Marlin/src/gcode/sd/M1001.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Marlin/src/gcode/sd/M1001.cpp b/Marlin/src/gcode/sd/M1001.cpp index 418e594deb..cd4933ff27 100644 --- a/Marlin/src/gcode/sd/M1001.cpp +++ b/Marlin/src/gcode/sd/M1001.cpp @@ -27,10 +27,7 @@ #include "../gcode.h" #include "../../module/planner.h" #include "../../module/printcounter.h" - -#if DISABLED(NO_SD_AUTOSTART) - #include "../../sd/cardreader.h" -#endif +#include "../../sd/cardreader.h" #ifdef SD_FINISHED_RELEASECOMMAND #include "../queue.h" From 90f14367640a942697f9e00df5762afe4121c566 Mon Sep 17 00:00:00 2001 From: ellensp Date: Fri, 14 May 2021 08:19:12 +1200 Subject: [PATCH 55/67] Fix nextion compile error (#21884) --- Marlin/src/lcd/extui/nextion/nextion_extui.cpp | 6 +++--- Marlin/src/lcd/extui/nextion/nextion_tft.cpp | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Marlin/src/lcd/extui/nextion/nextion_extui.cpp b/Marlin/src/lcd/extui/nextion/nextion_extui.cpp index 2ec8eeb30e..a825bd502f 100644 --- a/Marlin/src/lcd/extui/nextion/nextion_extui.cpp +++ b/Marlin/src/lcd/extui/nextion/nextion_extui.cpp @@ -26,12 +26,12 @@ * Nextion TFT support for Marlin */ -#include "../../inc/MarlinConfigPre.h" +#include "../../../inc/MarlinConfigPre.h" #if ENABLED(NEXTION_TFT) -#include "ui_api.h" -#include "lib/nextion/nextion_tft.h" +#include "../ui_api.h" +#include "nextion_tft.h" namespace ExtUI { diff --git a/Marlin/src/lcd/extui/nextion/nextion_tft.cpp b/Marlin/src/lcd/extui/nextion/nextion_tft.cpp index 35a5bb7c68..9035442681 100644 --- a/Marlin/src/lcd/extui/nextion/nextion_tft.cpp +++ b/Marlin/src/lcd/extui/nextion/nextion_tft.cpp @@ -645,6 +645,9 @@ void NextionTFT::UpdateOnChange() { last_flow_speed = getFlow_percent(getActiveTool()); } + // tmppage Axis + static float last_get_axis_position_mmX = 999, last_get_axis_position_mmY = 999, last_get_axis_position_mmZ = 999; + // tmppage Progress + Layer + Time if (isPrinting()) { @@ -679,9 +682,6 @@ void NextionTFT::UpdateOnChange() { } } - // tmppage Axis - static float last_get_axis_position_mmX = 999, last_get_axis_position_mmY = 999, last_get_axis_position_mmZ = 999; - if (!WITHIN(last_get_axis_position_mmX - getAxisPosition_mm(X), -0.1, 0.1)) { if (ELAPSED(ms, next_event_ms)) { next_event_ms = ms + 30; @@ -723,9 +723,9 @@ void NextionTFT::UpdateOnChange() { last_homedZ = isAxisPositionKnown(Z); } - // tmppage IDEX Mode - static uint8_t last_IDEX_Mode = 99; #if ENABLED(DUAL_X_CARRIAGE) + // tmppage IDEX Mode + static uint8_t last_IDEX_Mode = 99; if (last_IDEX_Mode != getIDEX_Mode()) { SEND_VAL("tmppage.idexmode", getIDEX_Mode()); last_IDEX_Mode = getIDEX_Mode(); From fe60a1892339600da18d2f54c074aa30708651e1 Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Thu, 13 May 2021 13:25:39 -0700 Subject: [PATCH 56/67] Fix Octopus 12864 LCD Delays (#21883) --- Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h b/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h index 8c16c2df29..994d19bb57 100644 --- a/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h +++ b/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h @@ -492,13 +492,13 @@ // Alter timing for graphical display #if HAS_MARLINUI_U8GLIB #ifndef BOARD_ST7920_DELAY_1 - #define BOARD_ST7920_DELAY_1 DELAY_NS(96) + #define BOARD_ST7920_DELAY_1 DELAY_NS(120) // DELAY_NS(96) #endif #ifndef BOARD_ST7920_DELAY_2 - #define BOARD_ST7920_DELAY_2 DELAY_NS(48) + #define BOARD_ST7920_DELAY_2 DELAY_NS(80) // DELAY_NS(48) #endif #ifndef BOARD_ST7920_DELAY_3 - #define BOARD_ST7920_DELAY_3 DELAY_NS(600) + #define BOARD_ST7920_DELAY_3 DELAY_NS(580) // DELAY_NS(600) #endif #endif From 558b60858c4500d98cd34c7ba19a82bafec23d4a Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Fri, 14 May 2021 01:08:17 +0000 Subject: [PATCH 57/67] [cron] Bump distribution date (2021-05-14) --- Marlin/src/inc/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 23c3de8510..46ad109e30 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2021-05-13" + #define STRING_DISTRIBUTION_DATE "2021-05-14" #endif /** From d97c1f1c6245e2b1f3152e5a210ed840b4bdbefb Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 14 May 2021 00:14:13 -0500 Subject: [PATCH 58/67] =?UTF-8?q?=E2=9C=A8=20Instant=20Freeze/Resume=20Fun?= =?UTF-8?q?ction=20(#17462)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine --- Marlin/Configuration_adv.h | 10 ++++++++++ Marlin/src/MarlinCore.cpp | 8 ++++++++ Marlin/src/inc/Conditionals_post.h | 16 +++++++++++++--- Marlin/src/inc/SanityCheck.h | 4 ++++ Marlin/src/module/stepper.cpp | 7 +++++++ Marlin/src/module/stepper.h | 4 ++++ Marlin/src/pins/pinsDebug_list.h | 5 ++++- buildroot/tests/mega2560 | 2 +- 8 files changed, 51 insertions(+), 5 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 47a844101f..1a1e11e234 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -3781,6 +3781,16 @@ #define GANTRY_CALIBRATION_COMMANDS_POST "G28" // G28 highly recommended to ensure an accurate position #endif +/** + * Instant freeze / unfreeze functionality + * Specified pin has pullup and connecting to ground will instantly pause motion. + * Potentially useful for emergency stop that allows being resumed. + */ +//#define FREEZE_FEATURE +#if ENABLED(FREEZE_FEATURE) + //#define FREEZE_PIN 41 // Override the default (KILL) pin here +#endif + /** * MAX7219 Debug Matrix * diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 85ee920e72..08d7968539 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -483,6 +483,10 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) { } #endif + #if HAS_FREEZE_PIN + Stepper::frozen = !READ(FREEZE_PIN); + #endif + #if HAS_HOME // Handle a standalone HOME button constexpr millis_t HOME_DEBOUNCE_DELAY = 1000UL; @@ -1089,6 +1093,10 @@ void setup() { #endif #endif + #if HAS_FREEZE_PIN + SET_INPUT_PULLUP(FREEZE_PIN); + #endif + #if HAS_SUICIDE SETUP_LOG("SUICIDE_PIN"); OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING); diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index ec6e66d35a..8c115fbab6 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2318,12 +2318,22 @@ #endif // User Interface +#if ENABLED(FREEZE_FEATURE) + #if !PIN_EXISTS(FREEZE) && PIN_EXISTS(KILL) + #define FREEZE_PIN KILL_PIN + #endif + #if PIN_EXISTS(FREEZE) + #define HAS_FREEZE_PIN 1 + #endif +#else + #undef FREEZE_PIN +#endif +#if PIN_EXISTS(KILL) && TERN1(FREEZE_FEATURE, KILL_PIN != FREEZE_PIN) + #define HAS_KILL 1 +#endif #if PIN_EXISTS(HOME) #define HAS_HOME 1 #endif -#if PIN_EXISTS(KILL) - #define HAS_KILL 1 -#endif #if PIN_EXISTS(SUICIDE) #define HAS_SUICIDE 1 #endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 0034c74c09..2131fcd678 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -3307,3 +3307,7 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) // Misc. Cleanup #undef _TEST_PWM + +#if ENABLED(FREEZE_FEATURE) && !PIN_EXISTS(FREEZE) + #error "FREEZE_FEATURE requires a FREEZE_PIN to be defined." +#endif diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 5a5fa3afe6..ff2be0c356 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -179,6 +179,10 @@ bool Stepper::abort_current_block; uint32_t Stepper::acceleration_time, Stepper::deceleration_time; uint8_t Stepper::steps_per_isr; +#if HAS_FREEZE_PIN + bool Stepper::frozen; // = false +#endif + IF_DISABLED(ADAPTIVE_STEP_SMOOTHING, constexpr) uint8_t Stepper::oversampling_factor; xyze_long_t Stepper::delta_error{0}; @@ -1531,6 +1535,9 @@ void Stepper::pulse_phase_isr() { // If there is no current block, do nothing if (!current_block) return; + // Skipping step processing causes motion to freeze + if (TERN0(HAS_FREEZE_PIN, frozen)) return; + // Count of pending loops and events for this iteration const uint32_t pending_events = step_event_count - step_events_completed; uint8_t events_to_do = _MIN(pending_events, steps_per_isr); diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index bbe8df146f..5ddd762aa9 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -266,6 +266,10 @@ class Stepper { static constexpr uint8_t last_moved_extruder = 0; #endif + #if HAS_FREEZE_PIN + static bool frozen; // Set this flag to instantly freeze motion + #endif + private: static block_t* current_block; // A pointer to the block currently being traced diff --git a/Marlin/src/pins/pinsDebug_list.h b/Marlin/src/pins/pinsDebug_list.h index 51a00630a4..8eee4f18fb 100644 --- a/Marlin/src/pins/pinsDebug_list.h +++ b/Marlin/src/pins/pinsDebug_list.h @@ -721,9 +721,12 @@ #if PIN_EXISTS(I2C_SDA) REPORT_NAME_DIGITAL(__LINE__, I2C_SDA_PIN) #endif -#if PIN_EXISTS(KILL) +#if HAS_KILL REPORT_NAME_DIGITAL(__LINE__, KILL_PIN) #endif +#if HAS_FREEZE_PIN + REPORT_NAME_DIGITAL(__LINE__, FREEZE_PIN) +#endif #if PIN_EXISTS(LCD_BACKLIGHT) REPORT_NAME_DIGITAL(__LINE__, LCD_BACKLIGHT_PIN) #endif diff --git a/buildroot/tests/mega2560 b/buildroot/tests/mega2560 index b4a3d2b9ac..98c4b761e0 100755 --- a/buildroot/tests/mega2560 +++ b/buildroot/tests/mega2560 @@ -21,7 +21,7 @@ opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO LCD_LANGUAGE fr \ opt_enable AUTO_BED_LEVELING_UBL RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_VALIDATION ENABLE_LEVELING_FADE_HEIGHT SKEW_CORRECTION \ REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER LIGHTWEIGHT_UI STATUS_MESSAGE_SCROLLING SHOW_CUSTOM_BOOTSCREEN BOOT_MARLIN_LOGO_SMALL \ SDSUPPORT SDCARD_SORT_ALPHA USB_FLASH_DRIVE_SUPPORT AUTO_REPORT_SD_STATUS SCROLL_LONG_FILENAMES CANCEL_OBJECTS SOUND_MENU_ITEM \ - EEPROM_SETTINGS EEPROM_CHITCHAT GCODE_MACROS CUSTOM_MENU_MAIN \ + EEPROM_SETTINGS EEPROM_CHITCHAT GCODE_MACROS CUSTOM_MENU_MAIN FREEZE_FEATURE \ MULTI_NOZZLE_DUPLICATION CLASSIC_JERK LIN_ADVANCE EXTRA_LIN_ADVANCE_K QUICK_HOME \ LCD_SET_PROGRESS_MANUALLY PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME \ BABYSTEPPING BABYSTEP_XY NANODLP_Z_SYNC I2C_POSITION_ENCODERS M114_DETAIL From a69e2923dd02537d777ee2e0d7cd838e39e66548 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 14 May 2021 00:17:04 -0500 Subject: [PATCH 59/67] =?UTF-8?q?=F0=9F=90=9B=20Fix=20RR=20collision=20wit?= =?UTF-8?q?h=20MM=20(#21902)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/gcode/parser.cpp | 97 +++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp index 896ff273cd..bfa4346f03 100644 --- a/Marlin/src/gcode/parser.cpp +++ b/Marlin/src/gcode/parser.cpp @@ -150,12 +150,30 @@ void GCodeParser::parse(char *p) { #endif /** - * Screen for good command letters. G, M, and T are always accepted. - * With Motion Modes enabled any axis letter can come first. + * Screen for good command letters. * With Realtime Reporting, commands S000, P000, and R000 are allowed. */ + #if ENABLED(REALTIME_REPORTING_COMMANDS) + switch (letter) { + case 'P': case 'R' ... 'S': { + uint8_t digits = 0; + char *a = p; + while (*a++ == '0') digits++; // Count up '0' characters + if (digits == 3) { // Three '0' digits is a good command + codenum = 0; + command_letter = letter; + return; + } + } + } + #endif + + /** + * Screen for good command letters. G, M, and T are always accepted. + * With Motion Modes enabled any axis letter can come first. + */ switch (letter) { - case 'G': case 'M': case 'T': TERN_(MARLIN_DEV_MODE, case 'D':) + case 'G': case 'M': case 'T': TERN_(MARLIN_DEV_MODE, case 'D':) { // Skip spaces to get the numeric part while (*p == ' ') p++; @@ -177,20 +195,18 @@ void GCodeParser::parse(char *p) { // A '?' signifies an unknown command command_letter = letter; - { - #if ENABLED(SIGNED_CODENUM) - int sign = 1; // Allow for a negative code like D-1 or T-1 - if (*p == '-') { sign = -1; ++p; } - #endif + #if ENABLED(SIGNED_CODENUM) + int sign = 1; // Allow for a negative code like D-1 or T-1 + if (*p == '-') { sign = -1; ++p; } + #endif - // Get the code number - integer digits only - codenum = 0; + // Get the code number - integer digits only + codenum = 0; - do { codenum = codenum * 10 + *p++ - '0'; } while (NUMERIC(*p)); + do { codenum = codenum * 10 + *p++ - '0'; } while (NUMERIC(*p)); - // Apply the sign, if any - TERN_(SIGNED_CODENUM, codenum *= sign); - } + // Apply the sign, if any + TERN_(SIGNED_CODENUM, codenum *= sign); // Allow for decimal point in command #if USE_GCODE_SUBCODES @@ -213,38 +229,33 @@ void GCodeParser::parse(char *p) { } #endif - break; + } break; #if ENABLED(GCODE_MOTION_MODES) - case 'I' ... 'J': - if (motion_mode_codenum != 5 && \ - TERN1(ARC_SUPPORT, motion_mode_codenum != 2 && motion_mode_codenum != 3)) return; - case 'Q': - if (motion_mode_codenum != 5) return; + + #if EITHER(BEZIER_CURVE_SUPPORT, ARC_SUPPORT) + case 'I' ... 'J': case 'P': + if (TERN1(BEZIER_CURVE_SUPPORT, motion_mode_codenum != 5) + && TERN1(ARC_P_CIRCLES, !WITHIN(motion_mode_codenum, 2, 3)) + ) return; + #endif + + #if ENABLED(BEZIER_CURVE_SUPPORT) + case 'Q': if (motion_mode_codenum != 5) return; + #endif + + #if ENABLED(ARC_SUPPORT) + case 'R': if (!WITHIN(motion_mode_codenum, 2, 3)) return; + #endif + case 'X' ... 'Z': case 'E' ... 'F': if (motion_mode_codenum < 0) return; command_letter = 'G'; codenum = motion_mode_codenum; TERN_(USE_GCODE_SUBCODES, subcode = motion_mode_subcode); p--; // Back up one character to use the current parameter - break; - #endif + break; - #if ENABLED(REALTIME_REPORTING_COMMANDS) - case 'P': case 'R': { - if (letter == 'R') { - #if ENABLED(GCODE_MOTION_MODES) - if (ENABLED(ARC_SUPPORT) && !WITHIN(motion_mode_codenum, 2, 3)) return; - #endif - } - else if (TERN0(GCODE_MOTION_MODES, motion_mode_codenum != 5)) return; - } // fall-thru - case 'S': { - codenum = 0; // The only valid codenum is 0 - uint8_t digits = 0; - while (*p++ == '0') digits++; // Count up '0' characters - command_letter = (digits == 3) ? letter : '?'; // Three '0' digits is a good command - } return; // No parameters needed, so return now #endif default: return; @@ -252,18 +263,12 @@ void GCodeParser::parse(char *p) { // The command parameters (if any) start here, for sure! - #if DISABLED(FASTER_GCODE_PARSER) - command_args = p; // Scan for parameters in seen() - #endif + IF_DISABLED(FASTER_GCODE_PARSER, command_args = p); // Scan for parameters in seen() // Only use string_arg for these M codes if (letter == 'M') switch (codenum) { - #if ENABLED(GCODE_MACROS) - case 810 ... 819: - #endif - #if ENABLED(EXPECTED_PRINTER_CHECK) - case 16: - #endif + TERN_(GCODE_MACROS, case 810 ... 819:) + TERN_(EXPECTED_PRINTER_CHECK, case 16:) case 23: case 28: case 30: case 117 ... 118: case 928: string_arg = unescape_string(p); return; From e5b280c3096a4c9974b1ba28ffca1bb27354e048 Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Thu, 13 May 2021 22:20:24 -0700 Subject: [PATCH 60/67] =?UTF-8?q?=F0=9F=9A=91=EF=B8=8F=20BTT=20Octopus=20S?= =?UTF-8?q?tep=20Timer=20(#21901)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h b/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h index 994d19bb57..6de3c544d3 100644 --- a/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h +++ b/Marlin/src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h @@ -36,6 +36,9 @@ // USB Flash Drive support #define HAS_OTG_USB_HOST_SUPPORT +// Avoid conflict with TIMER_TONE +#define STEP_TIMER 10 + // // Servos #define SERVO0_PIN PB6 From 2a5ab55c36380cd394c4922705412452f800c17c Mon Sep 17 00:00:00 2001 From: Victor Oliveira Date: Fri, 14 May 2021 02:22:43 -0300 Subject: [PATCH 61/67] =?UTF-8?q?=F0=9F=9A=91=EF=B8=8F=20Fix=20TFT=20for?= =?UTF-8?q?=20Robin=20Pro=20(#21900)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h index 2f318dde42..b56971c7a3 100644 --- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h @@ -213,6 +213,9 @@ #if HAS_FSMC_TFT #define FSMC_CS_PIN PD7 // NE4 #define FSMC_RS_PIN PD11 // A0 + #define FSMC_DMA_DEV DMA2 + #define FSMC_DMA_CHANNEL DMA_CH5 + #define LCD_USE_DMA_FSMC // Use DMA transfers to send data to the TFT #define TFT_CS_PIN FSMC_CS_PIN #define TFT_RS_PIN FSMC_RS_PIN @@ -221,8 +224,15 @@ #define TFT_RESET_PIN LCD_RESET_PIN #define TFT_BACKLIGHT_PIN LCD_BACKLIGHT_PIN + #define TFT_BUFFER_SIZE 14400 + #if NEED_TOUCH_PINS - #define TOUCH_CS_PIN PA7 + #define TOUCH_BUTTONS_HW_SPI + #define TOUCH_BUTTONS_HW_SPI_DEVICE 2 + #define TOUCH_CS_PIN PA7 // SPI2_NSS + #define TOUCH_SCK_PIN PB13 // SPI2_SCK + #define TOUCH_MISO_PIN PB14 // SPI2_MISO + #define TOUCH_MOSI_PIN PB15 // SPI2_MOSI #else #define BEEPER_PIN PC5 #define BTN_ENC PG2 From 3b4643d31a24cc6329ea3dd16827da18e77992e3 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Sat, 15 May 2021 01:05:33 +0000 Subject: [PATCH 62/67] [cron] Bump distribution date (2021-05-15) --- Marlin/src/inc/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 46ad109e30..f0695fe168 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2021-05-14" + #define STRING_DISTRIBUTION_DATE "2021-05-15" #endif /** From 874c531f27e7f342c7864c12310ef12c177d9000 Mon Sep 17 00:00:00 2001 From: ondrada <82547068+ondrada@users.noreply.github.com> Date: Sat, 15 May 2021 05:29:17 +0200 Subject: [PATCH 63/67] Fix G29_RETRY_AND_RECOVER dependency (#21907) Co-authored-by: Scott Lahteine --- Marlin/src/gcode/gcode.cpp | 8 ++++++-- Marlin/src/inc/Conditionals_LCD.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 241def0f77..7a3976a7bd 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -211,7 +211,7 @@ void GcodeSuite::dwell(millis_t time) { * When G29_RETRY_AND_RECOVER is enabled, call G29() in * a loop with recovery and retry handling. */ -#if BOTH(HAS_LEVELING, G29_RETRY_AND_RECOVER) +#if ENABLED(G29_RETRY_AND_RECOVER) void GcodeSuite::event_probe_recover() { TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_INFO, PSTR("G29 Retrying"), DISMISS_STR)); @@ -223,6 +223,10 @@ void GcodeSuite::dwell(millis_t time) { #endif } + #if ENABLED(G29_HALT_ON_FAILURE) + #include "../lcd/marlinui.h" + #endif + void GcodeSuite::event_probe_failure() { #ifdef ACTION_ON_G29_FAILURE host_action(PSTR(ACTION_ON_G29_FAILURE)); @@ -262,7 +266,7 @@ void GcodeSuite::dwell(millis_t time) { #endif } -#endif // HAS_LEVELING && G29_RETRY_AND_RECOVER +#endif // G29_RETRY_AND_RECOVER /** * Process the parsed command and dispatch it to its handler diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index 42349b955e..000aa60347 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -870,6 +870,7 @@ #if !HAS_LEVELING #undef RESTORE_LEVELING_AFTER_G28 #undef ENABLE_LEVELING_AFTER_G28 + #undef G29_RETRY_AND_RECOVER #endif #if !HAS_LEVELING || EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL) #undef PROBE_MANUALLY From 376f0be5da972c4e87e927b7aadba6e663010bb6 Mon Sep 17 00:00:00 2001 From: Moonglow Date: Sat, 15 May 2021 06:30:16 +0300 Subject: [PATCH 64/67] Fix MKS UI missing font select condition (#21905) --- Marlin/src/lcd/extui/mks_ui/draw_ui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp index 76898997eb..727120c183 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp @@ -374,7 +374,7 @@ void tft_style_init() { style_sel_text.body.grad_color = LV_COLOR_BACKGROUND; style_sel_text.text.color = LV_COLOR_YELLOW; style_sel_text.text.sel_color = LV_COLOR_YELLOW; - style_sel_text.text.font = &gb2312_puhui32; + style_sel_text.text.font = TERN(HAS_SPI_FLASH_FONT, &gb2312_puhui32, LV_FONT_DEFAULT); style_sel_text.line.width = 0; style_sel_text.text.letter_space = 0; style_sel_text.text.line_space = -5; From 7f774cab9005dd56667bf4db09c23370bd2c873f Mon Sep 17 00:00:00 2001 From: Luu Lac <45380455+shitcreek@users.noreply.github.com> Date: Sat, 15 May 2021 15:02:20 -0500 Subject: [PATCH 65/67] M154 Position Auto-Report (#18427) Co-authored-by: Scott Lahteine --- Marlin/Configuration_adv.h | 5 ++++ Marlin/src/MarlinCore.cpp | 1 + Marlin/src/gcode/gcode.cpp | 4 +++ Marlin/src/gcode/gcode.h | 5 ++++ Marlin/src/gcode/host/M115.cpp | 3 +++ Marlin/src/gcode/host/M154.cpp | 40 ++++++++++++++++++++++++++++++ Marlin/src/inc/Conditionals_post.h | 2 +- Marlin/src/module/motion.cpp | 5 ++++ Marlin/src/module/motion.h | 6 +++++ buildroot/tests/mega2560 | 2 +- ini/features.ini | 1 + platformio.ini | 1 + 12 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 Marlin/src/gcode/host/M154.cpp diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 1a1e11e234..4d75c8407a 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -3416,6 +3416,11 @@ */ #define AUTO_REPORT_TEMPERATURES +/** + * Auto-report position with M154 S + */ +//#define AUTO_REPORT_POSITION + /** * Include capabilities in M115 output */ diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 08d7968539..5cd0269bac 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -796,6 +796,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) { if (!gcode.autoreport_paused) { TERN_(AUTO_REPORT_TEMPERATURES, thermalManager.auto_reporter.tick()); TERN_(AUTO_REPORT_SD_STATUS, card.auto_reporter.tick()); + TERN_(AUTO_REPORT_POSITION, position_auto_reporter.tick()); } #endif diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 7a3976a7bd..0ca6c82c2a 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -565,6 +565,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 193: M193(); break; // M193: Wait for cooler temperature to reach target #endif + #if ENABLED(AUTO_REPORT_POSITION) + case 154: M154(); break; // M155: Set position auto-report interval + #endif + #if BOTH(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR) case 155: M155(); break; // M155: Set temperature auto-report interval #endif diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index dc0b89e098..cdf04cd0f2 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -159,6 +159,7 @@ * M145 - Set heatup values for materials on the LCD. H B F for S (0=PLA, 1=ABS) * M149 - Set temperature units. (Requires TEMPERATURE_UNITS_SUPPORT) * M150 - Set Status LED Color as R U B W P. Values 0-255. (Requires BLINKM, RGB_LED, RGBW_LED, NEOPIXEL_LED, PCA9533, or PCA9632). + * M154 - Auto-report position with interval of S. (Requires AUTO_REPORT_POSITION) * M155 - Auto-report temperatures with interval of S. (Requires AUTO_REPORT_TEMPERATURES) * M163 - Set a single proportion for a mixing extruder. (Requires MIXING_EXTRUDER) * M164 - Commit the mix and save to a virtual tool (current, or as specified by 'S'). (Requires MIXING_EXTRUDER) @@ -721,6 +722,10 @@ private: static void M150(); #endif + #if ENABLED(AUTO_REPORT_POSITION) + static void M154(); + #endif + #if BOTH(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR) static void M155(); #endif diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp index 4f18e5504d..ef4c8983cd 100644 --- a/Marlin/src/gcode/host/M115.cpp +++ b/Marlin/src/gcode/host/M115.cpp @@ -82,6 +82,9 @@ void GcodeSuite::M115() { // Volumetric Extrusion (M200) cap_line(PSTR("VOLUMETRIC"), DISABLED(NO_VOLUMETRICS)); + // AUTOREPORT_POS (M154) + cap_line(PSTR("AUTOREPORT_POS"), ENABLED(AUTO_REPORT_POSITION)); + // AUTOREPORT_TEMP (M155) cap_line(PSTR("AUTOREPORT_TEMP"), ENABLED(AUTO_REPORT_TEMPERATURES)); diff --git a/Marlin/src/gcode/host/M154.cpp b/Marlin/src/gcode/host/M154.cpp new file mode 100644 index 0000000000..156e6b69b6 --- /dev/null +++ b/Marlin/src/gcode/host/M154.cpp @@ -0,0 +1,40 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(AUTO_REPORT_POSITION) + +#include "../gcode.h" +#include "../../module/motion.h" + +/** + * M154: Set position auto-report interval. M154 S + */ +void GcodeSuite::M154() { + + if (parser.seenval('S')) + position_auto_reporter.set_interval(parser.value_byte()); + +} + +#endif // AUTO_REPORT_POSITION diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 8c115fbab6..6de9c40ac7 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2231,7 +2231,7 @@ #if !HAS_TEMP_SENSOR #undef AUTO_REPORT_TEMPERATURES #endif -#if EITHER(AUTO_REPORT_TEMPERATURES, AUTO_REPORT_SD_STATUS) +#if ANY(AUTO_REPORT_TEMPERATURES, AUTO_REPORT_SD_STATUS, AUTO_REPORT_POSITION) #define HAS_AUTO_REPORTING 1 #endif diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 6ca8dc054c..171d9520cb 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -230,6 +230,11 @@ void report_current_position_projected() { stepper.report_a_position(planner.position); } +#if ENABLED(AUTO_REPORT_POSITION) + //struct PositionReport { void report() { report_current_position_projected(); } }; + AutoReporter position_auto_reporter; +#endif + #if EITHER(FULL_REPORT_TO_HOST_FEATURE, REALTIME_REPORTING_COMMANDS) M_StateEnum M_State_grbl = M_INIT; diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index c734fbdf34..e01978c852 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -211,6 +211,12 @@ void report_real_position(); void report_current_position(); void report_current_position_projected(); +#if ENABLED(AUTO_REPORT_POSITION) + #include "../libs/autoreport.h" + struct PositionReport { static void report() { report_current_position_projected(); } }; + extern AutoReporter position_auto_reporter; +#endif + #if EITHER(FULL_REPORT_TO_HOST_FEATURE, REALTIME_REPORTING_COMMANDS) #define HAS_GRBL_STATE 1 /** diff --git a/buildroot/tests/mega2560 b/buildroot/tests/mega2560 index 98c4b761e0..7bbf29e630 100755 --- a/buildroot/tests/mega2560 +++ b/buildroot/tests/mega2560 @@ -56,7 +56,7 @@ opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO NUM_SERVOS 1 \ FIL_RUNOUT3_STATE HIGH opt_enable VIKI2 BOOT_MARLIN_LOGO_ANIMATED SDSUPPORT AUTO_REPORT_SD_STATUS \ Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE \ - EEPROM_SETTINGS EEPROM_CHITCHAT M114_DETAIL \ + EEPROM_SETTINGS EEPROM_CHITCHAT M114_DETAIL AUTO_REPORT_POSITION \ NO_VOLUMETRICS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET JOYSTICK \ DIRECT_STEPPING DETECT_BROKEN_ENDSTOP \ FILAMENT_RUNOUT_SENSOR NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE Z_SAFE_HOMING FIL_RUNOUT3_PULLUP diff --git a/ini/features.ini b/ini/features.ini index 586af1653f..6a2ccbedac 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -182,6 +182,7 @@ CNC_COORDINATE_SYSTEMS = src_filter=+ EXPECTED_PRINTER_CHECK = src_filter=+ HOST_KEEPALIVE_FEATURE = src_filter=+ +AUTO_REPORT_POSITION = src_filter=+ REPETIER_GCODE_M360 = src_filter=+ HAS_GCODE_M876 = src_filter=+ HAS_RESUME_CONTINUE = src_filter=+ diff --git a/platformio.ini b/platformio.ini index e743eb2db4..4d69ca12df 100644 --- a/platformio.ini +++ b/platformio.ini @@ -198,6 +198,7 @@ default_src_filter = + - - + - - - + - - - - From 05bb3bde7a761a3a3087ec29d0b45814cb2174bb Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 15 May 2021 15:21:02 -0500 Subject: [PATCH 66/67] Update Hex Version to 02000801 --- Marlin/Configuration.h | 2 +- Marlin/Configuration_adv.h | 2 +- Marlin/src/inc/Version.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 755b58fe15..78c2dc9160 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -35,7 +35,7 @@ * * Advanced settings can be found in Configuration_adv.h */ -#define CONFIGURATION_H_VERSION 020008 +#define CONFIGURATION_H_VERSION 02000801 //=========================================================================== //============================= Getting Started ============================= diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 4d75c8407a..5335fa012a 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -30,7 +30,7 @@ * * Basic settings can be found in Configuration.h */ -#define CONFIGURATION_ADV_H_VERSION 020008 +#define CONFIGURATION_ADV_H_VERSION 02000801 //=========================================================================== //============================= Thermal Settings ============================ diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index f0695fe168..3d69c70ba4 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -52,7 +52,7 @@ * to alert users to major changes. */ -#define MARLIN_HEX_VERSION 020008 +#define MARLIN_HEX_VERSION 02000801 #ifndef REQUIRED_CONFIGURATION_H_VERSION #define REQUIRED_CONFIGURATION_H_VERSION MARLIN_HEX_VERSION #endif From 533ba2ac96ee63ecc74bc4ba4473eecf0e4dab65 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Sun, 16 May 2021 01:12:19 +0000 Subject: [PATCH 67/67] [cron] Bump distribution date (2021-05-16) --- Marlin/src/inc/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 3d69c70ba4..90bd9f080f 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2021-05-15" + #define STRING_DISTRIBUTION_DATE "2021-05-16" #endif /**