Merge upstream changes from Marlin 2.1.2 #397

Merged
stklcode merged 1 commits from marlin-212 into master 2022-12-19 09:03:54 -06:00
427 changed files with 10732 additions and 7834 deletions

View File

@@ -14,6 +14,10 @@ end_of_line = lf
indent_style = space indent_style = space
indent_size = 2 indent_size = 2
[{*.py,*.conf,*.sublime-project}] [{*.py}]
indent_style = space
indent_size = 4
[{*.conf,*.sublime-project}]
indent_style = tab indent_style = tab
indent_size = 4 indent_size = 4

1
.gitignore vendored
View File

@@ -147,6 +147,7 @@ vc-fileutils.settings
imgui.ini imgui.ini
eeprom.dat eeprom.dat
spi_flash.bin spi_flash.bin
fs.img
#cmake #cmake
CMakeLists.txt CMakeLists.txt

View File

@@ -27,7 +27,7 @@ tests-single-ci:
tests-single-local: tests-single-local:
@if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET=<your-module> or use make tests-all-local" ; return 1; fi @if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET=<your-module> or use make tests-all-local" ; return 1; fi
export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \ export PATH="./buildroot/bin/:./buildroot/tests/:${PATH}" \
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \ && export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
&& run_tests . $(TEST_TARGET) "$(ONLY_TEST)" && run_tests . $(TEST_TARGET) "$(ONLY_TEST)"
.PHONY: tests-single-local .PHONY: tests-single-local
@@ -38,7 +38,7 @@ tests-single-local-docker:
.PHONY: tests-single-local-docker .PHONY: tests-single-local-docker
tests-all-local: tests-all-local:
export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \ export PATH="./buildroot/bin/:./buildroot/tests/:${PATH}" \
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \ && export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
&& for TEST_TARGET in $$(./get_test_targets.py) ; do echo "Running tests for $$TEST_TARGET" ; run_tests . $$TEST_TARGET ; done && for TEST_TARGET in $$(./get_test_targets.py) ; do echo "Running tests for $$TEST_TARGET" ; run_tests . $$TEST_TARGET ; done
.PHONY: tests-all-local .PHONY: tests-all-local

View File

@@ -35,8 +35,7 @@
* *
* Advanced settings can be found in Configuration_adv.h * Advanced settings can be found in Configuration_adv.h
*/ */
#define CONFIGURATION_H_VERSION 02010100 #define CONFIGURATION_H_VERSION 02010200
#define ANYCUBIC_TOUCHSCREEN #define ANYCUBIC_TOUCHSCREEN
#if DISABLED(KNUTWURST_4MAXP2) #if DISABLED(KNUTWURST_4MAXP2)
#define ANYCUBIC_FILAMENT_RUNOUT_SENSOR #define ANYCUBIC_FILAMENT_RUNOUT_SENSOR
@@ -222,6 +221,8 @@
// Choose your own or use a service like https://www.uuidgenerator.net/version4 // Choose your own or use a service like https://www.uuidgenerator.net/version4
// #define MACHINE_UUID "00000000-0000-0000-0000-000000000000" // #define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
// @section stepper drivers
/** /**
* Stepper Drivers * Stepper Drivers
* *
@@ -346,6 +347,8 @@
// #define SINGLENOZZLE_STANDBY_FAN // #define SINGLENOZZLE_STANDBY_FAN
#endif #endif
// @section multi-material
/** /**
* Multi-Material Unit * Multi-Material Unit
* Set to one of these predefined models: * Set to one of these predefined models:
@@ -358,6 +361,7 @@
* *
* Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails. * Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
* See additional options in Configuration_adv.h. * See additional options in Configuration_adv.h.
* :["PRUSA_MMU1", "PRUSA_MMU2", "PRUSA_MMU2S", "EXTENDABLE_EMU_MMU2", "EXTENDABLE_EMU_MMU2S"]
*/ */
// #define MMU_MODEL PRUSA_MMU2 // #define MMU_MODEL PRUSA_MMU2
@@ -597,7 +601,7 @@
* 30 : 100kΩ Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K - beta 3950 * 30 : 100kΩ Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K - beta 3950
* 60 : 100kΩ Maker's Tool Works Kapton Bed Thermistor - beta 3950 * 60 : 100kΩ Maker's Tool Works Kapton Bed Thermistor - beta 3950
* 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950 * 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950
* 66 : 4.7MΩ Dyze Design High Temperature Thermistor * 66 : 4.7MΩ Dyze Design / Trianglelab T-D500 500°C High Temperature Thermistor
* 67 : 500kΩ SliceEngineering 450°C Thermistor * 67 : 500kΩ SliceEngineering 450°C Thermistor
* 68 : PT100 amplifier board from Dyze Design * 68 : PT100 amplifier board from Dyze Design
* 70 : 100kΩ bq Hephestos 2 * 70 : 100kΩ bq Hephestos 2
@@ -619,6 +623,7 @@
* 110 : Pt100 with 1kΩ pullup (atypical) * 110 : Pt100 with 1kΩ pullup (atypical)
* 147 : Pt100 with 4.7kΩ pullup * 147 : Pt100 with 4.7kΩ pullup
* 1010 : Pt1000 with 1kΩ pullup (atypical) * 1010 : Pt1000 with 1kΩ pullup (atypical)
* 1022 : Pt1000 with 2.2kΩ pullup
* 1047 : Pt1000 with 4.7kΩ pullup (E3D) * 1047 : Pt1000 with 4.7kΩ pullup (E3D)
* 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage. * 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage.
* NOTE: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21. * NOTE: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21.
@@ -672,6 +677,10 @@
#define MAX31865_SENSOR_OHMS_1 100 #define MAX31865_SENSOR_OHMS_1 100
#define MAX31865_CALIBRATION_OHMS_1 430 #define MAX31865_CALIBRATION_OHMS_1 430
#endif #endif
#if TEMP_SENSOR_IS_MAX_TC(2)
#define MAX31865_SENSOR_OHMS_2 100
#define MAX31865_CALIBRATION_OHMS_2 430
#endif
#if HAS_E_TEMP_SENSOR #if HAS_E_TEMP_SENSOR
#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109 #define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
@@ -1020,7 +1029,7 @@
// #define POLARGRAPH // #define POLARGRAPH
#if ENABLED(POLARGRAPH) #if ENABLED(POLARGRAPH)
#define POLARGRAPH_MAX_BELT_LEN 1035.0 #define POLARGRAPH_MAX_BELT_LEN 1035.0
#define POLAR_SEGMENTS_PER_SECOND 5 #define DEFAULT_SEGMENTS_PER_SECOND 5
#endif #endif
// @section delta // @section delta
@@ -1032,28 +1041,26 @@
// Make delta curves from many straight lines (linear interpolation). // Make delta curves from many straight lines (linear interpolation).
// This is a trade-off between visible corners (not enough segments) // This is a trade-off between visible corners (not enough segments)
// and processor overload (too many expensive sqrt calls). // and processor overload (too many expensive sqrt calls).
#define DELTA_SEGMENTS_PER_SECOND 200 #define DEFAULT_SEGMENTS_PER_SECOND 200
// After homing move down to a height where XY movement is unconstrained // After homing move down to a height where XY movement is unconstrained
// #define DELTA_HOME_TO_SAFE_ZONE // #define DELTA_HOME_TO_SAFE_ZONE
// Delta calibration menu // Delta calibration menu
// uncomment to add three points calibration menu option. // Add three-point calibration to the MarlinUI menu.
// See http://minow.blogspot.com/index.html#4918805519571907051 // See http://minow.blogspot.com/index.html#4918805519571907051
// #define DELTA_CALIBRATION_MENU // #define DELTA_CALIBRATION_MENU
// uncomment to add G33 Delta Auto-Calibration (Enable EEPROM_SETTINGS to store results) // G33 Delta Auto-Calibration. Enable EEPROM_SETTINGS to store results.
// #define DELTA_AUTO_CALIBRATION // #define DELTA_AUTO_CALIBRATION
// NOTE NB all values for DELTA_* values MUST be floating point, so always have a decimal point in them
#if ENABLED(DELTA_AUTO_CALIBRATION) #if ENABLED(DELTA_AUTO_CALIBRATION)
// set the default number of probe points : n*n (1 -> 7) // Default number of probe points : n*n (1 -> 7)
#define DELTA_CALIBRATION_DEFAULT_POINTS 4 #define DELTA_CALIBRATION_DEFAULT_POINTS 4
#endif #endif
#if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU) #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
// Set the steprate for papertest probing // Step size for paper-test probing
#define PROBE_MANUALLY_STEP 0.05 // (mm) #define PROBE_MANUALLY_STEP 0.05 // (mm)
#endif #endif
@@ -1098,7 +1105,7 @@
// #define MP_SCARA // #define MP_SCARA
#if EITHER(MORGAN_SCARA, MP_SCARA) #if EITHER(MORGAN_SCARA, MP_SCARA)
// If movement is choppy try lowering this value // If movement is choppy try lowering this value
#define SCARA_SEGMENTS_PER_SECOND 200 #define DEFAULT_SEGMENTS_PER_SECOND 200
// Length of inner and outer support arms. Measure arm lengths precisely. // Length of inner and outer support arms. Measure arm lengths precisely.
#define SCARA_LINKAGE_1 150 // (mm) #define SCARA_LINKAGE_1 150 // (mm)
@@ -1134,18 +1141,18 @@
// Enable for TPARA kinematics and configure below // Enable for TPARA kinematics and configure below
// #define AXEL_TPARA // #define AXEL_TPARA
#if ENABLED(AXEL_TPARA) #if ENABLED(AXEL_TPARA)
#define DEBUG_ROBOT_KINEMATICS #define DEBUG_TPARA_KINEMATICS
#define ROBOT_SEGMENTS_PER_SECOND 200 #define DEFAULT_SEGMENTS_PER_SECOND 200
// Length of inner and outer support arms. Measure arm lengths precisely. // Length of inner and outer support arms. Measure arm lengths precisely.
#define ROBOT_LINKAGE_1 120 // (mm) #define TPARA_LINKAGE_1 120 // (mm)
#define ROBOT_LINKAGE_2 120 // (mm) #define TPARA_LINKAGE_2 120 // (mm)
// SCARA tower offset (position of Tower relative to bed zero position) // SCARA tower offset (position of Tower relative to bed zero position)
// This needs to be reasonably accurate as it defines the printbed position in the SCARA space. // This needs to be reasonably accurate as it defines the printbed position in the SCARA space.
#define ROBOT_OFFSET_X 0 // (mm) #define TPARA_OFFSET_X 0 // (mm)
#define ROBOT_OFFSET_Y 0 // (mm) #define TPARA_OFFSET_Y 0 // (mm)
#define ROBOT_OFFSET_Z 0 // (mm) #define TPARA_OFFSET_Z 0 // (mm)
#define SCARA_FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly #define SCARA_FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly
@@ -1998,7 +2005,7 @@
#define DISABLE_E false // Disable the extruder when not stepping #define DISABLE_E false // Disable the extruder when not stepping
#define DISABLE_INACTIVE_EXTRUDER // Keep only the active extruder enabled #define DISABLE_INACTIVE_EXTRUDER // Keep only the active extruder enabled
// @section machine // @section motion
#if DISABLED(KNUTWURST_TMC) #if DISABLED(KNUTWURST_TMC)
#if ANY(KNUTWURST_MEGA, KNUTWURST_MEGA_S, KNUTWURST_MEGA_X) #if ANY(KNUTWURST_MEGA, KNUTWURST_MEGA_S, KNUTWURST_MEGA_X)
@@ -2519,17 +2526,21 @@
#endif #endif
#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL) #if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL)
// Gradually reduce leveling correction until a set height is reached, /**
// at which point movement will be level to the machine's XY plane. * Gradually reduce leveling correction until a set height is reached,
// The height can be set with M420 Z<height> * at which point movement will be level to the machine's XY plane.
* The height can be set with M420 Z<height>
*/
#define ENABLE_LEVELING_FADE_HEIGHT #define ENABLE_LEVELING_FADE_HEIGHT
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
#define DEFAULT_LEVELING_FADE_HEIGHT 0.0 // (mm) Default fade height. #define DEFAULT_LEVELING_FADE_HEIGHT 0.0 // (mm) Default fade height.
#endif #endif
// For Cartesian machines, instead of dividing moves on mesh boundaries, /**
// split up moves into short segments like a Delta. This follows the * For Cartesian machines, instead of dividing moves on mesh boundaries,
// contours of the bed more closely than edge-to-edge straight moves. * split up moves into short segments like a Delta. This follows the
* contours of the bed more closely than edge-to-edge straight moves.
*/
#define SEGMENT_LEVELED_MOVES #define SEGMENT_LEVELED_MOVES
#define LEVELED_SEGMENT_LENGTH 5.0 // (mm) Length of all segments (except the last one) #define LEVELED_SEGMENT_LENGTH 5.0 // (mm) Length of all segments (except the last one)
@@ -2758,9 +2769,8 @@
#define XY_DIAG_BD 282.8427124746 #define XY_DIAG_BD 282.8427124746
#define XY_SIDE_AD 200 #define XY_SIDE_AD 200
// Or, set the default skew factors directly here // Or, set the XY skew factor directly:
// to override the above measurements: // #define XY_SKEW_FACTOR 0.0
#define XY_SKEW_FACTOR 0.0
// #define SKEW_CORRECTION_FOR_Z // #define SKEW_CORRECTION_FOR_Z
#if ENABLED(SKEW_CORRECTION_FOR_Z) #if ENABLED(SKEW_CORRECTION_FOR_Z)
@@ -2769,8 +2779,10 @@
#define YZ_DIAG_AC 282.8427124746 #define YZ_DIAG_AC 282.8427124746
#define YZ_DIAG_BD 282.8427124746 #define YZ_DIAG_BD 282.8427124746
#define YZ_SIDE_AD 200 #define YZ_SIDE_AD 200
#define XZ_SKEW_FACTOR 0.0
#define YZ_SKEW_FACTOR 0.0 // Or, set the Z skew factors directly:
// #define XZ_SKEW_FACTOR 0.0
// #define YZ_SKEW_FACTOR 0.0
#endif #endif
// Enable this option for M852 to set skew at runtime // Enable this option for M852 to set skew at runtime
@@ -2828,7 +2840,7 @@
// @section temperature // @section temperature
// //
// Preheat Constants - Up to 6 are supported without changes // Preheat Constants - Up to 10 are supported without changes
// //
#define PREHEAT_1_LABEL "PLA" #define PREHEAT_1_LABEL "PLA"
#define PREHEAT_1_TEMP_HOTEND 180 #define PREHEAT_1_TEMP_HOTEND 180
@@ -2986,7 +2998,7 @@
*/ */
#define PRINTCOUNTER #define PRINTCOUNTER
#if ENABLED(PRINTCOUNTER) #if ENABLED(PRINTCOUNTER)
#define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print #define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print. A value of 0 will save stats at end of print.
#endif #endif
// @section security // @section security
@@ -3368,7 +3380,7 @@
// //
// ReprapWorld Graphical LCD // ReprapWorld Graphical LCD
// https://reprapworld.com/?products_details&products_id/1218 // https://reprapworld.com/electronics/3d-printer-modules/autonomous-printing/graphical-lcd-screen-v1-0/
// //
// #define REPRAPWORLD_GRAPHICAL_LCD // #define REPRAPWORLD_GRAPHICAL_LCD
@@ -3623,6 +3635,7 @@
// #define ANYCUBIC_LCD_CHIRON // #define ANYCUBIC_LCD_CHIRON
#if EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON) #if EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
// #define ANYCUBIC_LCD_DEBUG // #define ANYCUBIC_LCD_DEBUG
// #define ANYCUBIC_LCD_GCODE_EXT // Add ".gcode" to menu entries for DGUS clone compatibility
#endif #endif
// //
@@ -3691,7 +3704,7 @@
// #define MKS_ROBIN_TFT_V1_1R // #define MKS_ROBIN_TFT_V1_1R
// //
// 480x320, 3.5", FSMC Stock Display from TronxXY // 480x320, 3.5", FSMC Stock Display from Tronxy
// //
// #define TFT_TRONXY_X5SA // #define TFT_TRONXY_X5SA
@@ -3758,6 +3771,10 @@
// #define TFT_COLOR_UI // #define TFT_COLOR_UI
// #define TFT_LVGL_UI // #define TFT_LVGL_UI
#if ENABLED(TFT_COLOR_UI)
// #define TFT_SHARED_SPI // SPI is shared between TFT display and other devices. Disable async data transfer
#endif
#if ENABLED(TFT_LVGL_UI) #if ENABLED(TFT_LVGL_UI)
// #define MKS_WIFI_MODULE // MKS WiFi module // #define MKS_WIFI_MODULE // MKS WiFi module
#endif #endif
@@ -3793,7 +3810,8 @@
#define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens #define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus #define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
// #define TOUCH_IDLE_SLEEP 300 // (s) Turn off the TFT backlight if set (5mn) // #define DISABLE_ENCODER // Disable the click encoder, if any
// #define TOUCH_IDLE_SLEEP_MINS 5 // (minutes) Display Sleep after a period of inactivity. Set with M255 S.
#define TOUCH_SCREEN_CALIBRATION #define TOUCH_SCREEN_CALIBRATION
@@ -3884,16 +3902,19 @@
* luminance values can be set from 0 to 255. * luminance values can be set from 0 to 255.
* For NeoPixel LED an overall brightness parameter is also available. * For NeoPixel LED an overall brightness parameter is also available.
* *
* *** CAUTION *** * === CAUTION ===
* LED Strips require a MOSFET Chip between PWM lines and LEDs, * LED Strips require a MOSFET Chip between PWM lines and LEDs,
* as the Arduino cannot handle the current the LEDs will require. * as the Arduino cannot handle the current the LEDs will require.
* Failure to follow this precaution can destroy your Arduino! * Failure to follow this precaution can destroy your Arduino!
*
* NOTE: A separate 5V power supply is required! The NeoPixel LED needs * NOTE: A separate 5V power supply is required! The NeoPixel LED needs
* more current than the Arduino 5V linear regulator can produce. * more current than the Arduino 5V linear regulator can produce.
* *** CAUTION ***
* *
* LED Type. Enable only one of the following two options. * Requires PWM frequency between 50 <> 100Hz (Check HAL or variant)
* Use FAST_PWM_FAN, if possible, to reduce fan noise.
*/ */
// LED Type. Enable only one of the following two options:
// #define RGB_LED // #define RGB_LED
// #define RGBW_LED // #define RGBW_LED
@@ -3902,6 +3923,10 @@
// #define RGB_LED_G_PIN 43 // #define RGB_LED_G_PIN 43
// #define RGB_LED_B_PIN 35 // #define RGB_LED_B_PIN 35
// #define RGB_LED_W_PIN -1 // #define RGB_LED_W_PIN -1
// #define RGB_STARTUP_TEST // For PWM pins, fade between all colors
#if ENABLED(RGB_STARTUP_TEST)
#define RGB_STARTUP_TEST_INNER_MS 10 // (ms) Reduce or increase fading speed
#endif
#endif #endif
// Support for Adafruit NeoPixel LED driver // Support for Adafruit NeoPixel LED driver
@@ -3923,6 +3948,7 @@
#define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip #define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip
#define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255) #define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255)
#define NEOPIXEL2_STARTUP_TEST // Cycle through colors at startup #define NEOPIXEL2_STARTUP_TEST // Cycle through colors at startup
#define NEOPIXEL_M150_DEFAULT -1 // Default strip for M150 without 'S'. Use -1 to set all by default.
#else #else
// #define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel // #define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel
#endif #endif

View File

@@ -30,7 +30,7 @@
* *
* Basic settings can be found in Configuration.h * Basic settings can be found in Configuration.h
*/ */
#define CONFIGURATION_ADV_H_VERSION 02010100 #define CONFIGURATION_ADV_H_VERSION 02010200
// @section develop // @section develop
@@ -48,7 +48,7 @@
* 3 = schema.json - The entire configuration schema. (13 = pattern groups) * 3 = schema.json - The entire configuration schema. (13 = pattern groups)
* 4 = schema.yml - The entire configuration schema. * 4 = schema.yml - The entire configuration schema.
*/ */
// #define CONFIG_EXPORT // :[1:'JSON', 2:'config.ini', 3:'schema.json', 4:'schema.yml'] // #define CONFIG_EXPORT 2 // :[1:'JSON', 2:'config.ini', 3:'schema.json', 4:'schema.yml']
#define KNUTWURST_MEGAS_ADV #define KNUTWURST_MEGAS_ADV
#define KNUTWURST_TMC_ADV #define KNUTWURST_TMC_ADV
@@ -178,6 +178,7 @@
// #define TEMP_SENSOR_FORCE_HW_SPI // Ignore SCK/MOSI/MISO pins; use CS and the default SPI bus. // #define TEMP_SENSOR_FORCE_HW_SPI // Ignore SCK/MOSI/MISO pins; use CS and the default SPI bus.
// #define MAX31865_SENSOR_WIRES_0 2 // (2-4) Number of wires for the probe connected to a MAX31865 board. // #define MAX31865_SENSOR_WIRES_0 2 // (2-4) Number of wires for the probe connected to a MAX31865 board.
// #define MAX31865_SENSOR_WIRES_1 2 // #define MAX31865_SENSOR_WIRES_1 2
// #define MAX31865_SENSOR_WIRES_2 2
// #define MAX31865_50HZ_FILTER // Use a 50Hz filter instead of the default 60Hz. // #define MAX31865_50HZ_FILTER // Use a 50Hz filter instead of the default 60Hz.
// #define MAX31865_USE_READ_ERROR_DETECTION // Treat value spikes (20°C delta in under 1s) as read errors. // #define MAX31865_USE_READ_ERROR_DETECTION // Treat value spikes (20°C delta in under 1s) as read errors.
@@ -188,6 +189,7 @@
// #define MAX31865_WIRE_OHMS_0 0.95f // For 2-wire, set the wire resistances for more accurate readings. // #define MAX31865_WIRE_OHMS_0 0.95f // For 2-wire, set the wire resistances for more accurate readings.
// #define MAX31865_WIRE_OHMS_1 0.0f // #define MAX31865_WIRE_OHMS_1 0.0f
// #define MAX31865_WIRE_OHMS_2 0.0f
/** /**
* Hephestos 2 24V heated bed upgrade kit. * Hephestos 2 24V heated bed upgrade kit.
@@ -507,18 +509,22 @@
// #define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 // #define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0
#endif #endif
// The number of milliseconds a hotend will preheat before starting to check /**
// the temperature. This value should NOT be set to the time it takes the * The number of milliseconds a hotend will preheat before starting to check
// hot end to reach the target temperature, but the time it takes to reach * the temperature. This value should NOT be set to the time it takes the
// the minimum temperature your thermistor can read. The lower the better/safer. * hot end to reach the target temperature, but the time it takes to reach
// This shouldn't need to be more than 30 seconds (30000) * the minimum temperature your thermistor can read. The lower the better/safer.
* This shouldn't need to be more than 30 seconds (30000)
*/
// #define MILLISECONDS_PREHEAT_TIME 0 // #define MILLISECONDS_PREHEAT_TIME 0
// @section extruder // @section extruder
// Extruder runout prevention. /**
// If the machine is idle and the temperature over MINTEMP * Extruder runout prevention.
// then extrude some filament every couple of SECONDS. * If the machine is idle and the temperature over MINTEMP
* then extrude some filament every couple of SECONDS.
*/
// #define EXTRUDER_RUNOUT_PREVENT // #define EXTRUDER_RUNOUT_PREVENT
#if ENABLED(EXTRUDER_RUNOUT_PREVENT) #if ENABLED(EXTRUDER_RUNOUT_PREVENT)
#define EXTRUDER_RUNOUT_MINTEMP 190 #define EXTRUDER_RUNOUT_MINTEMP 190
@@ -558,6 +564,7 @@
#define USE_CONTROLLER_FAN #define USE_CONTROLLER_FAN
#if ENABLED(USE_CONTROLLER_FAN) #if ENABLED(USE_CONTROLLER_FAN)
// #define CONTROLLER_FAN_PIN -1 // Set a custom pin for the controller fan // #define CONTROLLER_FAN_PIN -1 // Set a custom pin for the controller fan
// #define CONTROLLER_FAN2_PIN -1 // Set a custom pin for second controller fan
// #define CONTROLLER_FAN_USE_Z_ONLY // With this option only the Z axis is considered // #define CONTROLLER_FAN_USE_Z_ONLY // With this option only the Z axis is considered
// #define CONTROLLER_FAN_IGNORE_Z // Ignore Z stepper. Useful when stepper timeout is disabled. // #define CONTROLLER_FAN_IGNORE_Z // Ignore Z stepper. Useful when stepper timeout is disabled.
#define CONTROLLERFAN_SPEED_MIN 0 // (0-255) Minimum speed. (If set below this value the fan is turned off.) #define CONTROLLERFAN_SPEED_MIN 0 // (0-255) Minimum speed. (If set below this value the fan is turned off.)
@@ -574,10 +581,14 @@
#endif #endif
#endif #endif
// When first starting the main fan, run it at full speed for the /**
// given number of milliseconds. This gets the fan spinning reliably * Fan Kickstart
// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) * When part cooling or controller fans first start, run at a speed that
// #define FAN_KICKSTART_TIME 100 * gets it spinning reliably for a short time before setting the requested speed.
* (Does not work on Sanguinololu with FAN_SOFT_PWM.)
*/
// #define FAN_KICKSTART_TIME 100 // (ms)
// #define FAN_KICKSTART_POWER 180 // 64-255
// Some coolers may require a non-zero "off" state. // Some coolers may require a non-zero "off" state.
// #define FAN_OFF_PWM 1 // #define FAN_OFF_PWM 1
@@ -907,6 +918,7 @@
#if DISABLED(KNUTWURST_CHIRON) #if DISABLED(KNUTWURST_CHIRON)
#define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (linear=mm, rotational=°) Backoff from endstops after homing #define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (linear=mm, rotational=°) Backoff from endstops after homing
#endif #endif
// #define XY_COUNTERPART_BACKOFF_MM 0 // (mm) Backoff X after homing Y, and vice-versa
// #define QUICK_HOME // If G28 contains XY do a diagonal move first // #define QUICK_HOME // If G28 contains XY do a diagonal move first
// #define HOME_Y_BEFORE_X // If G28 contains XY home Y before X // #define HOME_Y_BEFORE_X // If G28 contains XY home Y before X
@@ -1358,7 +1370,7 @@
// //
// LCD Backlight Timeout // LCD Backlight Timeout
// //
// #define LCD_BACKLIGHT_TIMEOUT 30 // (s) Timeout before turning off the backlight // #define LCD_BACKLIGHT_TIMEOUT_MINS 1 // (minutes) Timeout before turning off the backlight
#if HAS_BED_PROBE && EITHER(HAS_MARLINUI_MENU, HAS_TFT_LVGL_UI) #if HAS_BED_PROBE && EITHER(HAS_MARLINUI_MENU, HAS_TFT_LVGL_UI)
// #define PROBE_OFFSET_WIZARD // Add a Probe Z Offset calibration option to the LCD menu // #define PROBE_OFFSET_WIZARD // Add a Probe Z Offset calibration option to the LCD menu
@@ -1435,9 +1447,6 @@
// On the Info Screen, display XY with one decimal place when possible // On the Info Screen, display XY with one decimal place when possible
// #define LCD_DECIMAL_SMALL_XY // #define LCD_DECIMAL_SMALL_XY
// Add an 'M73' G-code to set the current percentage
// #define LCD_SET_PROGRESS_MANUALLY
// Show the E position (filament used) during printing // Show the E position (filament used) during printing
// #define LCD_SHOW_E_TOTAL // #define LCD_SHOW_E_TOTAL
@@ -1467,21 +1476,29 @@
#endif #endif
#endif #endif
#endif // if EITHER(HAS_DISPLAY, DWIN_LCD_PROUI) #endif // HAS_DISPLAY || DWIN_LCD_PROUI
// LCD Print Progress options // Add 'M73' to set print job progress, overrides Marlin's built-in estimate
#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) // #define SET_PROGRESS_MANUALLY
#if CAN_SHOW_REMAINING_TIME #if ENABLED(SET_PROGRESS_MANUALLY)
// #define SHOW_REMAINING_TIME // Display estimated time to completion #define SET_PROGRESS_PERCENT // Add 'P' parameter to set percentage done
#if ENABLED(SHOW_REMAINING_TIME) #define SET_REMAINING_TIME // Add 'R' parameter to set remaining time
// #define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation // #define SET_INTERACTION_TIME // Add 'C' parameter to set time until next filament change or other user interaction
// #define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time // #define M73_REPORT // Report M73 values to host
#if BOTH(M73_REPORT, SDSUPPORT)
#define M73_REPORT_SD_ONLY // Report only when printing from SD
#endif #endif
#endif #endif
#if EITHER(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI) // LCD Print Progress options. Multiple times may be displayed in turn.
// #define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits #if HAS_DISPLAY && EITHER(SDSUPPORT, SET_PROGRESS_MANUALLY)
#define SHOW_PROGRESS_PERCENT // Show print progress percentage (doesn't affect progress bar)
#define SHOW_ELAPSED_TIME // Display elapsed printing time (prefix 'E')
// #define SHOW_REMAINING_TIME // Display estimated time to completion (prefix 'R')
#if ENABLED(SET_INTERACTION_TIME)
#define SHOW_INTERACTION_TIME // Display time until next user interaction ('C' = filament change)
#endif #endif
// #define PRINT_PROGRESS_SHOW_DECIMALS // Show/report progress with decimal digits, not all UIs support this
#if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) #if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
// #define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing // #define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing
@@ -1615,6 +1632,7 @@
// #define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 <dosname>' and list long filenames with 'M20 L' // #define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 <dosname>' and list long filenames with 'M20 L'
// #define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol // #define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol
// #define M20_TIMESTAMP_SUPPORT // Include timestamps by adding the 'T' flag to M20 commands
// #define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu // #define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu
@@ -1776,7 +1794,7 @@
* Adds the menu item Configuration > LCD Timeout (m) to set a wait period * Adds the menu item Configuration > LCD Timeout (m) to set a wait period
* from 0 (disabled) to 99 minutes. * from 0 (disabled) to 99 minutes.
*/ */
// #define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen // #define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen. Set with M255 S.
/** /**
* ST7920-based LCDs can emulate a 16 x 4 character display using * ST7920-based LCDs can emulate a 16 x 4 character display using
@@ -1830,14 +1848,8 @@
#endif // HAS_MARLINUI_U8GLIB #endif // HAS_MARLINUI_U8GLIB
#if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI #if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI
// Show SD percentage next to the progress bar #define MENU_HOLLOW_FRAME // Enable to save many cycles by drawing a hollow frame on Menu Screens
// #define SHOW_SD_PERCENT // #define OVERLAY_GFX_REVERSE // Swap the CW/CCW indicators in the graphics overlay
// Enable to save many cycles by drawing a hollow frame on Menu Screens
#define MENU_HOLLOW_FRAME
// Swap the CW/CCW indicators in the graphics overlay
// #define OVERLAY_GFX_REVERSE
#endif #endif
// //
@@ -2098,11 +2110,16 @@
*/ */
#define LIN_ADVANCE #define LIN_ADVANCE
#if ENABLED(LIN_ADVANCE) #if ENABLED(LIN_ADVANCE)
// #define EXTRA_LIN_ADVANCE_K // Enable for second linear advance constants #if ENABLED(DISTINCT_E_FACTORS)
#define LIN_ADVANCE_K 0.0 // Unit: mm compression per 1mm/s extruder speed #define ADVANCE_K { 0.0 } // (mm) Compression length per 1mm/s extruder speed, per extruder
// #define LA_DEBUG // If enabled, this will generate debug information output over USB. #else
#define EXPERIMENTAL_SCURVE // Enable this option to permit S-Curve Acceleration #define ADVANCE_K 0.0 // (mm) Compression length applying to all extruders
#endif
// #define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with M900 L.
// #define LA_DEBUG // Print debug information to serial during operation. Disable for production use.
#define EXPERIMENTAL_SCURVE // Allow S-Curve Acceleration to be used with LA.
// #define ALLOW_LOW_EJERK // Allow a DEFAULT_EJERK value of <10. Recommended for direct drive hotends. // #define ALLOW_LOW_EJERK // Allow a DEFAULT_EJERK value of <10. Recommended for direct drive hotends.
// #define EXPERIMENTAL_I2S_LA // Allow I2S_STEPPER_STREAM to be used with LA. Performance degrades as the LA step rate reaches ~20kHz.
#endif #endif
// @section leveling // @section leveling
@@ -2580,7 +2597,7 @@
// Longer prime to clean out a SINGLENOZZLE // Longer prime to clean out a SINGLENOZZLE
#define TOOLCHANGE_FS_EXTRA_PRIME 0 // (mm) Extra priming length #define TOOLCHANGE_FS_EXTRA_PRIME 0 // (mm) Extra priming length
#define TOOLCHANGE_FS_PRIME_SPEED (4.6 * 60) // (mm/min) Extra priming feedrate #define TOOLCHANGE_FS_PRIME_SPEED (4.6 * 60) // (mm/min) Extra priming feedrate
#define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm) Retract before cooling for less stringing, better wipe, etc. #define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm) Cutting retraction out of park, for less stringing, better wipe, etc. Adjust with LCD or M217 G.
// Cool after prime to reduce stringing // Cool after prime to reduce stringing
#define TOOLCHANGE_FS_FAN -1 // Fan index or -1 to skip #define TOOLCHANGE_FS_FAN -1 // Fan index or -1 to skip
@@ -4209,7 +4226,7 @@
/** /**
* WiFi Support (Espressif ESP32 WiFi) * WiFi Support (Espressif ESP32 WiFi)
*/ */
// #define WIFISUPPORT // Marlin embedded WiFi managenent // #define WIFISUPPORT // Marlin embedded WiFi management
// #define ESP3D_WIFISUPPORT // ESP3D Library WiFi management (https://github.com/luc-github/ESP3DLib) // #define ESP3D_WIFISUPPORT // ESP3D Library WiFi management (https://github.com/luc-github/ESP3DLib)
#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT) #if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT)

View File

@@ -307,20 +307,22 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1154)
else ifeq ($(HARDWARE_MOTHERBOARD),1155) else ifeq ($(HARDWARE_MOTHERBOARD),1155)
# Tenlog D3 Hero IDEX printer # Tenlog D3 Hero IDEX printer
else ifeq ($(HARDWARE_MOTHERBOARD),1156) else ifeq ($(HARDWARE_MOTHERBOARD),1156)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed) # Tenlog D3,5,6 Pro IDEX printers
else ifeq ($(HARDWARE_MOTHERBOARD),1157) else ifeq ($(HARDWARE_MOTHERBOARD),1157)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed) # Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1158) else ifeq ($(HARDWARE_MOTHERBOARD),1158)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed) # Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1159) else ifeq ($(HARDWARE_MOTHERBOARD),1159)
# Longer LK1 PRO / Alfawise U20 Pro (PRO version) # Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1160) else ifeq ($(HARDWARE_MOTHERBOARD),1160)
# Longer LKx PRO / Alfawise Uxx Pro (PRO version) # Longer LK1 PRO / Alfawise U20 Pro (PRO version)
else ifeq ($(HARDWARE_MOTHERBOARD),1161) else ifeq ($(HARDWARE_MOTHERBOARD),1161)
# Zonestar zrib V5.3 (Chinese RAMPS replica) # Longer LKx PRO / Alfawise Uxx Pro (PRO version)
else ifeq ($(HARDWARE_MOTHERBOARD),1162) else ifeq ($(HARDWARE_MOTHERBOARD),1162)
# Pxmalion Core I3 # Zonestar zrib V5.3 (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1163) else ifeq ($(HARDWARE_MOTHERBOARD),1163)
# Pxmalion Core I3
else ifeq ($(HARDWARE_MOTHERBOARD),1164)
# #
# RAMBo and derivatives # RAMBo and derivatives

View File

@@ -28,7 +28,7 @@
/** /**
* Marlin release version identifier * Marlin release version identifier
*/ */
//#define SHORT_BUILD_VERSION "2.1.1" //#define SHORT_BUILD_VERSION "2.1.2"
/** /**
* Verbose version identifier which should contain a reference to the location * Verbose version identifier which should contain a reference to the location

View File

@@ -32,6 +32,7 @@
#include <HardwareSerial.h> #include <HardwareSerial.h>
#else #else
#include "MarlinSerial.h" #include "MarlinSerial.h"
#define BOARD_NO_NATIVE_USB
#endif #endif
#include <stdint.h> #include <stdint.h>
@@ -106,36 +107,36 @@ typedef Servo hal_servo_t;
#define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0) #define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0)
#else #else
#if !WITHIN(SERIAL_PORT, -1, 3) #if !WITHIN(SERIAL_PORT, 0, 3)
#error "SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." #error "SERIAL_PORT must be from 0 to 3."
#endif #endif
#define MYSERIAL1 customizedSerial1 #define MYSERIAL1 customizedSerial1
#ifdef SERIAL_PORT_2 #ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3) #if !WITHIN(SERIAL_PORT_2, 0, 3)
#error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial." #error "SERIAL_PORT_2 must be from 0 to 3."
#endif #endif
#define MYSERIAL2 customizedSerial2 #define MYSERIAL2 customizedSerial2
#endif #endif
#ifdef SERIAL_PORT_3 #ifdef SERIAL_PORT_3
#if !WITHIN(SERIAL_PORT_3, -1, 3) #if !WITHIN(SERIAL_PORT_3, 0, 3)
#error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial." #error "SERIAL_PORT_3 must be from 0 to 3."
#endif #endif
#define MYSERIAL3 customizedSerial3 #define MYSERIAL3 customizedSerial3
#endif #endif
#endif #endif
#ifdef MMU2_SERIAL_PORT #ifdef MMU2_SERIAL_PORT
#if !WITHIN(MMU2_SERIAL_PORT, -1, 3) #if !WITHIN(MMU2_SERIAL_PORT, 0, 3)
#error "MMU2_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." #error "MMU2_SERIAL_PORT must be from 0 to 3"
#endif #endif
#define MMU2_SERIAL mmuSerial #define MMU2_SERIAL mmuSerial
#endif #endif
#ifdef LCD_SERIAL_PORT #ifdef LCD_SERIAL_PORT
#if !WITHIN(LCD_SERIAL_PORT, -1, 3) #if !WITHIN(LCD_SERIAL_PORT, 0, 3)
#error "LCD_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." #error "LCD_SERIAL_PORT must be from 0 to 3."
#endif #endif
#define LCD_SERIAL lcdSerial #define LCD_SERIAL lcdSerial
#if HAS_DGUS_LCD #if HAS_DGUS_LCD

View File

@@ -146,10 +146,10 @@ void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
LIMIT(res_pc_temp, 1U, maxtop); LIMIT(res_pc_temp, 1U, maxtop);
// Calculate frequencies of test prescaler and resolution values // Calculate frequencies of test prescaler and resolution values
const uint32_t f_diff = _MAX(f, f_desired) - _MIN(f, f_desired), const uint16_t f_fast_temp = (F_CPU) / (p * (1 + res_fast_temp)),
f_fast_temp = (F_CPU) / (p * (1 + res_fast_temp)), f_pc_temp = (F_CPU) / (2 * p * res_pc_temp);
const int f_diff = _MAX(f, f_desired) - _MIN(f, f_desired),
f_fast_diff = _MAX(f_fast_temp, f_desired) - _MIN(f_fast_temp, f_desired), f_fast_diff = _MAX(f_fast_temp, f_desired) - _MIN(f_fast_temp, f_desired),
f_pc_temp = (F_CPU) / (2 * p * res_pc_temp),
f_pc_diff = _MAX(f_pc_temp, f_desired) - _MIN(f_pc_temp, f_desired); f_pc_diff = _MAX(f_pc_temp, f_desired) - _MIN(f_pc_temp, f_desired);
if (f_fast_diff < f_diff && f_fast_diff <= f_pc_diff) { // FAST values are closest to desired f if (f_fast_diff < f_diff && f_fast_diff <= f_pc_diff) { // FAST values are closest to desired f

View File

@@ -293,11 +293,11 @@ enum ClockSource2 : uint8_t {
#if HAS_MOTOR_CURRENT_PWM #if HAS_MOTOR_CURRENT_PWM
#if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
#define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E || P == MOTOR_CURRENT_PWM_Z || P == MOTOR_CURRENT_PWM_XY) #define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E || P == MOTOR_CURRENT_PWM_E0 || P == MOTOR_CURRENT_PWM_E1 || P == MOTOR_CURRENT_PWM_Z || P == MOTOR_CURRENT_PWM_XY)
#elif PIN_EXISTS(MOTOR_CURRENT_PWM_Z) #elif PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
#define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E || P == MOTOR_CURRENT_PWM_Z) #define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E || P == MOTOR_CURRENT_PWM_E0 || P == MOTOR_CURRENT_PWM_E1 || P == MOTOR_CURRENT_PWM_Z)
#else #else
#define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E) #define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E || P == MOTOR_CURRENT_PWM_E0 || P == MOTOR_CURRENT_PWM_E1)
#endif #endif
#else #else
#define PWM_CHK_MOTOR_CURRENT(P) false #define PWM_CHK_MOTOR_CURRENT(P) false

View File

@@ -37,22 +37,24 @@
|| X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \ || X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \
|| BTN_EN1 == N || BTN_EN2 == N \ || BTN_EN1 == N || BTN_EN2 == N \
) )
#if CONF_SERIAL_IS(0) #if SERIAL_IN_USE(0)
// D0-D1. No known conflicts. // D0-D1. No known conflicts.
#endif #endif
#if SERIAL_IN_USE(1)
#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__) #if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__)
#if CONF_SERIAL_IS(1) && (CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19)) #if CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19)
#error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board." #error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board."
#endif #endif
#else #else
#if CONF_SERIAL_IS(1) && (CHECK_SERIAL_PIN(10) || CHECK_SERIAL_PIN(11)) #if CHECK_SERIAL_PIN(10) || CHECK_SERIAL_PIN(11)
#error "Serial Port 1 pin D10 and/or D11 conflicts with another pin on the board." #error "Serial Port 1 pin D10 and/or D11 conflicts with another pin on the board."
#endif #endif
#endif #endif
#if CONF_SERIAL_IS(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17)) #endif
#if SERIAL_IN_USE(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17))
#error "Serial Port 2 pin D16 and/or D17 conflicts with another pin on the board." #error "Serial Port 2 pin D16 and/or D17 conflicts with another pin on the board."
#endif #endif
#if CONF_SERIAL_IS(3) && (CHECK_SERIAL_PIN(14) || CHECK_SERIAL_PIN(15)) #if SERIAL_IN_USE(3) && (CHECK_SERIAL_PIN(14) || CHECK_SERIAL_PIN(15))
#error "Serial Port 3 pin D14 and/or D15 conflicts with another pin on the board." #error "Serial Port 3 pin D14 and/or D15 conflicts with another pin on the board."
#endif #endif
#undef CHECK_SERIAL_PIN #undef CHECK_SERIAL_PIN

View File

@@ -210,7 +210,7 @@ public:
static void adc_init() {} static void adc_init() {}
// Called by Temperature::init for each sensor at startup // Called by Temperature::init for each sensor at startup
static void adc_enable(const uint8_t ch) {} static void adc_enable(const uint8_t /*ch*/) {}
// Begin ADC sampling on the given channel. Called from Temperature::isr! // Begin ADC sampling on the given channel. Called from Temperature::isr!
static void adc_start(const uint8_t ch) { adc_result = analogRead(ch); } static void adc_start(const uint8_t ch) { adc_result = analogRead(ch); }

View File

@@ -247,12 +247,12 @@
b <<= 1; // little setup time b <<= 1; // little setup time
WRITE(SD_SCK_PIN, HIGH); WRITE(SD_SCK_PIN, HIGH);
DELAY_NS(spiDelayNS); DELAY_NS_VAR(spiDelayNS);
b |= (READ(SD_MISO_PIN) != 0); b |= (READ(SD_MISO_PIN) != 0);
WRITE(SD_SCK_PIN, LOW); WRITE(SD_SCK_PIN, LOW);
DELAY_NS(spiDelayNS); DELAY_NS_VAR(spiDelayNS);
} while (--bits); } while (--bits);
return b; return b;
} }

View File

@@ -41,7 +41,7 @@
practice, we need alignment to 256 bytes to make this work in all practice, we need alignment to 256 bytes to make this work in all
cases */ cases */
__attribute__ ((aligned(256))) __attribute__ ((aligned(256)))
static DeviceVectors ram_tab = { nullptr }; static DeviceVectors ram_tab[61] = { nullptr };
/** /**
* This function checks if the exception/interrupt table is already in SRAM or not. * This function checks if the exception/interrupt table is already in SRAM or not.

View File

@@ -36,15 +36,15 @@
|| X_DIR_PIN == N || Y_DIR_PIN == N || Z_DIR_PIN == N \ || X_DIR_PIN == N || Y_DIR_PIN == N || Z_DIR_PIN == N \
|| X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \ || X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \
) )
#if CONF_SERIAL_IS(0) // D0-D1. No known conflicts. #if SERIAL_IN_USE(0) // D0-D1. No known conflicts.
#endif #endif
#if CONF_SERIAL_IS(1) && (CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19)) #if SERIAL_IN_USE(1) && (CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19))
#error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board." #error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board."
#endif #endif
#if CONF_SERIAL_IS(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17)) #if SERIAL_IN_USE(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17))
#error "Serial Port 2 pin D16 and/or D17 conflicts with another pin on the board." #error "Serial Port 2 pin D16 and/or D17 conflicts with another pin on the board."
#endif #endif
#if CONF_SERIAL_IS(3) && (CHECK_SERIAL_PIN(14) || CHECK_SERIAL_PIN(15)) #if SERIAL_IN_USE(3) && (CHECK_SERIAL_PIN(14) || CHECK_SERIAL_PIN(15))
#error "Serial Port 3 pin D14 and/or D15 conflicts with another pin on the board." #error "Serial Port 3 pin D14 and/or D15 conflicts with another pin on the board."
#endif #endif
#undef CHECK_SERIAL_PIN #undef CHECK_SERIAL_PIN

View File

@@ -70,7 +70,7 @@
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) #define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
#define GET_ARRAY_PIN(p) pin_array[p].pin #define GET_ARRAY_PIN(p) pin_array[p].pin
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital #define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL ? 1 : 0) #define VALID_PIN(pin) (pin >= 0 && pin < int8_t(NUMBER_PINS_TOTAL))
#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0)) #define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0))
#define IS_ANALOG(P) WITHIN(P, char(analogInputToDigitalPin(0)), char(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1))) #define IS_ANALOG(P) WITHIN(P, char(analogInputToDigitalPin(0)), char(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1)))
#define pwm_status(pin) (((g_pinStatus[pin] & 0xF) == PIN_STATUS_PWM) && \ #define pwm_status(pin) (((g_pinStatus[pin] & 0xF) == PIN_STATUS_PWM) && \

View File

@@ -62,7 +62,7 @@ void usb_task_idle(void) {
// Attend SD card access from the USB MSD -- Prioritize access to improve speed // Attend SD card access from the USB MSD -- Prioritize access to improve speed
int delay = 2; int delay = 2;
while (main_b_msc_enable && --delay > 0) { while (main_b_msc_enable && --delay > 0) {
if (udi_msc_process_trans()) delay = 10000; if (udi_msc_process_trans()) delay = 20;
// Reset the watchdog, just to be sure // Reset the watchdog, just to be sure
REG_WDT_CR = WDT_CR_WDRSTT | WDT_CR_KEY(0xA5); REG_WDT_CR = WDT_CR_WDRSTT | WDT_CR_KEY(0xA5);

View File

@@ -139,22 +139,40 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg) {
} }
void stepperTask(void *parameter) { void stepperTask(void *parameter) {
uint32_t remaining = 0; uint32_t nextMainISR = 0;
#if ENABLED(LIN_ADVANCE)
uint32_t nextAdvanceISR = Stepper::LA_ADV_NEVER;
#endif
while (1) { for (;;) {
xQueueReceive(dma.queue, &dma.current, portMAX_DELAY); xQueueReceive(dma.queue, &dma.current, portMAX_DELAY);
dma.rw_pos = 0; dma.rw_pos = 0;
while (dma.rw_pos < DMA_SAMPLE_COUNT) { while (dma.rw_pos < DMA_SAMPLE_COUNT) {
// Fill with the port data post pulse_phase until the next step // Fill with the port data post pulse_phase until the next step
if (remaining) { if (nextMainISR && TERN1(LIN_ADVANCE, nextAdvanceISR))
i2s_push_sample(); i2s_push_sample();
remaining--;
// i2s_push_sample() is also called from Stepper::pulse_phase_isr() and Stepper::advance_isr()
// in a rare case where both are called, we need to double decrement the counters
const uint8_t push_count = 1 + (!nextMainISR && TERN0(LIN_ADVANCE, !nextAdvanceISR));
#if ENABLED(LIN_ADVANCE)
if (!nextAdvanceISR) {
Stepper::advance_isr();
nextAdvanceISR = Stepper::la_interval;
} }
else { else if (nextAdvanceISR == Stepper::LA_ADV_NEVER)
nextAdvanceISR = Stepper::la_interval;
#endif
if (!nextMainISR) {
Stepper::pulse_phase_isr(); Stepper::pulse_phase_isr();
remaining = Stepper::block_phase_isr(); nextMainISR = Stepper::block_phase_isr();
} }
nextMainISR -= push_count;
TERN_(LIN_ADVANCE, nextAdvanceISR -= push_count);
} }
} }
} }

View File

@@ -45,10 +45,14 @@
#error "FAST_PWM_FAN is not available on TinyBee." #error "FAST_PWM_FAN is not available on TinyBee."
#endif #endif
#if BOTH(I2S_STEPPER_STREAM, BABYSTEPPING) && DISABLED(INTEGRATED_BABYSTEPPING)
#error "BABYSTEPPING on I2S stream requires INTEGRATED_BABYSTEPPING."
#endif
#if USING_PULLDOWNS #if USING_PULLDOWNS
#error "PULLDOWN pin mode is not available on ESP32 boards." #error "PULLDOWN pin mode is not available on ESP32 boards."
#endif #endif
#if BOTH(I2S_STEPPER_STREAM, LIN_ADVANCE) #if BOTH(I2S_STEPPER_STREAM, LIN_ADVANCE) && DISABLED(EXPERIMENTAL_I2S_LA)
#error "I2S stream is currently incompatible with LIN_ADVANCE." #error "I2S stream is currently incompatible with LIN_ADVANCE."
#endif #endif

View File

@@ -32,6 +32,13 @@
#include "HAL.h" #include "HAL.h"
#include "SPI.h" #include "SPI.h"
#if ENABLED(SDSUPPORT)
#include "../../sd/cardreader.h"
#if ENABLED(ESP3D_WIFISUPPORT)
#include "sd_ESP32.h"
#endif
#endif
static SPISettings spiConfig; static SPISettings spiConfig;
@@ -45,6 +52,11 @@ static SPISettings spiConfig;
uint8_t u8g_eps_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { uint8_t u8g_eps_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT
#if ENABLED(PAUSE_LCD_FOR_BUSY_SD)
if (card.flag.saving || card.flag.logging || TERN0(ESP3D_WIFISUPPORT, sd_busy_lock == true)) return 0;
#endif
if (msgInitCount) { if (msgInitCount) {
if (msg == U8G_COM_MSG_INIT) msgInitCount--; if (msg == U8G_COM_MSG_INIT) msgInitCount--;
if (msgInitCount) return -1; if (msgInitCount) return -1;

View File

@@ -318,8 +318,16 @@ void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
// Enable DMA // Enable DMA
GPDMA_ChannelCmd(0, ENABLE); GPDMA_ChannelCmd(0, ENABLE);
/*
* Observed behaviour on normal data transfer completion (SKR 1.3 board / LPC1768 MCU)
* GPDMA_STAT_INTTC flag is SET
* GPDMA_STAT_INTERR flag is NOT SET
* GPDMA_STAT_RAWINTTC flag is NOT SET
* GPDMA_STAT_RAWINTERR flag is SET
*/
// Wait for data transfer // Wait for data transfer
while (!GPDMA_IntGetStatus(GPDMA_STAT_RAWINTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_RAWINTERR, 0)) { } while (!GPDMA_IntGetStatus(GPDMA_STAT_INTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0)) {}
// Clear err and int // Clear err and int
GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0); GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
@@ -333,6 +341,43 @@ void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, DISABLE); SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, DISABLE);
} }
void SPIClass::dmaSendAsync(void *buf, uint16_t length, bool minc) {
//TODO: LPC dma can only write 0xFFF bytes at once.
GPDMA_Channel_CFG_Type GPDMACfg;
/* Configure GPDMA channel 0 -------------------------------------------------------------*/
/* DMA Channel 0 */
GPDMACfg.ChannelNum = 0;
// Source memory
GPDMACfg.SrcMemAddr = (uint32_t)buf;
// Destination memory - Not used
GPDMACfg.DstMemAddr = 0;
// Transfer size
GPDMACfg.TransferSize = length;
// Transfer width
GPDMACfg.TransferWidth = (_currentSetting->dataSize == DATA_SIZE_16BIT) ? GPDMA_WIDTH_HALFWORD : GPDMA_WIDTH_BYTE;
// Transfer type
GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2P;
// Source connection - unused
GPDMACfg.SrcConn = 0;
// Destination connection
GPDMACfg.DstConn = (_currentSetting->spi_d == LPC_SSP0) ? GPDMA_CONN_SSP0_Tx : GPDMA_CONN_SSP1_Tx;
GPDMACfg.DMALLI = 0;
// Enable dma on SPI
SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE);
// Only increase memory if minc is true
GPDMACfg.MemoryIncrease = (minc ? GPDMA_DMACCxControl_SI : 0);
// Setup channel with given parameter
GPDMA_Setup(&GPDMACfg);
// Enable DMA
GPDMA_ChannelCmd(0, ENABLE);
}
uint16_t SPIClass::read() { uint16_t SPIClass::read() {
return SSP_ReceiveData(_currentSetting->spi_d); return SSP_ReceiveData(_currentSetting->spi_d);
} }

View File

@@ -29,6 +29,6 @@
// LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785) // LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785)
// TODO: Which other boards are incompatible? // TODO: Which other boards are incompatible?
#if defined(MCU_LPC1768) && PRINTCOUNTER_SAVE_INTERVAL > 0 #if defined(MCU_LPC1768) && ENABLED(FLASH_EEPROM_EMULATION) && PRINTCOUNTER_SAVE_INTERVAL > 0
#define PRINTCOUNTER_SYNC 1 #define PRINTCOUNTER_SYNC 1
#endif #endif

View File

@@ -155,6 +155,7 @@ public:
void read(uint8_t *buf, uint32_t len); void read(uint8_t *buf, uint32_t len);
void dmaSend(void *buf, uint16_t length, bool minc); void dmaSend(void *buf, uint16_t length, bool minc);
void dmaSendAsync(void *buf, uint16_t length, bool minc);
/** /**
* @brief Sets the number of the SPI peripheral to be used by * @brief Sets the number of the SPI peripheral to be used by

View File

@@ -26,7 +26,7 @@
#include "tft_spi.h" #include "tft_spi.h"
SPIClass TFT_SPI::SPIx(1); SPIClass TFT_SPI::SPIx(TFT_SPI_DEVICE);
void TFT_SPI::Init() { void TFT_SPI::Init() {
#if PIN_EXISTS(TFT_RESET) #if PIN_EXISTS(TFT_RESET)
@@ -38,40 +38,10 @@ void TFT_SPI::Init() {
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH); OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
#endif #endif
SET_OUTPUT(TFT_DC_PIN); OUT_WRITE(TFT_DC_PIN, HIGH);
SET_OUTPUT(TFT_CS_PIN); OUT_WRITE(TFT_CS_PIN, HIGH);
WRITE(TFT_DC_PIN, HIGH);
WRITE(TFT_CS_PIN, HIGH);
/** SPIx.setModule(TFT_SPI_DEVICE);
* STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
* STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1
* so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
*/
#if 0
#if SPI_DEVICE == 1
#define SPI_CLOCK_MAX SPI_CLOCK_DIV4
#else
#define SPI_CLOCK_MAX SPI_CLOCK_DIV2
#endif
uint8_t clock;
uint8_t spiRate = SPI_FULL_SPEED;
switch (spiRate) {
case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX ; break;
case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4 ; break;
case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8 ; break;
case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break;
case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break;
case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
default: clock = SPI_CLOCK_DIV2; // Default from the SPI library
}
#endif
#if TFT_MISO_PIN == BOARD_SPI1_MISO_PIN
SPIx.setModule(1);
#elif TFT_MISO_PIN == BOARD_SPI2_MISO_PIN
SPIx.setModule(2);
#endif
SPIx.setClock(SPI_CLOCK_MAX_TFT); SPIx.setClock(SPI_CLOCK_MAX_TFT);
SPIx.setBitOrder(MSBFIRST); SPIx.setBitOrder(MSBFIRST);
SPIx.setDataMode(SPI_MODE0); SPIx.setDataMode(SPI_MODE0);
@@ -114,17 +84,62 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
return data >> 7; return data >> 7;
} }
bool TFT_SPI::isBusy() { return false; } bool TFT_SPI::isBusy() {
#define __IS_DMA_CONFIGURED(__HANDLE__) ((__HANDLE__)->DMACCSrcAddr != 0)
void TFT_SPI::Abort() { DataTransferEnd(); } // DMA Channel 0 is hardcoded in dmaSendAsync() and dmaSend()
if (!__IS_DMA_CONFIGURED(LPC_GPDMACH0)) return false;
void TFT_SPI::Transmit(uint16_t Data) { SPIx.transfer(Data); } if (GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0)) {
// You should not be here - DMA transfer error flag is set
// Abort DMA transfer and release SPI
}
else {
// Check if DMA transfer completed flag is set
if (!GPDMA_IntGetStatus(GPDMA_STAT_INTTC, 0)) return true;
// Check if SPI TX butter is empty and SPI is idle
if ((SSP_GetStatus(LPC_SSPx, SSP_STAT_TXFIFO_EMPTY) == RESET) || (SSP_GetStatus(LPC_SSPx, SSP_STAT_BUSY) == SET)) return true;
}
Abort();
return false;
}
void TFT_SPI::Abort() {
// DMA Channel 0 is hardcoded in dmaSendAsync() and dmaSend()
// Disable DMA
GPDMA_ChannelCmd(0, DISABLE);
// Clear ERR and TC
GPDMA_ClearIntPending(GPDMA_STATCLR_INTTC, 0);
GPDMA_ClearIntPending(GPDMA_STATCLR_INTERR, 0);
// Disable DMA on SPI
SSP_DMACmd(LPC_SSPx, SSP_DMA_TX, DISABLE);
// Deconfigure DMA Channel 0
LPC_GPDMACH0->DMACCControl = 0U;
LPC_GPDMACH0->DMACCConfig = 0U;
LPC_GPDMACH0->DMACCSrcAddr = 0U;
LPC_GPDMACH0->DMACCDestAddr = 0U;
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DataTransferBegin(DATASIZE_16BIT);
WRITE(TFT_DC_PIN, HIGH);
SPIx.dmaSend(Data, Count, MemoryIncrease);
DataTransferEnd(); DataTransferEnd();
} }
void TFT_SPI::Transmit(uint16_t Data) { SPIx.transfer(Data); }
void TFT_SPI::Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DataTransferBegin(DATASIZE_16BIT);
SPIx.dmaSend(Data, Count, MemoryIncrease);
Abort();
}
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DataTransferBegin(DATASIZE_16BIT);
SPIx.dmaSendAsync(Data, Count, MemoryIncrease);
TERN_(TFT_SHARED_SPI, while (isBusy()));
}
#endif // HAS_SPI_TFT #endif // HAS_SPI_TFT

View File

@@ -27,6 +27,18 @@
#include <lpc17xx_ssp.h> #include <lpc17xx_ssp.h>
// #include <lpc17xx_gpdma.h> // #include <lpc17xx_gpdma.h>
#define IS_SPI(N) (BOARD_NR_SPI >= N && (TFT_SCK_PIN == BOARD_SPI##N##_SCK_PIN) && (TFT_MOSI_PIN == BOARD_SPI##N##_MOSI_PIN) && (TFT_MISO_PIN == BOARD_SPI##N##_MISO_PIN))
#if IS_SPI(1)
#define TFT_SPI_DEVICE 1
#define LPC_SSPx LPC_SSP0
#elif IS_SPI(2)
#define TFT_SPI_DEVICE 2
#define LPC_SSPx LPC_SSP1
#else
#error "Invalid TFT SPI configuration."
#endif
#undef IS_SPI
#ifndef LCD_READ_ID #ifndef LCD_READ_ID
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif #endif
@@ -37,6 +49,7 @@
#define DATASIZE_8BIT SSP_DATABIT_8 #define DATASIZE_8BIT SSP_DATABIT_8
#define DATASIZE_16BIT SSP_DATABIT_16 #define DATASIZE_16BIT SSP_DATABIT_16
#define TFT_IO_DRIVER TFT_SPI #define TFT_IO_DRIVER TFT_SPI
#define DMA_MAX_SIZE 0xFFF
#define DMA_MINC_ENABLE 1 #define DMA_MINC_ENABLE 1
#define DMA_MINC_DISABLE 0 #define DMA_MINC_DISABLE 0
@@ -45,6 +58,7 @@ class TFT_SPI {
private: private:
static uint32_t ReadID(uint16_t Reg); static uint32_t ReadID(uint16_t Reg);
static void Transmit(uint16_t Data); static void Transmit(uint16_t Data);
static void Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public: public:
@@ -56,22 +70,20 @@ public:
static void Abort(); static void Abort();
static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT); static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT);
static void DataTransferEnd() { OUT_WRITE(TFT_CS_PIN, HIGH); SPIx.end(); }; static void DataTransferEnd() { WRITE(TFT_CS_PIN, HIGH); SSP_Cmd(LPC_SSPx, DISABLE); };
static void DataTransferAbort(); static void DataTransferAbort();
static void WriteData(uint16_t Data) { Transmit(Data); } static void WriteData(uint16_t Data) { Transmit(Data); }
static void WriteReg(uint16_t Reg) { OUT_WRITE(TFT_A0_PIN, LOW); Transmit(Reg); OUT_WRITE(TFT_A0_PIN, HIGH); } static void WriteReg(uint16_t Reg) { WRITE(TFT_DC_PIN, LOW); Transmit(Reg); WRITE(TFT_DC_PIN, HIGH); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); } static void WriteSequence_DMA(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); }
// static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); } static void WriteMultiple_DMA(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { Transmit(DMA_MINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) { static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
//LPC dma can only write 0xFFF bytes at once.
#define MAX_DMA_SIZE (0xFFF - 1)
while (Count > 0) { while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > MAX_DMA_SIZE ? MAX_DMA_SIZE : Count); Transmit(DMA_MINC_DISABLE, &Color, Count > DMA_MAX_SIZE ? DMA_MAX_SIZE : Count);
Count = Count > MAX_DMA_SIZE ? Count - MAX_DMA_SIZE : 0; Count = Count > DMA_MAX_SIZE ? Count - DMA_MAX_SIZE : 0;
} }
#undef MAX_DMA_SIZE
} }
}; };

View File

@@ -44,9 +44,11 @@ uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; }
#endif #endif
void XPT2046::Init() { void XPT2046::Init() {
#if DISABLED(TOUCH_BUTTONS_HW_SPI)
SET_INPUT(TOUCH_MISO_PIN); SET_INPUT(TOUCH_MISO_PIN);
SET_OUTPUT(TOUCH_MOSI_PIN); SET_OUTPUT(TOUCH_MOSI_PIN);
SET_OUTPUT(TOUCH_SCK_PIN); SET_OUTPUT(TOUCH_SCK_PIN);
#endif
OUT_WRITE(TOUCH_CS_PIN, HIGH); OUT_WRITE(TOUCH_CS_PIN, HIGH);
#if PIN_EXISTS(TOUCH_INT) #if PIN_EXISTS(TOUCH_INT)

View File

@@ -73,7 +73,7 @@ if pioutil.is_pio_build():
# #
import getpass import getpass
user = getpass.getuser() user = getpass.getuser()
mpath = Path('media', user) mpath = Path('/media', user)
drives = [ x for x in mpath.iterdir() if x.is_dir() ] drives = [ x for x in mpath.iterdir() if x.is_dir() ]
if target_drive in drives: # If target drive is found, use it. if target_drive in drives: # If target drive is found, use it.
target_drive_found = True target_drive_found = True
@@ -82,11 +82,11 @@ if pioutil.is_pio_build():
for drive in drives: for drive in drives:
try: try:
fpath = mpath / drive fpath = mpath / drive
files = [ x for x in fpath.iterdir() if x.is_file() ] filenames = [ x.name for x in fpath.iterdir() if x.is_file() ]
except: except:
continue continue
else: else:
if target_filename in files: if target_filename in filenames:
upload_disk = mpath / drive upload_disk = mpath / drive
target_file_found = True target_file_found = True
break break
@@ -104,21 +104,21 @@ if pioutil.is_pio_build():
# platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive' # platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
# #
dpath = Path('/Volumes') # human readable names dpath = Path('/Volumes') # human readable names
drives = [ x for x in dpath.iterdir() ] drives = [ x for x in dpath.iterdir() if x.is_dir() ]
if target_drive in drives and not target_file_found: # set upload if not found target file yet if target_drive in drives and not target_file_found: # set upload if not found target file yet
target_drive_found = True target_drive_found = True
upload_disk = dpath / target_drive upload_disk = dpath / target_drive
for drive in drives: for drive in drives:
try: try:
fpath = dpath / drive # will get an error if the drive is protected fpath = dpath / drive # will get an error if the drive is protected
files = [ x for x in fpath.iterdir() ] filenames = [ x.name for x in fpath.iterdir() if x.is_file() ]
except: except:
continue continue
else: else:
if target_filename in files: if target_filename in filenames:
if not target_file_found:
upload_disk = dpath / drive upload_disk = dpath / drive
target_file_found = True target_file_found = True
break
# #
# Set upload_port to drive if found # Set upload_port to drive if found

View File

@@ -44,7 +44,7 @@
* *
* Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW); * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW);
* *
* Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html
*/ */
/// Read a pin /// Read a pin

View File

@@ -51,7 +51,7 @@ enum XPTCoordinate : uint8_t {
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE, XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
}; };
#if !defined(XPT2046_Z1_THRESHOLD) #ifndef XPT2046_Z1_THRESHOLD
#define XPT2046_Z1_THRESHOLD 10 #define XPT2046_Z1_THRESHOLD 10
#endif #endif

View File

@@ -168,4 +168,4 @@ uint8_t u8g_com_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
#endif #endif
#endif // IS_U8GLIB_ST7920 #endif // IS_U8GLIB_ST7920
#endif // TARGET_LPC1768 #endif // __PLAT_NATIVE_SIM__

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -18,6 +19,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef __SAMD51__ #ifdef __SAMD51__
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -20,6 +21,10 @@
*/ */
#pragma once #pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#define CPU_32_BIT #define CPU_32_BIT
#include "../shared/Marduino.h" #include "../shared/Marduino.h"

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -19,6 +20,10 @@
* *
*/ */
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
/** /**
* Hardware and software SPI implementations are included in this file. * Hardware and software SPI implementations are included in this file.
* *

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -18,6 +19,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef ADAFRUIT_GRAND_CENTRAL_M4 #ifdef ADAFRUIT_GRAND_CENTRAL_M4
/** /**

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -20,6 +21,10 @@
*/ */
#pragma once #pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#include "../../core/serial_hook.h" #include "../../core/serial_hook.h"
typedef Serial1Class<Uart> UartT; typedef Serial1Class<Uart> UartT;

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -20,6 +21,10 @@
*/ */
#pragma once #pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#define SYNC(sc) while (sc) { \ #define SYNC(sc) while (sc) { \
asm(""); \ asm(""); \
} }

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -19,6 +20,10 @@
* *
*/ */
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
/** /**
* This comes from Arduino library which at the moment is buggy and uncompilable * This comes from Arduino library which at the moment is buggy and uncompilable
*/ */

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -20,6 +21,10 @@
*/ */
#pragma once #pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#define _useTimer1 #define _useTimer1
#define _useTimer2 #define _useTimer2

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -18,6 +19,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef __SAMD51__ #ifdef __SAMD51__
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -18,6 +19,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef __SAMD51__ #ifdef __SAMD51__
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -18,6 +19,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef __SAMD51__ #ifdef __SAMD51__
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -20,6 +21,10 @@
*/ */
#pragma once #pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
/** /**
* Endstop interrupts for ATMEL SAMD51 based targets. * Endstop interrupts for ATMEL SAMD51 based targets.
* *

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -20,6 +21,10 @@
*/ */
#pragma once #pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
/** /**
* Fast IO functions for SAMD51 * Fast IO functions for SAMD51
*/ */

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -18,6 +19,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
#pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
/** /**
* Test SAMD51 specific configuration values for errors at compile-time. * Test SAMD51 specific configuration values for errors at compile-time.

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -20,6 +21,10 @@
*/ */
#pragma once #pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#define NUMBER_PINS_TOTAL PINS_COUNT #define NUMBER_PINS_TOTAL PINS_COUNT
#define digitalRead_mod(p) extDigitalRead(p) #define digitalRead_mod(p) extDigitalRead(p)
@@ -29,7 +34,7 @@
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) #define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
#define GET_ARRAY_PIN(p) pin_array[p].pin #define GET_ARRAY_PIN(p) pin_array[p].pin
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital #define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL) #define VALID_PIN(pin) (pin >= 0 && pin < int8_t(NUMBER_PINS_TOTAL))
#define DIGITAL_PIN_TO_ANALOG_PIN(p) digitalPinToAnalogInput(p) #define DIGITAL_PIN_TO_ANALOG_PIN(p) digitalPinToAnalogInput(p)
#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P)!=-1) #define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P)!=-1)
#define pwm_status(pin) digitalPinHasPWM(pin) #define pwm_status(pin) digitalPinHasPWM(pin)

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -20,6 +21,10 @@
*/ */
#pragma once #pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef ADAFRUIT_GRAND_CENTRAL_M4 #ifdef ADAFRUIT_GRAND_CENTRAL_M4
/* /*

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -18,6 +19,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef __SAMD51__ #ifdef __SAMD51__
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------

View File

@@ -1,8 +1,9 @@
/** /**
* Marlin 3D Printer Firmware * Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) *
* 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -20,6 +21,10 @@
*/ */
#pragma once #pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#include <stdint.h> #include <stdint.h>
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------

View File

@@ -95,7 +95,7 @@
static_assert(IS_FLASH_SECTOR(FLASH_SECTOR), "FLASH_SECTOR is invalid"); static_assert(IS_FLASH_SECTOR(FLASH_SECTOR), "FLASH_SECTOR is invalid");
static_assert(IS_POWER_OF_2(FLASH_UNIT_SIZE), "FLASH_UNIT_SIZE should be a power of 2, please check your chip's spec sheet"); static_assert(IS_POWER_OF_2(FLASH_UNIT_SIZE), "FLASH_UNIT_SIZE should be a power of 2, please check your chip's spec sheet");
#endif #endif // FLASH_EEPROM_LEVELING
static bool eeprom_data_written = false; static bool eeprom_data_written = false;
@@ -189,15 +189,15 @@ bool PersistentStore::access_finish() {
UNLOCK_FLASH(); UNLOCK_FLASH();
uint32_t offset = 0; uint32_t offset = 0,
uint32_t address = SLOT_ADDRESS(current_slot); address = SLOT_ADDRESS(current_slot),
uint32_t address_end = address + MARLIN_EEPROM_SIZE; address_end = address + MARLIN_EEPROM_SIZE,
uint32_t data = 0; data = 0;
bool success = true; bool success = true;
while (address < address_end) { while (address < address_end) {
memcpy(&data, ram_eeprom + offset, sizeof(uint32_t)); memcpy(&data, ram_eeprom + offset, sizeof(data));
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data); status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data);
if (status == HAL_OK) { if (status == HAL_OK) {
address += sizeof(uint32_t); address += sizeof(uint32_t);
@@ -221,7 +221,8 @@ bool PersistentStore::access_finish() {
return success; return success;
#else #else // !FLASH_EEPROM_LEVELING
// The following was written for the STM32F4 but may work with other MCUs as well. // The following was written for the STM32F4 but may work with other MCUs as well.
// Most STM32F4 flash does not allow reading from flash during erase operations. // Most STM32F4 flash does not allow reading from flash during erase operations.
// This takes about a second on a STM32F407 with a 128kB sector used as EEPROM. // This takes about a second on a STM32F407 with a 128kB sector used as EEPROM.
@@ -235,7 +236,8 @@ bool PersistentStore::access_finish() {
TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT()); TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT());
eeprom_data_written = false; eeprom_data_written = false;
#endif
#endif // !FLASH_EEPROM_LEVELING
} }
return true; return true;

View File

@@ -27,3 +27,8 @@
#elif EITHER(I2C_EEPROM, SPI_EEPROM) #elif EITHER(I2C_EEPROM, SPI_EEPROM)
#define USE_SHARED_EEPROM 1 #define USE_SHARED_EEPROM 1
#endif #endif
// Some STM32F4 boards may lose steps when saving to EEPROM during print (PR #17946)
#if defined(STM32F4xx) && ENABLED(FLASH_EEPROM_EMULATION) && PRINTCOUNTER_SAVE_INTERVAL > 0
#define PRINTCOUNTER_SYNC 1
#endif

View File

@@ -37,11 +37,6 @@
#error "SDCARD_EEPROM_EMULATION requires SDSUPPORT. Enable SDSUPPORT or choose another EEPROM emulation." #error "SDCARD_EEPROM_EMULATION requires SDSUPPORT. Enable SDSUPPORT or choose another EEPROM emulation."
#endif #endif
#if defined(STM32F4xx) && BOTH(PRINTCOUNTER, FLASH_EEPROM_EMULATION)
#warning "FLASH_EEPROM_EMULATION may cause long delays when writing and should not be used while printing."
#error "Disable PRINTCOUNTER or choose another EEPROM emulation."
#endif
#if !defined(STM32F4xx) && ENABLED(FLASH_EEPROM_LEVELING) #if !defined(STM32F4xx) && ENABLED(FLASH_EEPROM_LEVELING)
#error "FLASH_EEPROM_LEVELING is currently only supported on STM32F4 hardware." #error "FLASH_EEPROM_LEVELING is currently only supported on STM32F4 hardware."
#endif #endif
@@ -55,3 +50,62 @@
#if ANY(TFT_COLOR_UI, TFT_LVGL_UI, TFT_CLASSIC_UI) && NOT_TARGET(STM32H7xx, STM32F4xx, STM32F1xx) #if ANY(TFT_COLOR_UI, TFT_LVGL_UI, TFT_CLASSIC_UI) && NOT_TARGET(STM32H7xx, STM32F4xx, STM32F1xx)
#error "TFT_COLOR_UI, TFT_LVGL_UI and TFT_CLASSIC_UI are currently only supported on STM32H7, STM32F4 and STM32F1 hardware." #error "TFT_COLOR_UI, TFT_LVGL_UI and TFT_CLASSIC_UI are currently only supported on STM32H7, STM32F4 and STM32F1 hardware."
#endif #endif
/**
* Check for common serial pin conflicts
*/
#define _CHECK_SERIAL_PIN(N) (( \
BTN_EN1 == N || DOGLCD_CS == N || HEATER_BED_PIN == N || FAN_PIN == N || \
SDIO_D2_PIN == N || SDIO_D3_PIN == N || SDIO_CK_PIN == N || SDIO_CMD_PIN == N \
))
#define CHECK_SERIAL_PIN(T,N) defined(UART##N##_##T##_PIN) && _CHECK_SERIAL_PIN(UART##N##_##T##_PIN)
#if SERIAL_IN_USE(1)
#if CHECK_SERIAL_PIN(TX,1)
#error "Serial Port 1 TX IO pins conflict with another pin on the board."
#endif
#if CHECK_SERIAL_PIN(RX,1)
#error "Serial Port 1 RX IO pins conflict with another pin on the board."
#endif
#endif
#if SERIAL_IN_USE(2)
#if CHECK_SERIAL_PIN(TX,2)
#error "Serial Port 2 TX IO pins conflict with another pin on the board."
#endif
#if CHECK_SERIAL_PIN(RX,2)
#error "Serial Port 2 RX IO pins conflict with another pin on the board."
#endif
#endif
#if SERIAL_IN_USE(3)
#if CHECK_SERIAL_PIN(TX,3)
#error "Serial Port 3 TX IO pins conflict with another pin on the board."
#endif
#if CHECK_SERIAL_PIN(RX,3)
#error "Serial Port 3 RX IO pins conflict with another pin on the board."
#endif
#endif
#if SERIAL_IN_USE(4)
#if CHECK_SERIAL_PIN(TX,4)
#error "Serial Port 4 TX IO pins conflict with another pin on the board."
#endif
#if CHECK_SERIAL_PIN(RX,4)
#error "Serial Port 4 RX IO pins conflict with another pin on the board."
#endif
#endif
#if SERIAL_IN_USE(5)
#if CHECK_SERIAL_PIN(TX,5)
#error "Serial Port 5 TX IO pins conflict with another pin on the board."
#endif
#if CHECK_SERIAL_PIN(RX,5)
#error "Serial Port 5 RX IO pins conflict with another pin on the board."
#endif
#endif
#if SERIAL_IN_USE(6)
#if CHECK_SERIAL_PIN(TX,6)
#error "Serial Port 6 TX IO pins conflict with another pin on the board."
#endif
#if CHECK_SERIAL_PIN(RX,6)
#error "Serial Port 6 RX IO pins conflict with another pin on the board."
#endif
#endif
#undef CHECK_SERIAL_PIN
#undef _CHECK_SERIAL_PIN

View File

@@ -108,11 +108,12 @@ const XrefInfo pin_xref[] PROGMEM = {
* Translation of routines & variables used by pinsDebug.h * Translation of routines & variables used by pinsDebug.h
*/ */
#if PA0 >= NUM_DIGITAL_PINS #if NUM_ANALOG_FIRST >= NUM_DIGITAL_PINS
#define HAS_HIGH_ANALOG_PINS 1 #define HAS_HIGH_ANALOG_PINS 1
#endif #endif
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS + TERN0(HAS_HIGH_ANALOG_PINS, NUM_ANALOG_INPUTS) #define NUM_ANALOG_LAST ((NUM_ANALOG_FIRST) + (NUM_ANALOG_INPUTS) - 1)
#define VALID_PIN(ANUM) ((ANUM) >= 0 && (ANUM) < NUMBER_PINS_TOTAL) #define NUMBER_PINS_TOTAL ((NUM_DIGITAL_PINS) + TERN0(HAS_HIGH_ANALOG_PINS, NUM_ANALOG_INPUTS))
#define VALID_PIN(P) (WITHIN(P, 0, (NUM_DIGITAL_PINS) - 1) || TERN0(HAS_HIGH_ANALOG_PINS, WITHIN(P, NUM_ANALOG_FIRST, NUM_ANALOG_LAST)))
#define digitalRead_mod(Ard_num) extDigitalRead(Ard_num) // must use Arduino pin numbers when doing reads #define digitalRead_mod(Ard_num) extDigitalRead(Ard_num) // must use Arduino pin numbers when doing reads
#define PRINT_PIN(Q) #define PRINT_PIN(Q)
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) #define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
@@ -168,7 +169,7 @@ bool GET_PINMODE(const pin_t Ard_num) {
} }
int8_t digital_pin_to_analog_pin(const pin_t Ard_num) { int8_t digital_pin_to_analog_pin(const pin_t Ard_num) {
if (WITHIN(Ard_num, NUM_ANALOG_FIRST, NUM_ANALOG_FIRST + NUM_ANALOG_INPUTS - 1)) if (WITHIN(Ard_num, NUM_ANALOG_FIRST, NUM_ANALOG_LAST))
return Ard_num - NUM_ANALOG_FIRST; return Ard_num - NUM_ANALOG_FIRST;
const uint32_t ind = digitalPinToAnalogInput(Ard_num); const uint32_t ind = digitalPinToAnalogInput(Ard_num);
@@ -206,8 +207,11 @@ void port_print(const pin_t Ard_num) {
SERIAL_ECHO_SP(7); SERIAL_ECHO_SP(7);
// Print number to be used with M42 // Print number to be used with M42
int calc_p = Ard_num % (NUM_DIGITAL_PINS + 1); int calc_p = Ard_num;
if (Ard_num > NUM_DIGITAL_PINS && calc_p > 7) calc_p += 8; if (Ard_num > NUM_DIGITAL_PINS) {
calc_p -= NUM_ANALOG_FIRST;
if (calc_p > 7) calc_p += 8;
}
SERIAL_ECHOPGM(" M42 P", calc_p); SERIAL_ECHOPGM(" M42 P", calc_p);
SERIAL_CHAR(' '); SERIAL_CHAR(' ');
if (calc_p < 100) { if (calc_p < 100) {

View File

@@ -150,9 +150,9 @@ void GT911::read_reg(uint16_t reg, uint8_t reg_len, uint8_t* r_data, uint8_t r_l
sw_iic.start(); sw_iic.start();
sw_iic.send_byte(gt911_slave_address + 1); // Set read mode sw_iic.send_byte(gt911_slave_address + 1); // Set read mode
LOOP_L_N(i, r_len) { LOOP_L_N(i, r_len)
r_data[i] = sw_iic.read_byte(1); // Read data from reg r_data[i] = sw_iic.read_byte(1); // Read data from reg
}
sw_iic.stop(); sw_iic.stop();
} }

View File

@@ -39,42 +39,18 @@ class SW_IIC {
private: private:
uint16_t scl_pin; uint16_t scl_pin;
uint16_t sda_pin; uint16_t sda_pin;
void write_scl(bool level) void write_scl(bool level) { WRITE(scl_pin, level); }
{ void write_sda(bool level) { WRITE(sda_pin, level); }
WRITE(scl_pin, level); bool read_sda() { return READ(sda_pin); }
} void set_sda_out() { SET_OUTPUT(sda_pin); }
void write_sda(bool level) void set_sda_in() { SET_INPUT_PULLUP(sda_pin); }
{ static void iic_delay(uint8_t t) { delayMicroseconds(t); }
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: public:
SW_IIC(uint16_t sda, uint16_t scl); SW_IIC(uint16_t sda, uint16_t scl);
// setSCL/SDA have to be called before begin() // setSCL/SDA have to be called before begin()
void setSCL(uint16_t scl) void setSCL(uint16_t scl) { scl_pin = scl; }
{ void setSDA(uint16_t sda) { sda_pin = sda; }
scl_pin = scl;
};
void setSDA(uint16_t sda)
{
sda_pin = sda;
};
void init(); // Initialize the IO port of IIC void init(); // Initialize the IO port of IIC
void start(); // Send IIC start signal void start(); // Send IIC start signal
void stop(); // Send IIC stop signal void stop(); // Send IIC stop signal

View File

@@ -147,21 +147,36 @@ uint32_t TFT_FSMC::ReadID(tft_data_t Reg) {
} }
bool TFT_FSMC::isBusy() { bool TFT_FSMC::isBusy() {
#if defined(STM32F1xx) #ifdef STM32F1xx
volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET; #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
#define __IS_DMA_CONFIGURED(__HANDLE__) ((__HANDLE__)->Instance->CPAR != 0)
#elif defined(STM32F4xx) #elif defined(STM32F4xx)
volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN; #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
#define __IS_DMA_CONFIGURED(__HANDLE__) ((__HANDLE__)->Instance->PAR != 0)
#endif #endif
if (dmaEnabled) {
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0) if (!__IS_DMA_CONFIGURED(&DMAtx)) return false;
// Check if DMA transfer error or transfer complete flags are set
if ((__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) == 0) && (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) == 0)) return true;
__DSB();
Abort(); Abort();
return false;
} }
else
Abort(); void TFT_FSMC::Abort() {
return dmaEnabled; HAL_DMA_Abort(&DMAtx); // Abort DMA transfer if any
HAL_DMA_DeInit(&DMAtx); // Deconfigure DMA
} }
void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DMAtx.Init.PeriphInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx);
HAL_DMA_Start(&DMAtx, (uint32_t)Data, (uint32_t)&(LCD->RAM), Count);
}
void TFT_FSMC::Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DMAtx.Init.PeriphInc = MemoryIncrease; DMAtx.Init.PeriphInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx); HAL_DMA_Init(&DMAtx);
DataTransferBegin(); DataTransferBegin();

View File

@@ -41,6 +41,7 @@
#define DATASIZE_8BIT SPI_DATASIZE_8BIT #define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT #define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO_DRIVER TFT_FSMC #define TFT_IO_DRIVER TFT_FSMC
#define DMA_MAX_SIZE 0xFFFF
#define TFT_DATASIZE TERN(TFT_INTERFACE_FSMC_8BIT, DATASIZE_8BIT, DATASIZE_16BIT) #define TFT_DATASIZE TERN(TFT_INTERFACE_FSMC_8BIT, DATASIZE_8BIT, DATASIZE_16BIT)
typedef TERN(TFT_INTERFACE_FSMC_8BIT, uint8_t, uint16_t) tft_data_t; typedef TERN(TFT_INTERFACE_FSMC_8BIT, uint8_t, uint16_t) tft_data_t;
@@ -59,13 +60,14 @@ class TFT_FSMC {
static uint32_t ReadID(tft_data_t Reg); static uint32_t ReadID(tft_data_t Reg);
static void Transmit(tft_data_t Data) { LCD->RAM = Data; __DSB(); } static void Transmit(tft_data_t Data) { LCD->RAM = Data; __DSB(); }
static void Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public: public:
static void Init(); static void Init();
static uint32_t GetID(); static uint32_t GetID();
static bool isBusy(); static bool isBusy();
static void Abort() { __HAL_DMA_DISABLE(&DMAtx); } static void Abort();
static void DataTransferBegin(uint16_t DataWidth = TFT_DATASIZE) {} static void DataTransferBegin(uint16_t DataWidth = TFT_DATASIZE) {}
static void DataTransferEnd() {}; static void DataTransferEnd() {};
@@ -73,13 +75,14 @@ class TFT_FSMC {
static void WriteData(uint16_t Data) { Transmit(tft_data_t(Data)); } static void WriteData(uint16_t Data) { Transmit(tft_data_t(Data)); }
static void WriteReg(uint16_t Reg) { LCD->REG = tft_data_t(Reg); __DSB(); } static void WriteReg(uint16_t Reg) { LCD->REG = tft_data_t(Reg); __DSB(); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, Data, Count); } static void WriteSequence_DMA(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_PINC_DISABLE, &Data, Count); } static void WriteMultiple_DMA(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_PINC_DISABLE, &Data, Count); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { Transmit(DMA_PINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) { static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
while (Count > 0) { while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count); Transmit(DMA_MINC_DISABLE, &Color, Count > DMA_MAX_SIZE ? DMA_MAX_SIZE : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0; Count = Count > DMA_MAX_SIZE ? Count - DMA_MAX_SIZE : 0;
} }
} }
}; };

View File

@@ -356,7 +356,7 @@ void TFT_LTDC::WriteReg(uint16_t Reg) {
reg = Reg; reg = Reg;
} }
void TFT_LTDC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { void TFT_LTDC::Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
while (x_cur != x_min && Count) { while (x_cur != x_min && Count) {
Transmit(*Data); Transmit(*Data);

View File

@@ -32,6 +32,7 @@
#define DATASIZE_8BIT SPI_DATASIZE_8BIT #define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT #define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO_DRIVER TFT_LTDC #define TFT_IO_DRIVER TFT_LTDC
#define DMA_MAX_SIZE 0xFFFF
#define TFT_DATASIZE DATASIZE_16BIT #define TFT_DATASIZE DATASIZE_16BIT
typedef uint16_t tft_data_t; typedef uint16_t tft_data_t;
@@ -49,7 +50,7 @@ class TFT_LTDC {
static void DrawRect(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t color); static void DrawRect(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t color);
static void DrawImage(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *colors); static void DrawImage(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *colors);
static void Transmit(tft_data_t Data); static void Transmit(tft_data_t Data);
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); static void Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public: public:
static void Init(); static void Init();
@@ -63,13 +64,15 @@ class TFT_LTDC {
static void WriteData(uint16_t Data); static void WriteData(uint16_t Data);
static void WriteReg(uint16_t Reg); static void WriteReg(uint16_t Reg);
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, Data, Count); } // Non-blocking DMA data transfer is not implemented for LTDC interface
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_PINC_DISABLE, &Data, Count); } inline static void WriteSequence_DMA(uint16_t *Data, uint16_t Count) { WriteSequence(Data, Count); }
inline static void WriteMultiple_DMA(uint16_t Color, uint16_t Count) { WriteMultiple(Color, Count); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { Transmit(DMA_PINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) { static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
while (Count > 0) { while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count); Transmit(DMA_PINC_DISABLE, &Color, Count > DMA_MAX_SIZE ? DMA_MAX_SIZE : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0; Count = Count > DMA_MAX_SIZE ? Count - DMA_MAX_SIZE : 0;
} }
} }
}; };

View File

@@ -160,16 +160,13 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
#if TFT_MISO_PIN != TFT_MOSI_PIN #if TFT_MISO_PIN != TFT_MOSI_PIN
//if (hspi->Init.Direction == SPI_DIRECTION_2LINES) {
while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {} while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {}
SPIx.Instance->DR = 0; SPIx.Instance->DR = 0;
//}
#endif #endif
while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_RXNE)) {} while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_RXNE)) {}
Data = (Data << 8) | SPIx.Instance->DR; Data = (Data << 8) | SPIx.Instance->DR;
} }
__HAL_SPI_DISABLE(&SPIx);
DataTransferEnd(); DataTransferEnd();
SPIx.Init.BaudRatePrescaler = BaudRatePrescaler; SPIx.Init.BaudRatePrescaler = BaudRatePrescaler;
@@ -179,36 +176,44 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
} }
bool TFT_SPI::isBusy() { bool TFT_SPI::isBusy() {
#if defined(STM32F1xx) #ifdef STM32F1xx
volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET; #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
#define __IS_DMA_CONFIGURED(__HANDLE__) ((__HANDLE__)->Instance->CPAR != 0)
#elif defined(STM32F4xx) #elif defined(STM32F4xx)
volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN; #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
#define __IS_DMA_CONFIGURED(__HANDLE__) ((__HANDLE__)->Instance->PAR != 0)
#endif #endif
if (dmaEnabled) {
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0) if (!__IS_DMA_CONFIGURED(&DMAtx)) return false;
Abort();
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx))) {
// You should not be here - DMA transfer error flag is set
// Abort DMA transfer and release SPI
} }
else else {
// Check if DMA transfer completed flag is set
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) == 0) return true;
// Check if SPI transmit butter is empty and SPI is idle
if ((!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) || (__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_BSY))) return true;
}
Abort(); Abort();
return dmaEnabled; return false;
} }
void TFT_SPI::Abort() { void TFT_SPI::Abort() {
// Wait for any running spi HAL_DMA_Abort(&DMAtx); // Abort DMA transfer if any
while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {}
while ( __HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_BSY)) {}
// First, abort any running dma
HAL_DMA_Abort(&DMAtx);
// DeInit objects
HAL_DMA_DeInit(&DMAtx); HAL_DMA_DeInit(&DMAtx);
HAL_SPI_DeInit(&SPIx);
// Deselect CS CLEAR_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN);
DataTransferEnd();
DataTransferEnd(); // Stop SPI and deselect CS
} }
void TFT_SPI::Transmit(uint16_t Data) { void TFT_SPI::Transmit(uint16_t Data) {
if (TFT_MISO_PIN == TFT_MOSI_PIN) #if TFT_MISO_PIN == TFT_MOSI_PIN
SPI_1LINE_TX(&SPIx); SPI_1LINE_TX(&SPIx);
#endif
__HAL_SPI_ENABLE(&SPIx); __HAL_SPI_ENABLE(&SPIx);
@@ -217,14 +222,31 @@ void TFT_SPI::Transmit(uint16_t Data) {
while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {} while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {}
while ( __HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_BSY)) {} while ( __HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_BSY)) {}
if (TFT_MISO_PIN != TFT_MOSI_PIN) #if TFT_MISO_PIN != TFT_MOSI_PIN
__HAL_SPI_CLEAR_OVRFLAG(&SPIx); // Clear overrun flag in 2 Lines communication mode because received is not read __HAL_SPI_CLEAR_OVRFLAG(&SPIx); // Clear overrun flag in 2 Lines communication mode because received data is not read
#endif
} }
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
// Wait last dma finish, to start another DMAtx.Init.MemInc = MemoryIncrease;
while (isBusy()) { /* nada */ } HAL_DMA_Init(&DMAtx);
#if TFT_MISO_PIN == TFT_MOSI_PIN
SPI_1LINE_TX(&SPIx);
#endif
DataTransferBegin();
HAL_DMA_Start(&DMAtx, (uint32_t)Data, (uint32_t)&(SPIx.Instance->DR), Count);
__HAL_SPI_ENABLE(&SPIx);
SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); // Enable Tx DMA Request
TERN_(TFT_SHARED_SPI, while (isBusy()));
}
void TFT_SPI::Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DMAtx.Init.MemInc = MemoryIncrease; DMAtx.Init.MemInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx); HAL_DMA_Init(&DMAtx);
@@ -243,7 +265,6 @@ void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Coun
} }
#if ENABLED(USE_SPI_DMA_TC) #if ENABLED(USE_SPI_DMA_TC)
void TFT_SPI::TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { void TFT_SPI::TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DMAtx.Init.MemInc = MemoryIncrease; DMAtx.Init.MemInc = MemoryIncrease;
@@ -262,8 +283,7 @@ void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Coun
SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); // Enable Tx DMA Request SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); // Enable Tx DMA Request
} }
extern "C" void DMA2_Stream3_IRQHandler(void) { HAL_DMA_IRQHandler(&TFT_SPI::DMAtx); } extern "C" void DMA2_Stream3_IRQHandler(void) { TFT_SPI::DMA_IRQHandler(); }
#endif #endif
#endif // HAS_SPI_TFT #endif // HAS_SPI_TFT

View File

@@ -39,46 +39,47 @@
#define DATASIZE_8BIT SPI_DATASIZE_8BIT #define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT #define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO_DRIVER TFT_SPI #define TFT_IO_DRIVER TFT_SPI
#define DMA_MAX_SIZE 0xFFFF
class TFT_SPI { class TFT_SPI {
private: private:
static SPI_HandleTypeDef SPIx; static SPI_HandleTypeDef SPIx;
static DMA_HandleTypeDef DMAtx;
static uint32_t ReadID(uint16_t Reg); static uint32_t ReadID(uint16_t Reg);
static void Transmit(uint16_t Data); static void Transmit(uint16_t Data);
static void Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
#if ENABLED(USE_SPI_DMA_TC) #if ENABLED(USE_SPI_DMA_TC)
static void TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); static void TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
#endif #endif
public: public:
static DMA_HandleTypeDef DMAtx;
static void Init(); static void Init();
static uint32_t GetID(); static uint32_t GetID();
static bool isBusy(); static bool isBusy();
static void Abort(); static void Abort();
static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT); static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT);
static void DataTransferEnd() { WRITE(TFT_CS_PIN, HIGH); }; static void DataTransferEnd() { WRITE(TFT_CS_PIN, HIGH); __HAL_SPI_DISABLE(&SPIx); };
static void DataTransferAbort(); static void DataTransferAbort();
static void WriteData(uint16_t Data) { Transmit(Data); } static void WriteData(uint16_t Data) { Transmit(Data); }
static void WriteReg(uint16_t Reg) { WRITE(TFT_A0_PIN, LOW); Transmit(Reg); WRITE(TFT_A0_PIN, HIGH); } static void WriteReg(uint16_t Reg) { WRITE(TFT_A0_PIN, LOW); Transmit(Reg); WRITE(TFT_A0_PIN, HIGH); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); } static void WriteSequence_DMA(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); }
static void WriteMultiple_DMA(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
#if ENABLED(USE_SPI_DMA_TC) #if ENABLED(USE_SPI_DMA_TC)
static void WriteSequenceIT(uint16_t *Data, uint16_t Count) { TransmitDMA_IT(DMA_MINC_ENABLE, Data, Count); } static void WriteSequenceIT(uint16_t *Data, uint16_t Count) { TransmitDMA_IT(DMA_MINC_ENABLE, Data, Count); }
inline static void DMA_IRQHandler() { HAL_DMA_IRQHandler(&TFT_SPI::DMAtx); }
#endif #endif
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); } static void WriteSequence(uint16_t *Data, uint16_t Count) { Transmit(DMA_MINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) { static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
while (Count > 0) { while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count); Transmit(DMA_MINC_DISABLE, &Color, Count > DMA_MAX_SIZE ? DMA_MAX_SIZE : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0; Count = Count > DMA_MAX_SIZE ? Count - DMA_MAX_SIZE : 0;
} }
} }
}; };

View File

@@ -541,8 +541,7 @@ void SPIClass::onReceive(void(*callback)()) {
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi3EventCallback); dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi3EventCallback);
break; break;
#endif #endif
default: default: ASSERT(0);
ASSERT(0);
} }
} }
else { else {
@@ -569,8 +568,7 @@ void SPIClass::onTransmit(void(*callback)()) {
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi3EventCallback); dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi3EventCallback);
break; break;
#endif #endif
default: default: ASSERT(0);
ASSERT(0);
} }
} }
else { else {

View File

@@ -33,6 +33,15 @@
#include <stdint.h> #include <stdint.h>
#include <wirish.h> #include <wirish.h>
// Number of SPI ports
#ifdef BOARD_SPI3_SCK_PIN
#define BOARD_NR_SPI 3
#elif defined(BOARD_SPI2_SCK_PIN)
#define BOARD_NR_SPI 2
#elif defined(BOARD_SPI1_SCK_PIN)
#define BOARD_NR_SPI 1
#endif
// SPI_HAS_TRANSACTION means SPI has // SPI_HAS_TRANSACTION means SPI has
// - beginTransaction() // - beginTransaction()
// - endTransaction() // - endTransaction()

View File

@@ -215,22 +215,47 @@ uint32_t TFT_FSMC::GetID() {
} }
bool TFT_FSMC::isBusy() { bool TFT_FSMC::isBusy() {
#define __IS_DMA_CONFIGURED(__DMAx__, __CHx__) (dma_channel_regs(__DMAx__, __CHx__)->CPAR != 0)
if (!__IS_DMA_CONFIGURED(FSMC_DMA_DEV, FSMC_DMA_CHANNEL)) return false;
// Check if DMA transfer error or transfer complete flags are set
if ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & (DMA_ISR_TCIF | DMA_ISR_TEIF)) == 0) return true;
__DSB();
Abort();
return false; return false;
} }
void TFT_FSMC::Abort() { void TFT_FSMC::Abort() {
dma_channel_reg_map *channel_regs = dma_channel_regs(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); // Abort DMA transfer if any
// Deconfigure DMA
channel_regs->CCR = 0U;
channel_regs->CNDTR = 0U;
channel_regs->CMAR = 0U;
channel_regs->CPAR = 0U;
} }
void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
// TODO: HAL STM32 uses DMA2_Channel1 for FSMC on STM32F1
dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | MemoryIncrease);
dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Count);
dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
}
void TFT_FSMC::Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
#if defined(FSMC_DMA_DEV) && defined(FSMC_DMA_CHANNEL) #if defined(FSMC_DMA_DEV) && defined(FSMC_DMA_CHANNEL)
dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | MemoryIncrease); dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | MemoryIncrease);
dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Count); dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Count);
dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {}; while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & (DMA_CCR_TEIE | DMA_CCR_TCIE)) == 0) {}
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); Abort();
#endif #endif
} }

View File

@@ -33,6 +33,10 @@
#define DATASIZE_8BIT DMA_SIZE_8BITS #define DATASIZE_8BIT DMA_SIZE_8BITS
#define DATASIZE_16BIT DMA_SIZE_16BITS #define DATASIZE_16BIT DMA_SIZE_16BITS
#define TFT_IO_DRIVER TFT_FSMC #define TFT_IO_DRIVER TFT_FSMC
#define DMA_MAX_SIZE 0xFFFF
#define DMA_PINC_ENABLE DMA_PINC_MODE
#define DMA_PINC_DISABLE 0
typedef struct { typedef struct {
__IO uint16_t REG; __IO uint16_t REG;
@@ -45,6 +49,7 @@ class TFT_FSMC {
static uint32_t ReadID(uint16_t Reg); static uint32_t ReadID(uint16_t Reg);
static void Transmit(uint16_t Data); static void Transmit(uint16_t Data);
static void Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public: public:
@@ -59,13 +64,14 @@ class TFT_FSMC {
static void WriteData(uint16_t Data) { Transmit(Data); } static void WriteData(uint16_t Data) { Transmit(Data); }
static void WriteReg(uint16_t Reg); static void WriteReg(uint16_t Reg);
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_MODE, Data, Count); } static void WriteSequence_DMA(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_CIRC_MODE, &Data, Count); } static void WriteMultiple_DMA(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_PINC_DISABLE, &Data, Count); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { Transmit(DMA_PINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) { static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
while (Count > 0) { while (Count > 0) {
TransmitDMA(DMA_CIRC_MODE, &Data, Count > 0xFFFF ? 0xFFFF : Count); Transmit(DMA_PINC_DISABLE, &Color, Count > DMA_MAX_SIZE ? DMA_MAX_SIZE : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0; Count = Count > DMA_MAX_SIZE ? Count - DMA_MAX_SIZE : 0;
} }
} }
}; };

View File

@@ -26,7 +26,7 @@
#include "tft_spi.h" #include "tft_spi.h"
SPIClass TFT_SPI::SPIx(1); SPIClass TFT_SPI::SPIx(TFT_SPI_DEVICE);
void TFT_SPI::Init() { void TFT_SPI::Init() {
#if PIN_EXISTS(TFT_RESET) #if PIN_EXISTS(TFT_RESET)
@@ -46,7 +46,7 @@ void TFT_SPI::Init() {
* STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1 * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1
* so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2 * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
*/ */
#if SPI_DEVICE == 1 #if TFT_SPI_DEVICE == 1
#define SPI_CLOCK_MAX SPI_CLOCK_DIV4 #define SPI_CLOCK_MAX SPI_CLOCK_DIV4
#else #else
#define SPI_CLOCK_MAX SPI_CLOCK_DIV2 #define SPI_CLOCK_MAX SPI_CLOCK_DIV2
@@ -62,7 +62,7 @@ void TFT_SPI::Init() {
case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
default: clock = SPI_CLOCK_DIV2; // Default from the SPI library default: clock = SPI_CLOCK_DIV2; // Default from the SPI library
} }
SPIx.setModule(1); SPIx.setModule(TFT_SPI_DEVICE);
SPIx.setClockDivider(clock); SPIx.setClockDivider(clock);
SPIx.setBitOrder(MSBFIRST); SPIx.setBitOrder(MSBFIRST);
SPIx.setDataMode(SPI_MODE0); SPIx.setDataMode(SPI_MODE0);
@@ -71,7 +71,7 @@ void TFT_SPI::Init() {
void TFT_SPI::DataTransferBegin(uint16_t DataSize) { void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
SPIx.setDataSize(DataSize); SPIx.setDataSize(DataSize);
SPIx.begin(); SPIx.begin();
OUT_WRITE(TFT_CS_PIN, LOW); WRITE(TFT_CS_PIN, LOW);
} }
#ifdef TFT_DEFAULT_DRIVER #ifdef TFT_DEFAULT_DRIVER
@@ -113,15 +113,53 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
#endif #endif
} }
bool TFT_SPI::isBusy() { return false; } bool TFT_SPI::isBusy() {
#define __IS_DMA_CONFIGURED(__DMAx__, __CHx__) (dma_channel_regs(__DMAx__, __CHx__)->CPAR != 0)
void TFT_SPI::Abort() { DataTransferEnd(); } if (!__IS_DMA_CONFIGURED(DMAx, DMA_CHx)) return false;
if (dma_get_isr_bits(DMAx, DMA_CHx) & DMA_ISR_TEIF) {
// You should not be here - DMA transfer error flag is set
// Abort DMA transfer and release SPI
}
else {
// Check if DMA transfer completed flag is set
if (!(dma_get_isr_bits(DMAx, DMA_CHx) & DMA_ISR_TCIF)) return true;
// Check if SPI TX butter is empty and SPI is idle
if (!(SPIdev->regs->SR & SPI_SR_TXE) || (SPIdev->regs->SR & SPI_SR_BSY)) return true;
}
Abort();
return false;
}
void TFT_SPI::Abort() {
dma_channel_reg_map *channel_regs = dma_channel_regs(DMAx, DMA_CHx);
dma_disable(DMAx, DMA_CHx); // Abort DMA transfer if any
spi_tx_dma_disable(SPIdev);
// Deconfigure DMA
channel_regs->CCR = 0U;
channel_regs->CNDTR = 0U;
channel_regs->CMAR = 0U;
channel_regs->CPAR = 0U;
DataTransferEnd();
}
void TFT_SPI::Transmit(uint16_t Data) { SPIx.send(Data); } void TFT_SPI::Transmit(uint16_t Data) { SPIx.send(Data); }
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DataTransferBegin(); DataTransferBegin();
OUT_WRITE(TFT_DC_PIN, HIGH); SPIx.dmaSendAsync(Data, Count, MemoryIncrease == DMA_MINC_ENABLE);
TERN_(TFT_SHARED_SPI, while (isBusy()));
}
void TFT_SPI::Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
WRITE(TFT_DC_PIN, HIGH);
DataTransferBegin();
SPIx.dmaSend(Data, Count, MemoryIncrease == DMA_MINC_ENABLE); SPIx.dmaSend(Data, Count, MemoryIncrease == DMA_MINC_ENABLE);
DataTransferEnd(); DataTransferEnd();
} }

View File

@@ -25,6 +25,27 @@
#include <SPI.h> #include <SPI.h>
#define IS_SPI(N) (BOARD_NR_SPI >= N && (TFT_SCK_PIN == BOARD_SPI##N##_SCK_PIN) && (TFT_MOSI_PIN == BOARD_SPI##N##_MOSI_PIN) && (TFT_MISO_PIN == BOARD_SPI##N##_MISO_PIN))
#if IS_SPI(1)
#define TFT_SPI_DEVICE 1
#define SPIdev SPI1
#define DMAx DMA1
#define DMA_CHx DMA_CH3
#elif IS_SPI(2)
#define TFT_SPI_DEVICE 2
#define SPIdev SPI2
#define DMAx DMA1
#define DMA_CHx DMA_CH5
#elif IS_SPI(3)
#define TFT_SPI_DEVICE 3
#define SPIdev SPI3
#define DMAx DMA2
#define DMA_CHx DMA_CH2
#else
#error "Invalid TFT SPI configuration."
#endif
#undef IS_SPI
#ifndef LCD_READ_ID #ifndef LCD_READ_ID
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif #endif
@@ -35,14 +56,16 @@
#define DATASIZE_8BIT DATA_SIZE_8BIT #define DATASIZE_8BIT DATA_SIZE_8BIT
#define DATASIZE_16BIT DATA_SIZE_16BIT #define DATASIZE_16BIT DATA_SIZE_16BIT
#define TFT_IO_DRIVER TFT_SPI #define TFT_IO_DRIVER TFT_SPI
#define DMA_MAX_SIZE 0xFFFF
#define DMA_MINC_ENABLE 1 #define DMA_MINC_ENABLE DMA_MINC_MODE
#define DMA_MINC_DISABLE 0 #define DMA_MINC_DISABLE 0
class TFT_SPI { class TFT_SPI {
private: private:
static uint32_t ReadID(uint16_t Reg); static uint32_t ReadID(uint16_t Reg);
static void Transmit(uint16_t Data); static void Transmit(uint16_t Data);
static void Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public: public:
@@ -58,15 +81,16 @@ public:
static void DataTransferAbort(); static void DataTransferAbort();
static void WriteData(uint16_t Data) { Transmit(Data); } static void WriteData(uint16_t Data) { Transmit(Data); }
static void WriteReg(uint16_t Reg) { WRITE(TFT_A0_PIN, LOW); Transmit(Reg); WRITE(TFT_A0_PIN, HIGH); } static void WriteReg(uint16_t Reg) { WRITE(TFT_DC_PIN, LOW); Transmit(Reg); WRITE(TFT_DC_PIN, HIGH); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); } static void WriteSequence_DMA(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); } static void WriteMultiple_DMA(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { Transmit(DMA_MINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) { static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
while (Count > 0) { while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count); Transmit(DMA_MINC_DISABLE, &Color, Count > DMA_MAX_SIZE ? DMA_MAX_SIZE : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0; Count = Count > DMA_MAX_SIZE ? Count - DMA_MAX_SIZE : 0;
} }
} }
}; };

View File

@@ -36,7 +36,7 @@
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) #define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
#define GET_ARRAY_PIN(p) pin_array[p].pin #define GET_ARRAY_PIN(p) pin_array[p].pin
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital #define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL ? 1 : 0) #define VALID_PIN(pin) (pin >= 0 && pin < int8_t(NUMBER_PINS_TOTAL))
#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0)) #define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0))
#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && (P) <= analogInputToDigitalPin(13)) || ((P) >= analogInputToDigitalPin(14) && (P) <= analogInputToDigitalPin(17)) #define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && (P) <= analogInputToDigitalPin(13)) || ((P) >= analogInputToDigitalPin(14) && (P) <= analogInputToDigitalPin(17))
#define pwm_status(pin) HAL_pwm_status(pin) #define pwm_status(pin) HAL_pwm_status(pin)

View File

@@ -50,6 +50,8 @@
#define HAL_PATH(PATH, NAME) XSTR(PATH/NATIVE_SIM/NAME) #define HAL_PATH(PATH, NAME) XSTR(PATH/NATIVE_SIM/NAME)
#elif defined(__SAMD51__) #elif defined(__SAMD51__)
#define HAL_PATH(PATH, NAME) XSTR(PATH/SAMD51/NAME) #define HAL_PATH(PATH, NAME) XSTR(PATH/SAMD51/NAME)
#elif defined(__SAMD21__)
#define HAL_PATH(PATH, NAME) XSTR(PATH/SAMD21/NAME)
#else #else
#error "Unsupported Platform!" #error "Unsupported Platform!"
#endif #endif

View File

@@ -35,6 +35,7 @@ void UnwPrintf(const char *format, ...) {
va_start(args, format); va_start(args, format);
vprintf(format, args); vprintf(format, args);
va_end(args);
} }
#endif #endif

View File

@@ -83,10 +83,10 @@
#else #else
#include <stdint.h> #include <stdint.h>
#if defined(__AVR__) || defined(ARDUINO_ARCH_SAM) || defined(__SAMD51__) #if defined(__AVR__) || defined(ARDUINO_ARCH_SAM) || defined(__SAMD51__) || defined(__SAMD21__)
// we're good to go // we're good to go
#else #else
#error "This library only supports boards with an AVR, SAM3X or SAMD51 processor." #error "This library only supports boards with an AVR, SAM3X, SAMD21 or SAMD51 processor."
#endif #endif
#define Servo_VERSION 2 // software version of this library #define Servo_VERSION 2 // software version of this library

View File

@@ -49,8 +49,10 @@
#include "../DUE/ServoTimers.h" #include "../DUE/ServoTimers.h"
#elif defined(__SAMD51__) #elif defined(__SAMD51__)
#include "../SAMD51/ServoTimers.h" #include "../SAMD51/ServoTimers.h"
#elif defined(__SAMD21__)
#include "../SAMD21/ServoTimers.h"
#else #else
#error "This library only supports boards with an AVR, SAM3X or SAMD51 processor." #error "This library only supports boards with an AVR, SAM3X, SAMD21 or SAMD51 processor."
#endif #endif
// Macros // Macros

View File

@@ -353,7 +353,7 @@ void startOrResumeJob() {
TERN_(GCODE_REPEAT_MARKERS, repeat.reset()); TERN_(GCODE_REPEAT_MARKERS, repeat.reset());
TERN_(CANCEL_OBJECTS, cancelable.reset()); TERN_(CANCEL_OBJECTS, cancelable.reset());
TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator = 0); TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator = 0);
#if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME) #if ENABLED(SET_REMAINING_TIME)
ui.reset_remaining_time(); ui.reset_remaining_time();
#endif #endif
} }
@@ -582,7 +582,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
} }
#endif #endif
#if HAS_FREEZE_PIN #if ENABLED(FREEZE_FEATURE)
stepper.frozen = READ(FREEZE_PIN) == FREEZE_STATE; stepper.frozen = READ(FREEZE_PIN) == FREEZE_STATE;
#endif #endif

View File

@@ -110,15 +110,16 @@
#define BOARD_COPYMASTER_3D 1154 // Copymaster 3D #define BOARD_COPYMASTER_3D 1154 // Copymaster 3D
#define BOARD_ORTUR_4 1155 // Ortur 4 #define BOARD_ORTUR_4 1155 // Ortur 4
#define BOARD_TENLOG_D3_HERO 1156 // Tenlog D3 Hero IDEX printer #define BOARD_TENLOG_D3_HERO 1156 // Tenlog D3 Hero IDEX printer
#define BOARD_RAMPS_S_12_EEFB 1157 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed) #define BOARD_TENLOG_MB1_V23 1157 // Tenlog D3, D5, D6 IDEX Printer
#define BOARD_RAMPS_S_12_EEEB 1158 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed) #define BOARD_RAMPS_S_12_EEFB 1158 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
#define BOARD_RAMPS_S_12_EFFB 1159 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed) #define BOARD_RAMPS_S_12_EEEB 1159 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
#define BOARD_LONGER3D_LK1_PRO 1160 // Longer LK1 PRO / Alfawise U20 Pro (PRO version) #define BOARD_RAMPS_S_12_EFFB 1160 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
#define BOARD_LONGER3D_LKx_PRO 1161 // Longer LKx PRO / Alfawise Uxx Pro (PRO version) #define BOARD_LONGER3D_LK1_PRO 1161 // Longer LK1 PRO / Alfawise U20 Pro (PRO version)
#define BOARD_ZRIB_V53 1162 // Zonestar zrib V5.3 (Chinese RAMPS replica) #define BOARD_LONGER3D_LKx_PRO 1162 // Longer LKx PRO / Alfawise Uxx Pro (PRO version)
#define BOARD_PXMALION_CORE_I3 1163 // Pxmalion Core I3 #define BOARD_ZRIB_V53 1163 // Zonestar zrib V5.3 (Chinese RAMPS replica)
#define BOARD_PXMALION_CORE_I3 1164 // Pxmalion Core I3
// PATCH START: Knutwurst // PATCH START: Knutwurst
#define BOARD_TRIGORILLA_CHIRON 1164 // TriGorilla Anycubic version 1.4 based on RAMPS EFB for Chiron #define BOARD_TRIGORILLA_CHIRON 1165 // TriGorilla Anycubic version 1.4 based on RAMPS EFB for Chiron
// PATCH END: Knutwurst // PATCH END: Knutwurst
// //
@@ -327,50 +328,53 @@
#define BOARD_MKS_ROBIN_E3D 4020 // MKS Robin E3D (STM32F103RC) #define BOARD_MKS_ROBIN_E3D 4020 // MKS Robin E3D (STM32F103RC)
#define BOARD_MKS_ROBIN_E3D_V1_1 4021 // MKS Robin E3D V1.1 (STM32F103RC) #define BOARD_MKS_ROBIN_E3D_V1_1 4021 // MKS Robin E3D V1.1 (STM32F103RC)
#define BOARD_MKS_ROBIN_E3P 4022 // MKS Robin E3p (STM32F103VE) #define BOARD_MKS_ROBIN_E3P 4022 // MKS Robin E3p (STM32F103VE)
#define BOARD_BTT_SKR_MINI_V1_1 4023 // BigTreeTech SKR Mini v1.1 (STM32F103RC) #define BOARD_BTT_EBB42_V1_1 4023 // BigTreeTech EBB42 V1.1 (STM32G0B1CB)
#define BOARD_BTT_SKR_MINI_E3_V1_0 4024 // BigTreeTech SKR Mini E3 (STM32F103RC) #define BOARD_BTT_SKR_MINI_V1_1 4024 // BigTreeTech SKR Mini v1.1 (STM32F103RC)
#define BOARD_BTT_SKR_MINI_E3_V1_2 4025 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC) #define BOARD_BTT_SKR_MINI_E3_V1_0 4025 // BigTreeTech SKR Mini E3 (STM32F103RC)
#define BOARD_BTT_SKR_MINI_E3_V2_0 4026 // BigTreeTech SKR Mini E3 V2.0 (STM32F103RC / STM32F103RE) #define BOARD_BTT_SKR_MINI_E3_V1_2 4026 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC)
#define BOARD_BTT_SKR_MINI_E3_V3_0 4027 // BigTreeTech SKR Mini E3 V3.0 (STM32G0B1RE) #define BOARD_BTT_SKR_MINI_E3_V2_0 4027 // BigTreeTech SKR Mini E3 V2.0 (STM32F103RC / STM32F103RE)
#define BOARD_BTT_SKR_MINI_MZ_V1_0 4028 // BigTreeTech SKR Mini MZ V1.0 (STM32F103RC) #define BOARD_BTT_SKR_MINI_E3_V3_0 4028 // BigTreeTech SKR Mini E3 V3.0 (STM32G0B1RE)
#define BOARD_BTT_SKR_E3_DIP 4029 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE) #define BOARD_BTT_SKR_MINI_E3_V3_0_1 4029 // BigTreeTech SKR Mini E3 V3.0.1 (STM32F401RC)
#define BOARD_BTT_SKR_CR6 4030 // BigTreeTech SKR CR6 v1.0 (STM32F103RE) #define BOARD_BTT_SKR_MINI_MZ_V1_0 4030 // BigTreeTech SKR Mini MZ V1.0 (STM32F103RC)
#define BOARD_JGAURORA_A5S_A1 4031 // JGAurora A5S A1 (STM32F103ZE) #define BOARD_BTT_SKR_E3_DIP 4031 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE)
#define BOARD_FYSETC_AIO_II 4032 // FYSETC AIO_II (STM32F103RC) #define BOARD_BTT_SKR_CR6 4032 // BigTreeTech SKR CR6 v1.0 (STM32F103RE)
#define BOARD_FYSETC_CHEETAH 4033 // FYSETC Cheetah (STM32F103RC) #define BOARD_JGAURORA_A5S_A1 4033 // JGAurora A5S A1 (STM32F103ZE)
#define BOARD_FYSETC_CHEETAH_V12 4034 // FYSETC Cheetah V1.2 (STM32F103RC) #define BOARD_FYSETC_AIO_II 4034 // FYSETC AIO_II (STM32F103RC)
#define BOARD_LONGER3D_LK 4035 // Longer3D LK1/2 - Alfawise U20/U20+/U30 (STM32F103VE) #define BOARD_FYSETC_CHEETAH 4035 // FYSETC Cheetah (STM32F103RC)
#define BOARD_CCROBOT_MEEB_3DP 4036 // ccrobot-online.com MEEB_3DP (STM32F103RC) #define BOARD_FYSETC_CHEETAH_V12 4036 // FYSETC Cheetah V1.2 (STM32F103RC)
#define BOARD_CHITU3D_V5 4037 // Chitu3D TronXY X5SA V5 Board (STM32F103ZE) #define BOARD_LONGER3D_LK 4037 // Longer3D LK1/2 - Alfawise U20/U20+/U30 (STM32F103VE)
#define BOARD_CHITU3D_V6 4038 // Chitu3D TronXY X5SA V6 Board (STM32F103ZE) #define BOARD_CCROBOT_MEEB_3DP 4038 // ccrobot-online.com MEEB_3DP (STM32F103RC)
#define BOARD_CHITU3D_V9 4039 // Chitu3D TronXY X5SA V9 Board (STM32F103ZE) #define BOARD_CHITU3D_V5 4039 // Chitu3D TronXY X5SA V5 Board (STM32F103ZE)
#define BOARD_CREALITY_V4 4040 // Creality v4.x (STM32F103RC / STM32F103RE) #define BOARD_CHITU3D_V6 4040 // Chitu3D TronXY X5SA V6 Board (STM32F103ZE)
#define BOARD_CREALITY_V422 4041 // Creality v4.2.2 (STM32F103RC / STM32F103RE) #define BOARD_CHITU3D_V9 4041 // Chitu3D TronXY X5SA V9 Board (STM32F103ZE)
#define BOARD_CREALITY_V423 4042 // Creality v4.2.3 (STM32F103RC / STM32F103RE) #define BOARD_CREALITY_V4 4042 // Creality v4.x (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V425 4043 // Creality v4.2.5 (STM32F103RC / STM32F103RE) #define BOARD_CREALITY_V422 4043 // Creality v4.2.2 (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V427 4044 // Creality v4.2.7 (STM32F103RC / STM32F103RE) #define BOARD_CREALITY_V423 4044 // Creality v4.2.3 (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V4210 4045 // Creality v4.2.10 (STM32F103RC / STM32F103RE) as found in the CR-30 #define BOARD_CREALITY_V425 4045 // Creality v4.2.5 (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V431 4046 // Creality v4.3.1 (STM32F103RC / STM32F103RE) #define BOARD_CREALITY_V427 4046 // Creality v4.2.7 (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V431_A 4047 // Creality v4.3.1a (STM32F103RC / STM32F103RE) #define BOARD_CREALITY_V4210 4047 // Creality v4.2.10 (STM32F103RC / STM32F103RE) as found in the CR-30
#define BOARD_CREALITY_V431_B 4048 // Creality v4.3.1b (STM32F103RC / STM32F103RE) #define BOARD_CREALITY_V431 4048 // Creality v4.3.1 (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V431_C 4049 // Creality v4.3.1c (STM32F103RC / STM32F103RE) #define BOARD_CREALITY_V431_A 4049 // Creality v4.3.1a (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V431_D 4050 // Creality v4.3.1d (STM32F103RC / STM32F103RE) #define BOARD_CREALITY_V431_B 4050 // Creality v4.3.1b (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V452 4051 // Creality v4.5.2 (STM32F103RC / STM32F103RE) #define BOARD_CREALITY_V431_C 4051 // Creality v4.3.1c (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V453 4052 // Creality v4.5.3 (STM32F103RC / STM32F103RE) #define BOARD_CREALITY_V431_D 4052 // Creality v4.3.1d (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V24S1 4053 // Creality v2.4.S1 (STM32F103RC / STM32F103RE) v101 as found in the Ender-7 #define BOARD_CREALITY_V452 4053 // Creality v4.5.2 (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V24S1_301 4054 // Creality v2.4.S1_301 (STM32F103RC / STM32F103RE) v301 as found in the Ender-3 S1 #define BOARD_CREALITY_V453 4054 // Creality v4.5.3 (STM32F103RC / STM32F103RE)
#define BOARD_CREALITY_V25S1 4055 // Creality v2.5.S1 (STM32F103RE) as found in the CR-10 Smart Pro #define BOARD_CREALITY_V521 4055 // Creality v5.2.1 (STM32F103VE) as found in the SV04
#define BOARD_TRIGORILLA_PRO 4056 // Trigorilla Pro (STM32F103ZE) #define BOARD_CREALITY_V24S1 4056 // Creality v2.4.S1 (STM32F103RC / STM32F103RE) v101 as found in the Ender-7
#define BOARD_FLY_MINI 4057 // FLYmaker FLY MINI (STM32F103RC) #define BOARD_CREALITY_V24S1_301 4057 // Creality v2.4.S1_301 (STM32F103RC / STM32F103RE) v301 as found in the Ender-3 S1
#define BOARD_FLSUN_HISPEED 4058 // FLSUN HiSpeedV1 (STM32F103VE) #define BOARD_CREALITY_V25S1 4058 // Creality v2.5.S1 (STM32F103RE) as found in the CR-10 Smart Pro
#define BOARD_BEAST 4059 // STM32F103RE Libmaple-based controller #define BOARD_TRIGORILLA_PRO 4059 // Trigorilla Pro (STM32F103ZE)
#define BOARD_MINGDA_MPX_ARM_MINI 4060 // STM32F103ZE Mingda MD-16 #define BOARD_FLY_MINI 4060 // FLYmaker FLY MINI (STM32F103RC)
#define BOARD_GTM32_PRO_VD 4061 // STM32F103VE controller #define BOARD_FLSUN_HISPEED 4061 // FLSUN HiSpeedV1 (STM32F103VE)
#define BOARD_ZONESTAR_ZM3E2 4062 // Zonestar ZM3E2 (STM32F103RC) #define BOARD_BEAST 4062 // STM32F103RE Libmaple-based controller
#define BOARD_ZONESTAR_ZM3E4 4063 // Zonestar ZM3E4 V1 (STM32F103VC) #define BOARD_MINGDA_MPX_ARM_MINI 4063 // STM32F103ZE Mingda MD-16
#define BOARD_ZONESTAR_ZM3E4V2 4064 // Zonestar ZM3E4 V2 (STM32F103VC) #define BOARD_GTM32_PRO_VD 4064 // STM32F103VE controller
#define BOARD_ERYONE_ERY32_MINI 4065 // Eryone Ery32 mini (STM32F103VE) #define BOARD_ZONESTAR_ZM3E2 4065 // Zonestar ZM3E2 (STM32F103RC)
#define BOARD_PANDA_PI_V29 4066 // Panda Pi V2.9 - Standalone (STM32F103RC) #define BOARD_ZONESTAR_ZM3E4 4066 // Zonestar ZM3E4 V1 (STM32F103VC)
#define BOARD_ZONESTAR_ZM3E4V2 4067 // Zonestar ZM3E4 V2 (STM32F103VC)
#define BOARD_ERYONE_ERY32_MINI 4068 // Eryone Ery32 mini (STM32F103VE)
#define BOARD_PANDA_PI_V29 4069 // Panda Pi V2.9 - Standalone (STM32F103RC)
// //
// ARM Cortex-M4F // ARM Cortex-M4F
@@ -424,6 +428,10 @@
#define BOARD_ARTILLERY_RUBY 4238 // Artillery Ruby (STM32F401RC) #define BOARD_ARTILLERY_RUBY 4238 // Artillery Ruby (STM32F401RC)
#define BOARD_FYSETC_SPIDER_V2_2 4239 // FYSETC Spider V2.2 (STM32F446VE) #define BOARD_FYSETC_SPIDER_V2_2 4239 // FYSETC Spider V2.2 (STM32F446VE)
#define BOARD_CREALITY_V24S1_301F4 4240 // Creality v2.4.S1_301F4 (STM32F401RC) as found in the Ender-3 S1 F4 #define BOARD_CREALITY_V24S1_301F4 4240 // Creality v2.4.S1_301F4 (STM32F401RC) as found in the Ender-3 S1 F4
#define BOARD_OPULO_LUMEN_REV4 4241 // Opulo Lumen PnP Controller REV4 (STM32F407VE / STM32F407VG)
#define BOARD_FYSETC_SPIDER_KING407 4242 // FYSETC Spider King407 (STM32F407ZG)
#define BOARD_MKS_SKIPR_V1 4243 // MKS SKIPR v1.0 all-in-one board (STM32F407VE)
#define BOARD_TRONXY_V10 4244 // TRONXY V10 (STM32F446ZE)
// //
// ARM Cortex M7 // ARM Cortex M7
@@ -461,6 +469,12 @@
#define BOARD_BRICOLEMON_V1_0 6101 // Bricolemon #define BOARD_BRICOLEMON_V1_0 6101 // Bricolemon
#define BOARD_BRICOLEMON_LITE_V1_0 6102 // Bricolemon Lite #define BOARD_BRICOLEMON_LITE_V1_0 6102 // Bricolemon Lite
//
// SAMD21 ARM Cortex M4
//
#define BOARD_MINITRONICS20 6103 // Minitronics v2.0
// //
// Custom board // Custom board
// //

View File

@@ -125,6 +125,8 @@
|| AXIS_DRIVER_TYPE(A,TMC2660) \ || AXIS_DRIVER_TYPE(A,TMC2660) \
|| AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) ) || AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) )
#define AXIS_IS_TMC_CONFIG(A) ( AXIS_IS_TMC(A) || AXIS_DRIVER_TYPE(A,TMC26X) )
// Test for a driver that uses SPI - this allows checking whether a _CS_ pin // Test for a driver that uses SPI - this allows checking whether a _CS_ pin
// is considered sensitive // is considered sensitive
#define AXIS_HAS_SPI(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ #define AXIS_HAS_SPI(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \

View File

@@ -174,6 +174,7 @@
#define STR_SD_VOL_INIT_FAIL "volume.init failed" #define STR_SD_VOL_INIT_FAIL "volume.init failed"
#define STR_SD_OPENROOT_FAIL "openRoot failed" #define STR_SD_OPENROOT_FAIL "openRoot failed"
#define STR_SD_CARD_OK "SD card ok" #define STR_SD_CARD_OK "SD card ok"
#define STR_SD_CARD_RELEASED "SD card released"
#define STR_SD_WORKDIR_FAIL "workDir open failed" #define STR_SD_WORKDIR_FAIL "workDir open failed"
#define STR_SD_OPEN_FILE_FAIL "open failed, File: " #define STR_SD_OPEN_FILE_FAIL "open failed, File: "
#define STR_SD_FILE_OPENED "File opened: " #define STR_SD_FILE_OPENED "File opened: "

View File

@@ -21,7 +21,7 @@
*/ */
#pragma once #pragma once
#if !defined(__has_include) #ifndef __has_include
#define __has_include(...) 1 #define __has_include(...) 1
#endif #endif
@@ -338,6 +338,12 @@
#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) #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 // Macros for initializing arrays
#define LIST_26(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
#define LIST_25(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y
#define LIST_24(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X
#define LIST_23(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W
#define LIST_22(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V
#define LIST_21(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U
#define LIST_20(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T #define LIST_20(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T
#define LIST_19(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S #define LIST_19(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S
#define LIST_18(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R #define LIST_18(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R
@@ -732,6 +738,7 @@
#define MAPLIST(OP,V...) EVAL(_MAPLIST(OP,V)) #define MAPLIST(OP,V...) EVAL(_MAPLIST(OP,V))
// Temperature Sensor Config // Temperature Sensor Config
#define _HAS_E_TEMP(N) || (TEMP_SENSOR_##N != 0) #define TEMP_SENSOR(N) TEMP_SENSOR_##N
#define _HAS_E_TEMP(N) || TEMP_SENSOR(N)
#define HAS_E_TEMP_SENSOR (0 REPEAT(EXTRUDERS, _HAS_E_TEMP)) #define HAS_E_TEMP_SENSOR (0 REPEAT(EXTRUDERS, _HAS_E_TEMP))
#define TEMP_SENSOR_IS_MAX_TC(T) (TEMP_SENSOR_##T == -5 || TEMP_SENSOR_##T == -3 || TEMP_SENSOR_##T == -2) #define TEMP_SENSOR_IS_MAX_TC(T) (TEMP_SENSOR(T) == -5 || TEMP_SENSOR(T) == -3 || TEMP_SENSOR(T) == -2)

View File

@@ -36,6 +36,8 @@ struct IF { typedef R type; };
template <class L, class R> template <class L, class R>
struct IF<true, L, R> { typedef L type; }; struct IF<true, L, R> { typedef L type; };
#define ALL_AXIS_NAMES X, X2, Y, Y2, Z, Z2, Z3, Z4, I, J, K, U, V, W, E0, E1, E2, E3, E4, E5, E6, E7
#define NUM_AXIS_GANG(V...) GANG_N(NUM_AXES, V) #define NUM_AXIS_GANG(V...) GANG_N(NUM_AXES, V)
#define NUM_AXIS_CODE(V...) CODE_N(NUM_AXES, V) #define NUM_AXIS_CODE(V...) CODE_N(NUM_AXES, V)
#define NUM_AXIS_LIST(V...) LIST_N(NUM_AXES, V) #define NUM_AXIS_LIST(V...) LIST_N(NUM_AXES, V)
@@ -99,8 +101,8 @@ struct Flags {
void set(const int n) { b |= (bits_t)_BV(n); } void set(const int n) { b |= (bits_t)_BV(n); }
void clear(const int n) { b &= ~(bits_t)_BV(n); } void clear(const int n) { b &= ~(bits_t)_BV(n); }
bool test(const int n) const { return TEST(b, n); } bool test(const int n) const { return TEST(b, n); }
const bool operator[](const int n) { return test(n); } bool operator[](const int n) { return test(n); }
const bool operator[](const int n) const { return test(n); } bool operator[](const int n) const { return test(n); }
int size() const { return sizeof(b); } int size() const { return sizeof(b); }
}; };
@@ -226,8 +228,8 @@ typedef const_float_t const_celsius_float_t;
// Helpers // Helpers
#define _RECIP(N) ((N) ? 1.0f / static_cast<float>(N) : 0.0f) #define _RECIP(N) ((N) ? 1.0f / static_cast<float>(N) : 0.0f)
#define _ABS(N) ((N) < 0 ? -(N) : (N)) #define _ABS(N) ((N) < 0 ? -(N) : (N))
#define _LS(N) (N = (T)(uint32_t(N) << v)) #define _LS(N) (N = (T)(uint32_t(N) << p))
#define _RS(N) (N = (T)(uint32_t(N) >> v)) #define _RS(N) (N = (T)(uint32_t(N) >> p))
#define FI FORCE_INLINE #define FI FORCE_INLINE
// Forward declarations // Forward declarations
@@ -307,9 +309,9 @@ typedef abce_float_t abce_pos_t;
void toLogical(xy_pos_t &raw); void toLogical(xy_pos_t &raw);
void toLogical(xyz_pos_t &raw); void toLogical(xyz_pos_t &raw);
void toLogical(xyze_pos_t &raw); void toLogical(xyze_pos_t &raw);
void toNative(xy_pos_t &raw); void toNative(xy_pos_t &lpos);
void toNative(xyz_pos_t &raw); void toNative(xyz_pos_t &lpos);
void toNative(xyze_pos_t &raw); void toNative(xyze_pos_t &lpos);
// //
// Paired XY coordinates, counters, flags, etc. // Paired XY coordinates, counters, flags, etc.
@@ -347,6 +349,10 @@ struct XYval {
FI operator T* () { return pos; } FI operator T* () { return pos; }
// If any element is true then it's true // If any element is true then it's true
FI operator bool() { return x || y; } FI operator bool() { return x || y; }
// Smallest element
FI T small() const { return _MIN(x, y); }
// Largest element
FI T large() const { return _MAX(x, y); }
// Explicit copy and copies with conversion // Explicit copy and copies with conversion
FI XYval<T> copy() const { return *this; } FI XYval<T> copy() const { return *this; }
@@ -405,18 +411,18 @@ struct XYval {
FI XYval<T> operator* (const XYZEval<T> &rs) { XYval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; } FI XYval<T> operator* (const XYZEval<T> &rs) { XYval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
FI XYval<T> operator/ (const XYZEval<T> &rs) const { XYval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } FI XYval<T> operator/ (const XYZEval<T> &rs) const { XYval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
FI XYval<T> operator/ (const XYZEval<T> &rs) { XYval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } FI XYval<T> operator/ (const XYZEval<T> &rs) { XYval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
FI XYval<T> operator* (const float &v) const { XYval<T> ls = *this; ls.x *= v; ls.y *= v; return ls; } FI XYval<T> operator* (const float &p) const { XYval<T> ls = *this; ls.x *= p; ls.y *= p; return ls; }
FI XYval<T> operator* (const float &v) { XYval<T> ls = *this; ls.x *= v; ls.y *= v; return ls; } FI XYval<T> operator* (const float &p) { XYval<T> ls = *this; ls.x *= p; ls.y *= p; return ls; }
FI XYval<T> operator* (const int &v) const { XYval<T> ls = *this; ls.x *= v; ls.y *= v; return ls; } FI XYval<T> operator* (const int &p) const { XYval<T> ls = *this; ls.x *= p; ls.y *= p; return ls; }
FI XYval<T> operator* (const int &v) { XYval<T> ls = *this; ls.x *= v; ls.y *= v; return ls; } FI XYval<T> operator* (const int &p) { XYval<T> ls = *this; ls.x *= p; ls.y *= p; return ls; }
FI XYval<T> operator/ (const float &v) const { XYval<T> ls = *this; ls.x /= v; ls.y /= v; return ls; } FI XYval<T> operator/ (const float &p) const { XYval<T> ls = *this; ls.x /= p; ls.y /= p; return ls; }
FI XYval<T> operator/ (const float &v) { XYval<T> ls = *this; ls.x /= v; ls.y /= v; return ls; } FI XYval<T> operator/ (const float &p) { XYval<T> ls = *this; ls.x /= p; ls.y /= p; return ls; }
FI XYval<T> operator/ (const int &v) const { XYval<T> ls = *this; ls.x /= v; ls.y /= v; return ls; } FI XYval<T> operator/ (const int &p) const { XYval<T> ls = *this; ls.x /= p; ls.y /= p; return ls; }
FI XYval<T> operator/ (const int &v) { XYval<T> ls = *this; ls.x /= v; ls.y /= v; return ls; } FI XYval<T> operator/ (const int &p) { XYval<T> ls = *this; ls.x /= p; ls.y /= p; return ls; }
FI XYval<T> operator>>(const int &v) const { XYval<T> ls = *this; _RS(ls.x); _RS(ls.y); return ls; } FI XYval<T> operator>>(const int &p) const { XYval<T> ls = *this; _RS(ls.x); _RS(ls.y); return ls; }
FI XYval<T> operator>>(const int &v) { XYval<T> ls = *this; _RS(ls.x); _RS(ls.y); return ls; } FI XYval<T> operator>>(const int &p) { XYval<T> ls = *this; _RS(ls.x); _RS(ls.y); return ls; }
FI XYval<T> operator<<(const int &v) const { XYval<T> ls = *this; _LS(ls.x); _LS(ls.y); return ls; } FI XYval<T> operator<<(const int &p) const { XYval<T> ls = *this; _LS(ls.x); _LS(ls.y); return ls; }
FI XYval<T> operator<<(const int &v) { XYval<T> ls = *this; _LS(ls.x); _LS(ls.y); return ls; } FI XYval<T> operator<<(const int &p) { XYval<T> ls = *this; _LS(ls.x); _LS(ls.y); return ls; }
FI const XYval<T> operator-() const { XYval<T> o = *this; o.x = -x; o.y = -y; return o; } FI const XYval<T> operator-() const { XYval<T> o = *this; o.x = -x; o.y = -y; return o; }
FI XYval<T> operator-() { XYval<T> o = *this; o.x = -x; o.y = -y; return o; } FI XYval<T> operator-() { XYval<T> o = *this; o.x = -x; o.y = -y; return o; }
@@ -430,21 +436,15 @@ struct XYval {
FI XYval<T>& operator+=(const XYZEval<T> &rs) { x += rs.x; y += rs.y; return *this; } FI XYval<T>& operator+=(const XYZEval<T> &rs) { x += rs.x; y += rs.y; return *this; }
FI XYval<T>& operator-=(const XYZEval<T> &rs) { x -= rs.x; y -= rs.y; return *this; } FI XYval<T>& operator-=(const XYZEval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
FI XYval<T>& operator*=(const XYZEval<T> &rs) { x *= rs.x; y *= rs.y; return *this; } FI XYval<T>& operator*=(const XYZEval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
FI XYval<T>& operator*=(const float &v) { x *= v; y *= v; return *this; } FI XYval<T>& operator*=(const float &p) { x *= p; y *= p; return *this; }
FI XYval<T>& operator*=(const int &v) { x *= v; y *= v; return *this; } FI XYval<T>& operator*=(const int &p) { x *= p; y *= p; return *this; }
FI XYval<T>& operator>>=(const int &v) { _RS(x); _RS(y); return *this; } FI XYval<T>& operator>>=(const int &p) { _RS(x); _RS(y); return *this; }
FI XYval<T>& operator<<=(const int &v) { _LS(x); _LS(y); return *this; } FI XYval<T>& operator<<=(const int &p) { _LS(x); _LS(y); return *this; }
// Exact comparisons. For floats a "NEAR" operation may be better. // Exact comparisons. For floats a "NEAR" operation may be better.
FI bool operator==(const XYval<T> &rs) { return x == rs.x && y == rs.y; }
FI bool operator==(const XYZval<T> &rs) { return x == rs.x && y == rs.y; }
FI bool operator==(const XYZEval<T> &rs) { return x == rs.x && y == rs.y; }
FI bool operator==(const XYval<T> &rs) const { return x == rs.x && y == rs.y; } FI bool operator==(const XYval<T> &rs) const { return x == rs.x && y == rs.y; }
FI bool operator==(const XYZval<T> &rs) const { return x == rs.x && y == rs.y; } FI bool operator==(const XYZval<T> &rs) const { return x == rs.x && y == rs.y; }
FI bool operator==(const XYZEval<T> &rs) const { return x == rs.x && y == rs.y; } FI bool operator==(const XYZEval<T> &rs) const { return x == rs.x && y == rs.y; }
FI bool operator!=(const XYval<T> &rs) { return !operator==(rs); }
FI bool operator!=(const XYZval<T> &rs) { return !operator==(rs); }
FI bool operator!=(const XYZEval<T> &rs) { return !operator==(rs); }
FI bool operator!=(const XYval<T> &rs) const { return !operator==(rs); } FI bool operator!=(const XYval<T> &rs) const { return !operator==(rs); }
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); } FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); } FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
@@ -494,10 +494,10 @@ struct XYZval {
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; } FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; }
#endif #endif
#if HAS_V_AXIS #if HAS_V_AXIS
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pm) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; } FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pu) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; }
#endif #endif
#if HAS_W_AXIS #if HAS_W_AXIS
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pm, const T po) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; v = pv; } FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pu, const T pv) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; v = pv; }
#endif #endif
// Length reduced to one dimension // Length reduced to one dimension
@@ -506,6 +506,10 @@ struct XYZval {
FI operator T* () { return pos; } FI operator T* () { return pos; }
// If any element is true then it's true // If any element is true then it's true
FI operator bool() { return NUM_AXIS_GANG(x, || y, || z, || i, || j, || k, || u, || v, || w); } FI operator bool() { return NUM_AXIS_GANG(x, || y, || z, || i, || j, || k, || u, || v, || w); }
// Smallest element
FI T small() const { return _MIN(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)); }
// Largest element
FI T large() const { return _MAX(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)); }
// Explicit copy and copies with conversion // Explicit copy and copies with conversion
FI XYZval<T> copy() const { XYZval<T> o = *this; return o; } FI XYZval<T> copy() const { XYZval<T> o = *this; return o; }
@@ -565,18 +569,18 @@ struct XYZval {
FI XYZval<T> operator* (const XYZEval<T> &rs) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k, ls.u *= rs.u, ls.v *= rs.v, ls.w *= rs.w); return ls; } FI XYZval<T> operator* (const XYZEval<T> &rs) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k, ls.u *= rs.u, ls.v *= rs.v, ls.w *= rs.w); return ls; }
FI XYZval<T> operator/ (const XYZEval<T> &rs) const { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k, ls.u /= rs.u, ls.v /= rs.v, ls.w /= rs.w); return ls; } FI XYZval<T> operator/ (const XYZEval<T> &rs) const { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k, ls.u /= rs.u, ls.v /= rs.v, ls.w /= rs.w); return ls; }
FI XYZval<T> operator/ (const XYZEval<T> &rs) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k, ls.u /= rs.u, ls.v /= rs.v, ls.w /= rs.w); return ls; } FI XYZval<T> operator/ (const XYZEval<T> &rs) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k, ls.u /= rs.u, ls.v /= rs.v, ls.w /= rs.w); return ls; }
FI XYZval<T> operator* (const float &v) const { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v, ls.u *= v, ls.v *= v, ls.w *= v ); return ls; } FI XYZval<T> operator* (const float &p) const { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x *= p, ls.y *= p, ls.z *= p, ls.i *= p, ls.j *= p, ls.k *= p, ls.u *= p, ls.v *= p, ls.w *= p ); return ls; }
FI XYZval<T> operator* (const float &v) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v, ls.u *= v, ls.v *= v, ls.w *= v ); return ls; } FI XYZval<T> operator* (const float &p) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x *= p, ls.y *= p, ls.z *= p, ls.i *= p, ls.j *= p, ls.k *= p, ls.u *= p, ls.v *= p, ls.w *= p ); return ls; }
FI XYZval<T> operator* (const int &v) const { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v, ls.u *= v, ls.v *= v, ls.w *= v ); return ls; } FI XYZval<T> operator* (const int &p) const { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x *= p, ls.y *= p, ls.z *= p, ls.i *= p, ls.j *= p, ls.k *= p, ls.u *= p, ls.v *= p, ls.w *= p ); return ls; }
FI XYZval<T> operator* (const int &v) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v, ls.u *= v, ls.v *= v, ls.w *= v ); return ls; } FI XYZval<T> operator* (const int &p) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x *= p, ls.y *= p, ls.z *= p, ls.i *= p, ls.j *= p, ls.k *= p, ls.u *= p, ls.v *= p, ls.w *= p ); return ls; }
FI XYZval<T> operator/ (const float &v) const { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v, ls.u /= v, ls.v /= v, ls.w /= v ); return ls; } FI XYZval<T> operator/ (const float &p) const { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= p, ls.y /= p, ls.z /= p, ls.i /= p, ls.j /= p, ls.k /= p, ls.u /= p, ls.v /= p, ls.w /= p ); return ls; }
FI XYZval<T> operator/ (const float &v) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v, ls.u /= v, ls.v /= v, ls.w /= v ); return ls; } FI XYZval<T> operator/ (const float &p) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= p, ls.y /= p, ls.z /= p, ls.i /= p, ls.j /= p, ls.k /= p, ls.u /= p, ls.v /= p, ls.w /= p ); return ls; }
FI XYZval<T> operator/ (const int &v) const { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v, ls.u /= v, ls.v /= v, ls.w /= v ); return ls; } FI XYZval<T> operator/ (const int &p) const { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= p, ls.y /= p, ls.z /= p, ls.i /= p, ls.j /= p, ls.k /= p, ls.u /= p, ls.v /= p, ls.w /= p ); return ls; }
FI XYZval<T> operator/ (const int &v) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v, ls.u /= v, ls.v /= v, ls.w /= v ); return ls; } FI XYZval<T> operator/ (const int &p) { XYZval<T> ls = *this; NUM_AXIS_CODE(ls.x /= p, ls.y /= p, ls.z /= p, ls.i /= p, ls.j /= p, ls.k /= p, ls.u /= p, ls.v /= p, ls.w /= p ); return ls; }
FI XYZval<T> operator>>(const int &v) const { XYZval<T> ls = *this; NUM_AXIS_CODE(_RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k), _RS(ls.u), _RS(ls.v), _RS(ls.w) ); return ls; } FI XYZval<T> operator>>(const int &p) const { XYZval<T> ls = *this; NUM_AXIS_CODE(_RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k), _RS(ls.u), _RS(ls.v), _RS(ls.w) ); return ls; }
FI XYZval<T> operator>>(const int &v) { XYZval<T> ls = *this; NUM_AXIS_CODE(_RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k), _RS(ls.u), _RS(ls.v), _RS(ls.w) ); return ls; } FI XYZval<T> operator>>(const int &p) { XYZval<T> ls = *this; NUM_AXIS_CODE(_RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k), _RS(ls.u), _RS(ls.v), _RS(ls.w) ); return ls; }
FI XYZval<T> operator<<(const int &v) const { XYZval<T> ls = *this; NUM_AXIS_CODE(_LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k), _LS(ls.u), _LS(ls.v), _LS(ls.w) ); return ls; } FI XYZval<T> operator<<(const int &p) const { XYZval<T> ls = *this; NUM_AXIS_CODE(_LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k), _LS(ls.u), _LS(ls.v), _LS(ls.w) ); return ls; }
FI XYZval<T> operator<<(const int &v) { XYZval<T> ls = *this; NUM_AXIS_CODE(_LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k), _LS(ls.u), _LS(ls.v), _LS(ls.w) ); return ls; } FI XYZval<T> operator<<(const int &p) { XYZval<T> ls = *this; NUM_AXIS_CODE(_LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k), _LS(ls.u), _LS(ls.v), _LS(ls.w) ); return ls; }
FI const XYZval<T> operator-() const { XYZval<T> o = *this; NUM_AXIS_CODE(o.x = -x, o.y = -y, o.z = -z, o.i = -i, o.j = -j, o.k = -k, o.u = -u, o.v = -v, o.w = -w); return o; } FI const XYZval<T> operator-() const { XYZval<T> o = *this; NUM_AXIS_CODE(o.x = -x, o.y = -y, o.z = -z, o.i = -i, o.j = -j, o.k = -k, o.u = -u, o.v = -v, o.w = -w); return o; }
FI XYZval<T> operator-() { XYZval<T> o = *this; NUM_AXIS_CODE(o.x = -x, o.y = -y, o.z = -z, o.i = -i, o.j = -j, o.k = -k, o.u = -u, o.v = -v, o.w = -w); return o; } FI XYZval<T> operator-() { XYZval<T> o = *this; NUM_AXIS_CODE(o.x = -x, o.y = -y, o.z = -z, o.i = -i, o.j = -j, o.k = -k, o.u = -u, o.v = -v, o.w = -w); return o; }
@@ -593,15 +597,13 @@ struct XYZval {
FI XYZval<T>& operator-=(const XYZEval<T> &rs) { NUM_AXIS_CODE(x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k, u -= rs.u, v -= rs.v, w -= rs.w); return *this; } FI XYZval<T>& operator-=(const XYZEval<T> &rs) { NUM_AXIS_CODE(x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k, u -= rs.u, v -= rs.v, w -= rs.w); return *this; }
FI XYZval<T>& operator*=(const XYZEval<T> &rs) { NUM_AXIS_CODE(x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k, u *= rs.u, v *= rs.v, w *= rs.w); return *this; } FI XYZval<T>& operator*=(const XYZEval<T> &rs) { NUM_AXIS_CODE(x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k, u *= rs.u, v *= rs.v, w *= rs.w); return *this; }
FI XYZval<T>& operator/=(const XYZEval<T> &rs) { NUM_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k, u /= rs.u, v /= rs.v, w /= rs.w); return *this; } FI XYZval<T>& operator/=(const XYZEval<T> &rs) { NUM_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k, u /= rs.u, v /= rs.v, w /= rs.w); return *this; }
FI XYZval<T>& operator*=(const float &v) { NUM_AXIS_CODE(x *= v, y *= v, z *= v, i *= v, j *= v, k *= v, u *= v, v *= v, w *= v); return *this; } FI XYZval<T>& operator*=(const float &p) { NUM_AXIS_CODE(x *= p, y *= p, z *= p, i *= p, j *= p, k *= p, u *= p, v *= p, w *= p); return *this; }
FI XYZval<T>& operator*=(const int &v) { NUM_AXIS_CODE(x *= v, y *= v, z *= v, i *= v, j *= v, k *= v, u *= v, v *= v, w *= v); return *this; } FI XYZval<T>& operator*=(const int &p) { NUM_AXIS_CODE(x *= p, y *= p, z *= p, i *= p, j *= p, k *= p, u *= p, v *= p, w *= p); return *this; }
FI XYZval<T>& operator>>=(const int &v) { NUM_AXIS_CODE(_RS(x), _RS(y), _RS(z), _RS(i), _RS(j), _RS(k), _RS(u), _RS(v), _RS(w)); return *this; } FI XYZval<T>& operator>>=(const int &p) { NUM_AXIS_CODE(_RS(x), _RS(y), _RS(z), _RS(i), _RS(j), _RS(k), _RS(u), _RS(v), _RS(w)); return *this; }
FI XYZval<T>& operator<<=(const int &v) { NUM_AXIS_CODE(_LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k), _LS(u), _LS(v), _LS(w)); return *this; } FI XYZval<T>& operator<<=(const int &p) { NUM_AXIS_CODE(_LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k), _LS(u), _LS(v), _LS(w)); return *this; }
// Exact comparisons. For floats a "NEAR" operation may be better. // Exact comparisons. For floats a "NEAR" operation may be better.
FI bool operator==(const XYZEval<T> &rs) { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
FI bool operator==(const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); } FI bool operator==(const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
FI bool operator!=(const XYZEval<T> &rs) { return !operator==(rs); }
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); } FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
}; };
@@ -634,10 +636,10 @@ struct XYZEval {
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; } FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; }
#endif #endif
#if HAS_V_AXIS #if HAS_V_AXIS
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pm) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; } FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pu) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; }
#endif #endif
#if HAS_W_AXIS #if HAS_W_AXIS
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pm, const T po) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pm; v = pv; } FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pu, const T pv) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; v = pv; }
#endif #endif
// Setters taking struct types and arrays // Setters taking struct types and arrays
@@ -659,6 +661,10 @@ struct XYZEval {
FI operator T* () { return pos; } FI operator T* () { return pos; }
// If any element is true then it's true // If any element is true then it's true
FI operator bool() { return 0 LOGICAL_AXIS_GANG(|| e, || x, || y, || z, || i, || j, || k, || u, || v, || w); } FI operator bool() { return 0 LOGICAL_AXIS_GANG(|| e, || x, || y, || z, || i, || j, || k, || u, || v, || w); }
// Smallest element
FI T small() const { return _MIN(LOGICAL_AXIS_LIST(e, x, y, z, i, j, k, u, v, w)); }
// Largest element
FI T large() const { return _MAX(LOGICAL_AXIS_LIST(e, x, y, z, i, j, k, u, v, w)); }
// Explicit copy and copies with conversion // Explicit copy and copies with conversion
FI XYZEval<T> copy() const { XYZEval<T> v = *this; return v; } FI XYZEval<T> copy() const { XYZEval<T> v = *this; return v; }
@@ -717,18 +723,18 @@ struct XYZEval {
FI XYZEval<T> operator* (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= rs.e, ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k, ls.u *= rs.u, ls.v *= rs.v, ls.w *= rs.w); return ls; } FI XYZEval<T> operator* (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= rs.e, ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k, ls.u *= rs.u, ls.v *= rs.v, ls.w *= rs.w); return ls; }
FI XYZEval<T> operator/ (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= rs.e, ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k, ls.u /= rs.u, ls.v /= rs.v, ls.w /= rs.w); return ls; } FI XYZEval<T> operator/ (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= rs.e, ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k, ls.u /= rs.u, ls.v /= rs.v, ls.w /= rs.w); return ls; }
FI XYZEval<T> operator/ (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= rs.e, ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k, ls.u /= rs.u, ls.v /= rs.v, ls.w /= rs.w); return ls; } FI XYZEval<T> operator/ (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= rs.e, ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k, ls.u /= rs.u, ls.v /= rs.v, ls.w /= rs.w); return ls; }
FI XYZEval<T> operator* (const float &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v, ls.u *= v, ls.v *= v, ls.w *= v ); return ls; } FI XYZEval<T> operator* (const float &p) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= p, ls.x *= p, ls.y *= p, ls.z *= p, ls.i *= p, ls.j *= p, ls.k *= p, ls.u *= p, ls.v *= p, ls.w *= p ); return ls; }
FI XYZEval<T> operator* (const float &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v, ls.u *= v, ls.v *= v, ls.w *= v ); return ls; } FI XYZEval<T> operator* (const float &p) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= p, ls.x *= p, ls.y *= p, ls.z *= p, ls.i *= p, ls.j *= p, ls.k *= p, ls.u *= p, ls.v *= p, ls.w *= p ); return ls; }
FI XYZEval<T> operator* (const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v, ls.u *= v, ls.v *= v, ls.w *= v ); return ls; } FI XYZEval<T> operator* (const int &p) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= p, ls.x *= p, ls.y *= p, ls.z *= p, ls.i *= p, ls.j *= p, ls.k *= p, ls.u *= p, ls.v *= p, ls.w *= p ); return ls; }
FI XYZEval<T> operator* (const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v, ls.u *= v, ls.v *= v, ls.w *= v ); return ls; } FI XYZEval<T> operator* (const int &p) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= p, ls.x *= p, ls.y *= p, ls.z *= p, ls.i *= p, ls.j *= p, ls.k *= p, ls.u *= p, ls.v *= p, ls.w *= p ); return ls; }
FI XYZEval<T> operator/ (const float &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v, ls.u /= v, ls.v /= v, ls.w /= v ); return ls; } FI XYZEval<T> operator/ (const float &p) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= p, ls.x /= p, ls.y /= p, ls.z /= p, ls.i /= p, ls.j /= p, ls.k /= p, ls.u /= p, ls.v /= p, ls.w /= p ); return ls; }
FI XYZEval<T> operator/ (const float &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v, ls.u /= v, ls.v /= v, ls.w /= v ); return ls; } FI XYZEval<T> operator/ (const float &p) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= p, ls.x /= p, ls.y /= p, ls.z /= p, ls.i /= p, ls.j /= p, ls.k /= p, ls.u /= p, ls.v /= p, ls.w /= p ); return ls; }
FI XYZEval<T> operator/ (const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v, ls.u /= v, ls.v /= v, ls.w /= v ); return ls; } FI XYZEval<T> operator/ (const int &p) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= p, ls.x /= p, ls.y /= p, ls.z /= p, ls.i /= p, ls.j /= p, ls.k /= p, ls.u /= p, ls.v /= p, ls.w /= p ); return ls; }
FI XYZEval<T> operator/ (const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v, ls.u /= v, ls.v /= v, ls.w /= v ); return ls; } FI XYZEval<T> operator/ (const int &p) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= p, ls.x /= p, ls.y /= p, ls.z /= p, ls.i /= p, ls.j /= p, ls.k /= p, ls.u /= p, ls.v /= p, ls.w /= p ); return ls; }
FI XYZEval<T> operator>>(const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_RS(ls.e), _RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k), _RS(ls.u), _RS(ls.v), _RS(ls.w) ); return ls; } FI XYZEval<T> operator>>(const int &p) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_RS(ls.e), _RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k), _RS(ls.u), _RS(ls.v), _RS(ls.w) ); return ls; }
FI XYZEval<T> operator>>(const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_RS(ls.e), _RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k), _RS(ls.u), _RS(ls.v), _RS(ls.w) ); return ls; } FI XYZEval<T> operator>>(const int &p) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_RS(ls.e), _RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k), _RS(ls.u), _RS(ls.v), _RS(ls.w) ); return ls; }
FI XYZEval<T> operator<<(const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_LS(ls.e), _LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k), _LS(ls.u), _LS(ls.v), _LS(ls.w) ); return ls; } FI XYZEval<T> operator<<(const int &p) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_LS(ls.e), _LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k), _LS(ls.u), _LS(ls.v), _LS(ls.w) ); return ls; }
FI XYZEval<T> operator<<(const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_LS(ls.e), _LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k), _LS(ls.u), _LS(ls.v), _LS(ls.w) ); return ls; } FI XYZEval<T> operator<<(const int &p) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_LS(ls.e), _LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k), _LS(ls.u), _LS(ls.v), _LS(ls.w) ); return ls; }
FI const XYZEval<T> operator-() const { return LOGICAL_AXIS_ARRAY(-e, -x, -y, -z, -i, -j, -k, -u, -v, -w); } FI const XYZEval<T> operator-() const { return LOGICAL_AXIS_ARRAY(-e, -x, -y, -z, -i, -j, -k, -u, -v, -w); }
FI XYZEval<T> operator-() { return LOGICAL_AXIS_ARRAY(-e, -x, -y, -z, -i, -j, -k, -u, -v, -w); } FI XYZEval<T> operator-() { return LOGICAL_AXIS_ARRAY(-e, -x, -y, -z, -i, -j, -k, -u, -v, -w); }
@@ -745,15 +751,15 @@ struct XYZEval {
FI XYZEval<T>& operator-=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e -= rs.e, x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k, u -= rs.u, v -= rs.v, w -= rs.w); return *this; } FI XYZEval<T>& operator-=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e -= rs.e, x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k, u -= rs.u, v -= rs.v, w -= rs.w); return *this; }
FI XYZEval<T>& operator*=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e *= rs.e, x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k, u *= rs.u, v *= rs.v, w *= rs.w); return *this; } FI XYZEval<T>& operator*=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e *= rs.e, x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k, u *= rs.u, v *= rs.v, w *= rs.w); return *this; }
FI XYZEval<T>& operator/=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e /= rs.e, x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k, u /= rs.u, v /= rs.v, w /= rs.w); return *this; } FI XYZEval<T>& operator/=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e /= rs.e, x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k, u /= rs.u, v /= rs.v, w /= rs.w); return *this; }
FI XYZEval<T>& operator*=(const T &v) { LOGICAL_AXIS_CODE(e *= v, x *= v, y *= v, z *= v, i *= v, j *= v, k *= v, u *= v, v *= v, w *= v); return *this; } FI XYZEval<T>& operator*=(const T &p) { LOGICAL_AXIS_CODE(e *= p, x *= p, y *= p, z *= p, i *= p, j *= p, k *= p, u *= p, v *= p, w *= p); return *this; }
FI XYZEval<T>& operator>>=(const int &v) { LOGICAL_AXIS_CODE(_RS(e), _RS(x), _RS(y), _RS(z), _RS(i), _RS(j), _RS(k), _RS(u), _RS(v), _RS(w)); return *this; } FI XYZEval<T>& operator>>=(const int &p) { LOGICAL_AXIS_CODE(_RS(e), _RS(x), _RS(y), _RS(z), _RS(i), _RS(j), _RS(k), _RS(u), _RS(v), _RS(w)); return *this; }
FI XYZEval<T>& operator<<=(const int &v) { LOGICAL_AXIS_CODE(_LS(e), _LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k), _LS(u), _LS(v), _LS(w)); return *this; } FI XYZEval<T>& operator<<=(const int &p) { LOGICAL_AXIS_CODE(_LS(e), _LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k), _LS(u), _LS(v), _LS(w)); return *this; }
// Exact comparisons. For floats a "NEAR" operation may be better. // Exact comparisons. For floats a "NEAR" operation may be better.
FI bool operator==(const XYZval<T> &rs) { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
FI bool operator==(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); } FI bool operator==(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
FI bool operator!=(const XYZval<T> &rs) { return !operator==(rs); } FI bool operator==(const XYZEval<T> &rs) const { return true LOGICAL_AXIS_GANG(&& e == rs.e, && x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); } FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
}; };
#undef _RECIP #undef _RECIP

View File

@@ -96,6 +96,7 @@ void BDS_Leveling::process() {
const float z_sensor = (tmp & 0x3FF) / 100.0f; const float z_sensor = (tmp & 0x3FF) / 100.0f;
if (cur_z < 0) config_state = 0; if (cur_z < 0) config_state = 0;
//float abs_z = current_position.z > cur_z ? (current_position.z - cur_z) : (cur_z - current_position.z); //float abs_z = current_position.z > cur_z ? (current_position.z - cur_z) : (cur_z - current_position.z);
#if ENABLED(BABYSTEPPING)
if (cur_z < config_state * 0.1f if (cur_z < config_state * 0.1f
&& config_state > 0 && config_state > 0
&& old_cur_z == cur_z && old_cur_z == cur_z
@@ -108,10 +109,10 @@ void BDS_Leveling::process() {
#endif #endif
} }
else { else {
babystep.set_mm(Z_AXIS, 0); babystep.set_mm(Z_AXIS, 0); //if (old_cur_z <= cur_z) Z_DIR_WRITE(!INVERT_Z_DIR);
//if (old_cur_z <= cur_z) Z_DIR_WRITE(!INVERT_Z_DIR);
stepper.set_directions(); stepper.set_directions();
} }
#endif
old_cur_z = cur_z; old_cur_z = cur_z;
old_buf_z = current_position.z; old_buf_z = current_position.z;
endstops.bdp_state_update(z_sensor <= 0.01f); endstops.bdp_state_update(z_sensor <= 0.01f);

View File

@@ -57,6 +57,7 @@ bool leveling_is_valid() {
* Enable: Current position = "unleveled" physical position * Enable: Current position = "unleveled" physical position
*/ */
void set_bed_leveling_enabled(const bool enable/*=true*/) { void set_bed_leveling_enabled(const bool enable/*=true*/) {
DEBUG_SECTION(log_sble, "set_bed_leveling_enabled", DEBUGGING(LEVELING));
const bool can_change = TERN1(AUTO_BED_LEVELING_BILINEAR, !enable || leveling_is_valid()); const bool can_change = TERN1(AUTO_BED_LEVELING_BILINEAR, !enable || leveling_is_valid());
@@ -75,9 +76,9 @@ void set_bed_leveling_enabled(const bool enable/*=true*/) {
planner.synchronize(); planner.synchronize();
// Get the corrected leveled / unleveled position // Get the corrected leveled / unleveled position
planner.apply_modifiers(current_position); // Physical position with all modifiers planner.apply_modifiers(current_position, true); // Physical position with all modifiers
planner.leveling_active ^= true; // Toggle leveling between apply and unapply planner.leveling_active ^= true; // Toggle leveling between apply and unapply
planner.unapply_modifiers(current_position); // Logical position with modifiers removed planner.unapply_modifiers(current_position, true); // Logical position with modifiers removed
sync_plan_position(); sync_plan_position();
_report_leveling(); _report_leveling();

View File

@@ -260,7 +260,7 @@ bool unified_bed_leveling::sanity_check() {
*/ */
void GcodeSuite::M1004() { void GcodeSuite::M1004() {
#define ALIGN_GCODE TERN(Z_STEPPER_AUTO_ALIGN, "G34", "") #define ALIGN_GCODE TERN(Z_STEPPER_AUTO_ALIGN, "G34\n", "")
#define PROBE_GCODE TERN(HAS_BED_PROBE, "G29P1\nG29P3", "G29P4R") #define PROBE_GCODE TERN(HAS_BED_PROBE, "G29P1\nG29P3", "G29P4R")
#if HAS_HOTEND #if HAS_HOTEND
@@ -280,7 +280,7 @@ bool unified_bed_leveling::sanity_check() {
#endif #endif
process_subcommands_now(FPSTR(G28_STR)); // Home process_subcommands_now(FPSTR(G28_STR)); // Home
process_subcommands_now(F(ALIGN_GCODE "\n" // Align multi z axis if available process_subcommands_now(F(ALIGN_GCODE // Align multi z axis if available
PROBE_GCODE "\n" // Build mesh with available hardware PROBE_GCODE "\n" // Build mesh with available hardware
"G29P3\nG29P3")); // Ensure mesh is complete by running smart fill twice "G29P3\nG29P3")); // Ensure mesh is complete by running smart fill twice

View File

@@ -407,7 +407,7 @@ void unified_bed_leveling::G29() {
z_values[x][x2] += 9.999f; // We want the altered line several mesh points thick z_values[x][x2] += 9.999f; // We want the altered line several mesh points thick
#if ENABLED(EXTENSIBLE_UI) #if ENABLED(EXTENSIBLE_UI)
ExtUI::onMeshUpdate(x, x, z_values[x][x]); ExtUI::onMeshUpdate(x, x, z_values[x][x]);
ExtUI::onMeshUpdate(x, (x2), z_values[x][x2]); ExtUI::onMeshUpdate(x, x2, z_values[x][x2]);
#endif #endif
} }
break; break;

View File

@@ -336,9 +336,9 @@
#if IS_SCARA #if IS_SCARA
#define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm #define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
#elif ENABLED(DELTA) #elif ENABLED(DELTA)
#define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND) #define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DEFAULT_SEGMENTS_PER_SECOND)
#elif ENABLED(POLARGRAPH) #elif ENABLED(POLARGRAPH)
#define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND) #define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DEFAULT_SEGMENTS_PER_SECOND)
#else // CARTESIAN #else // CARTESIAN
#ifdef LEVELED_SEGMENT_LENGTH #ifdef LEVELED_SEGMENT_LENGTH
#define DELTA_SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH #define DELTA_SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH
@@ -423,10 +423,12 @@
LIMIT(icell.x, 0, GRID_MAX_CELLS_X); LIMIT(icell.x, 0, GRID_MAX_CELLS_X);
LIMIT(icell.y, 0, GRID_MAX_CELLS_Y); LIMIT(icell.y, 0, GRID_MAX_CELLS_Y);
const int8_t ncellx = _MIN(icell.x+1, GRID_MAX_CELLS_X),
ncelly = _MIN(icell.y+1, GRID_MAX_CELLS_Y);
float z_x0y0 = z_values[icell.x][icell.y], // z at lower left corner float z_x0y0 = z_values[icell.x][icell.y], // z at lower left corner
z_x1y0 = z_values[icell.x+1][icell.y ], // z at upper left corner z_x1y0 = z_values[ncellx ][icell.y], // z at upper left corner
z_x0y1 = z_values[icell.x ][icell.y+1], // z at lower right corner z_x0y1 = z_values[icell.x][ncelly ], // z at lower right corner
z_x1y1 = z_values[icell.x+1][icell.y+1]; // z at upper right corner z_x1y1 = z_values[ncellx ][ncelly ]; // z at upper right corner
if (isnan(z_x0y0)) z_x0y0 = 0; // ideally activating planner.leveling_active (G29 A) if (isnan(z_x0y0)) z_x0y0 = 0; // ideally activating planner.leveling_active (G29 A)
if (isnan(z_x1y0)) z_x1y0 = 0; // should refuse if any invalid mesh points if (isnan(z_x1y0)) z_x1y0 = 0; // should refuse if any invalid mesh points

View File

@@ -38,8 +38,6 @@ bool BLTouch::od_5v_mode; // Initialized by settings.load, 0 = Open Drai
#include "../module/servo.h" #include "../module/servo.h"
#include "../module/probe.h" #include "../module/probe.h"
void stop();
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../core/debug_out.h" #include "../core/debug_out.h"

View File

@@ -40,6 +40,9 @@ uint8_t ControllerFan::speed;
void ControllerFan::setup() { void ControllerFan::setup() {
SET_OUTPUT(CONTROLLER_FAN_PIN); SET_OUTPUT(CONTROLLER_FAN_PIN);
#ifdef CONTROLLER_FAN2_PIN
SET_OUTPUT(CONTROLLER_FAN2_PIN);
#endif
init(); init();
} }
@@ -72,6 +75,22 @@ void ControllerFan::update() {
? settings.active_speed : settings.idle_speed ? settings.active_speed : settings.idle_speed
); );
speed = CALC_FAN_SPEED(speed);
#if FAN_KICKSTART_TIME
static millis_t fan_kick_end = 0;
if (speed > FAN_OFF_PWM) {
if (!fan_kick_end) {
fan_kick_end = ms + FAN_KICKSTART_TIME; // May be longer based on slow update interval for controller fn check. Sets minimum
speed = FAN_KICKSTART_POWER;
}
else if (PENDING(ms, fan_kick_end))
speed = FAN_KICKSTART_POWER;
}
else
fan_kick_end = 0;
#endif
#if ENABLED(FAN_SOFT_PWM) #if ENABLED(FAN_SOFT_PWM)
thermalManager.soft_pwm_controller_speed = speed; thermalManager.soft_pwm_controller_speed = speed;
#else #else
@@ -79,6 +98,13 @@ void ControllerFan::update() {
hal.set_pwm_duty(pin_t(CONTROLLER_FAN_PIN), speed); hal.set_pwm_duty(pin_t(CONTROLLER_FAN_PIN), speed);
else else
WRITE(CONTROLLER_FAN_PIN, speed > 0); WRITE(CONTROLLER_FAN_PIN, speed > 0);
#ifdef CONTROLLER_FAN2_PIN
if (PWM_PIN(CONTROLLER_FAN2_PIN))
hal.set_pwm_duty(pin_t(CONTROLLER_FAN2_PIN), speed);
else
WRITE(CONTROLLER_FAN2_PIN, speed > 0);
#endif
#endif #endif
} }
} }

View File

@@ -33,6 +33,9 @@
// Static data members // Static data members
bool EmergencyParser::killed_by_M112, // = false bool EmergencyParser::killed_by_M112, // = false
EmergencyParser::quickstop_by_M410, EmergencyParser::quickstop_by_M410,
#if ENABLED(SDSUPPORT)
EmergencyParser::sd_abort_by_M524,
#endif
EmergencyParser::enabled; EmergencyParser::enabled;
#if ENABLED(HOST_PROMPT_SUPPORT) #if ENABLED(HOST_PROMPT_SUPPORT)

View File

@@ -49,7 +49,7 @@ class EmergencyParser {
public: public:
// Currently looking for: M108, M112, M410, M876 S[0-9], S000, P000, R000 // Currently looking for: M108, M112, M410, M524, M876 S[0-9], S000, P000, R000
enum State : uint8_t { enum State : uint8_t {
EP_RESET, EP_RESET,
EP_N, EP_N,
@@ -58,6 +58,9 @@ public:
EP_M10, EP_M108, EP_M10, EP_M108,
EP_M11, EP_M112, EP_M11, EP_M112,
EP_M4, EP_M41, EP_M410, EP_M4, EP_M41, EP_M410,
#if ENABLED(SDSUPPORT)
EP_M5, EP_M52, EP_M524,
#endif
#if ENABLED(HOST_PROMPT_SUPPORT) #if ENABLED(HOST_PROMPT_SUPPORT)
EP_M8, EP_M87, EP_M876, EP_M876S, EP_M876SN, EP_M8, EP_M87, EP_M876, EP_M876S, EP_M876SN,
#endif #endif
@@ -76,6 +79,10 @@ public:
static bool killed_by_M112; static bool killed_by_M112;
static bool quickstop_by_M410; static bool quickstop_by_M410;
#if ENABLED(SDSUPPORT)
static bool sd_abort_by_M524;
#endif
#if ENABLED(HOST_PROMPT_SUPPORT) #if ENABLED(HOST_PROMPT_SUPPORT)
static uint8_t M876_reason; static uint8_t M876_reason;
#endif #endif
@@ -145,6 +152,9 @@ public:
case ' ': break; case ' ': break;
case '1': state = EP_M1; break; case '1': state = EP_M1; break;
case '4': state = EP_M4; break; case '4': state = EP_M4; break;
#if ENABLED(SDSUPPORT)
case '5': state = EP_M5; break;
#endif
#if ENABLED(HOST_PROMPT_SUPPORT) #if ENABLED(HOST_PROMPT_SUPPORT)
case '8': state = EP_M8; break; case '8': state = EP_M8; break;
#endif #endif
@@ -165,6 +175,11 @@ public:
case EP_M4: state = (c == '1') ? EP_M41 : EP_IGNORE; break; case EP_M4: state = (c == '1') ? EP_M41 : EP_IGNORE; break;
case EP_M41: state = (c == '0') ? EP_M410 : EP_IGNORE; break; case EP_M41: state = (c == '0') ? EP_M410 : EP_IGNORE; break;
#if ENABLED(SDSUPPORT)
case EP_M5: state = (c == '2') ? EP_M52 : EP_IGNORE; break;
case EP_M52: state = (c == '4') ? EP_M524 : EP_IGNORE; break;
#endif
#if ENABLED(HOST_PROMPT_SUPPORT) #if ENABLED(HOST_PROMPT_SUPPORT)
case EP_M8: state = (c == '7') ? EP_M87 : EP_IGNORE; break; case EP_M8: state = (c == '7') ? EP_M87 : EP_IGNORE; break;
@@ -200,6 +215,9 @@ public:
case EP_M108: wait_for_user = wait_for_heatup = false; break; case EP_M108: wait_for_user = wait_for_heatup = false; break;
case EP_M112: killed_by_M112 = true; break; case EP_M112: killed_by_M112 = true; break;
case EP_M410: quickstop_by_M410 = true; break; case EP_M410: quickstop_by_M410 = true; break;
#if ENABLED(SDSUPPORT)
case EP_M524: sd_abort_by_M524 = true; break;
#endif
#if ENABLED(HOST_PROMPT_SUPPORT) #if ENABLED(HOST_PROMPT_SUPPORT)
case EP_M876SN: hostui.handle_response(M876_reason); break; case EP_M876SN: hostui.handle_response(M876_reason); break;
#endif #endif

View File

@@ -111,20 +111,29 @@ void HostUI::action(FSTR_P const fstr, const bool eol) {
if (eol) SERIAL_EOL(); if (eol) SERIAL_EOL();
} }
void HostUI::prompt_plus(FSTR_P const ptype, FSTR_P const fstr, const char extra_char/*='\0'*/) { void HostUI::prompt_plus(const bool pgm, FSTR_P const ptype, const char * const str, const char extra_char/*='\0'*/) {
prompt(ptype, false); prompt(ptype, false);
PORT_REDIRECT(SerialMask::All); PORT_REDIRECT(SerialMask::All);
SERIAL_CHAR(' '); SERIAL_CHAR(' ');
SERIAL_ECHOF(fstr); if (pgm)
SERIAL_ECHOPGM_P(str);
else
SERIAL_ECHO(str);
if (extra_char != '\0') SERIAL_CHAR(extra_char); if (extra_char != '\0') SERIAL_CHAR(extra_char);
SERIAL_EOL(); SERIAL_EOL();
} }
void HostUI::prompt_begin(const PromptReason reason, FSTR_P const fstr, const char extra_char/*='\0'*/) { void HostUI::prompt_begin(const PromptReason reason, FSTR_P const fstr, const char extra_char/*='\0'*/) {
prompt_end(); prompt_end();
host_prompt_reason = reason; host_prompt_reason = reason;
prompt_plus(F("begin"), fstr, extra_char); prompt_plus(F("begin"), fstr, extra_char);
} }
void HostUI::prompt_button(FSTR_P const fstr) { prompt_plus(F("button"), fstr); } void HostUI::prompt_begin(const PromptReason reason, const char * const cstr, const char extra_char/*='\0'*/) {
prompt_end();
host_prompt_reason = reason;
prompt_plus(F("begin"), cstr, extra_char);
}
void HostUI::prompt_end() { prompt(F("end")); } void HostUI::prompt_end() { prompt(F("end")); }
void HostUI::prompt_show() { prompt(F("show")); } void HostUI::prompt_show() { prompt(F("show")); }
@@ -133,14 +142,26 @@ void HostUI::action(FSTR_P const fstr, const bool eol) {
if (btn2) prompt_button(btn2); if (btn2) prompt_button(btn2);
prompt_show(); prompt_show();
} }
void HostUI::prompt_button(FSTR_P const fstr) { prompt_plus(F("button"), fstr); }
void HostUI::prompt_button(const char * const cstr) { prompt_plus(F("button"), cstr); }
void HostUI::prompt_do(const PromptReason reason, FSTR_P const fstr, FSTR_P const btn1/*=nullptr*/, FSTR_P const btn2/*=nullptr*/) { void HostUI::prompt_do(const PromptReason reason, FSTR_P const fstr, FSTR_P const btn1/*=nullptr*/, FSTR_P const btn2/*=nullptr*/) {
prompt_begin(reason, fstr); prompt_begin(reason, fstr);
_prompt_show(btn1, btn2); _prompt_show(btn1, btn2);
} }
void HostUI::prompt_do(const PromptReason reason, const char * const cstr, FSTR_P const btn1/*=nullptr*/, FSTR_P const btn2/*=nullptr*/) {
prompt_begin(reason, cstr);
_prompt_show(btn1, btn2);
}
void HostUI::prompt_do(const PromptReason reason, FSTR_P const fstr, const char extra_char, FSTR_P const btn1/*=nullptr*/, FSTR_P const btn2/*=nullptr*/) { void HostUI::prompt_do(const PromptReason reason, FSTR_P const fstr, const char extra_char, FSTR_P const btn1/*=nullptr*/, FSTR_P const btn2/*=nullptr*/) {
prompt_begin(reason, fstr, extra_char); prompt_begin(reason, fstr, extra_char);
_prompt_show(btn1, btn2); _prompt_show(btn1, btn2);
} }
void HostUI::prompt_do(const PromptReason reason, const char * const cstr, const char extra_char, FSTR_P const btn1/*=nullptr*/, FSTR_P const btn2/*=nullptr*/) {
prompt_begin(reason, cstr, extra_char);
_prompt_show(btn1, btn2);
}
#if ENABLED(ADVANCED_PAUSE_FEATURE) #if ENABLED(ADVANCED_PAUSE_FEATURE)
void HostUI::filament_load_prompt() { void HostUI::filament_load_prompt() {

View File

@@ -79,7 +79,14 @@ class HostUI {
#if ENABLED(HOST_PROMPT_SUPPORT) #if ENABLED(HOST_PROMPT_SUPPORT)
private: private:
static void prompt(FSTR_P const ptype, const bool eol=true); static void prompt(FSTR_P const ptype, const bool eol=true);
static void prompt_plus(FSTR_P const ptype, FSTR_P const fstr, const char extra_char='\0'); static void prompt_plus(const bool pgm, FSTR_P const ptype, const char * const str, const char extra_char='\0');
static void prompt_plus(FSTR_P const ptype, FSTR_P const fstr, const char extra_char='\0') {
prompt_plus(true, ptype, FTOP(fstr), extra_char);
}
static void prompt_plus(FSTR_P const ptype, const char * const cstr, const char extra_char='\0') {
prompt_plus(false, ptype, cstr, extra_char);
}
static void prompt_show(); static void prompt_show();
static void _prompt_show(FSTR_P const btn1, FSTR_P const btn2); static void _prompt_show(FSTR_P const btn1, FSTR_P const btn2);
@@ -93,10 +100,17 @@ class HostUI {
static void notify(const char * const message); static void notify(const char * const message);
static void prompt_begin(const PromptReason reason, FSTR_P const fstr, const char extra_char='\0'); static void prompt_begin(const PromptReason reason, FSTR_P const fstr, const char extra_char='\0');
static void prompt_button(FSTR_P const fstr); static void prompt_begin(const PromptReason reason, const char * const cstr, const char extra_char='\0');
static void prompt_end(); static void prompt_end();
static void prompt_button(FSTR_P const fstr);
static void prompt_button(const char * const cstr);
static void prompt_do(const PromptReason reason, FSTR_P const pstr, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr); static void prompt_do(const PromptReason reason, FSTR_P const pstr, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr);
static void prompt_do(const PromptReason reason, const char * const cstr, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr);
static void prompt_do(const PromptReason reason, FSTR_P const pstr, const char extra_char, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr); static void prompt_do(const PromptReason reason, FSTR_P const pstr, const char extra_char, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr);
static void prompt_do(const PromptReason reason, const char * const cstr, const char extra_char, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr);
static void prompt_open(const PromptReason reason, FSTR_P const pstr, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr) { static void prompt_open(const PromptReason reason, FSTR_P const pstr, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr) {
if (host_prompt_reason == PROMPT_NOT_DEFINED) prompt_do(reason, pstr, btn1, btn2); if (host_prompt_reason == PROMPT_NOT_DEFINED) prompt_do(reason, pstr, btn1, btn2);
} }

View File

@@ -30,18 +30,6 @@
#include "leds.h" #include "leds.h"
#if ENABLED(BLINKM)
#include "blinkm.h"
#endif
#if ENABLED(PCA9632)
#include "pca9632.h"
#endif
#if ENABLED(PCA9533)
#include "pca9533.h"
#endif
#if EITHER(CASE_LIGHT_USE_RGB_LED, CASE_LIGHT_USE_NEOPIXEL) #if EITHER(CASE_LIGHT_USE_RGB_LED, CASE_LIGHT_USE_NEOPIXEL)
#include "../../feature/caselight.h" #include "../../feature/caselight.h"
#endif #endif
@@ -69,6 +57,44 @@ void LEDLights::setup() {
#if ENABLED(RGBW_LED) #if ENABLED(RGBW_LED)
if (PWM_PIN(RGB_LED_W_PIN)) SET_PWM(RGB_LED_W_PIN); else SET_OUTPUT(RGB_LED_W_PIN); if (PWM_PIN(RGB_LED_W_PIN)) SET_PWM(RGB_LED_W_PIN); else SET_OUTPUT(RGB_LED_W_PIN);
#endif #endif
#if ENABLED(RGB_STARTUP_TEST)
int8_t led_pin_count = 0;
if (PWM_PIN(RGB_LED_R_PIN) && PWM_PIN(RGB_LED_G_PIN) && PWM_PIN(RGB_LED_B_PIN)) led_pin_count = 3;
#if ENABLED(RGBW_LED)
if (PWM_PIN(RGB_LED_W_PIN) && led_pin_count) led_pin_count++;
#endif
// Startup animation
if (led_pin_count) {
// blackout
if (PWM_PIN(RGB_LED_R_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_R_PIN), 0); else WRITE(RGB_LED_R_PIN, LOW);
if (PWM_PIN(RGB_LED_G_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_G_PIN), 0); else WRITE(RGB_LED_G_PIN, LOW);
if (PWM_PIN(RGB_LED_B_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_B_PIN), 0); else WRITE(RGB_LED_B_PIN, LOW);
#if ENABLED(RGBW_LED)
if (PWM_PIN(RGB_LED_W_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_W_PIN), 0);
else WRITE(RGB_LED_W_PIN, LOW);
#endif
delay(200);
LOOP_L_N(i, led_pin_count) {
LOOP_LE_N(b, 200) {
const uint16_t led_pwm = b <= 100 ? b : 200 - b;
if (i == 0 && PWM_PIN(RGB_LED_R_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_R_PIN), led_pwm); else WRITE(RGB_LED_R_PIN, b < 100 ? HIGH : LOW);
if (i == 1 && PWM_PIN(RGB_LED_G_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_G_PIN), led_pwm); else WRITE(RGB_LED_G_PIN, b < 100 ? HIGH : LOW);
if (i == 2 && PWM_PIN(RGB_LED_B_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_B_PIN), led_pwm); else WRITE(RGB_LED_B_PIN, b < 100 ? HIGH : LOW);
#if ENABLED(RGBW_LED)
if (i == 3){
if (PWM_PIN(RGB_LED_W_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_W_PIN), led_pwm);
else WRITE(RGB_LED_W_PIN, b < 100 ? HIGH : LOW);
delay(RGB_STARTUP_TEST_INNER_MS);//More slowing for ending
}
#endif
delay(RGB_STARTUP_TEST_INNER_MS);
}
}
delay(500);
}
#endif // RGB_STARTUP_TEST
#endif #endif
TERN_(NEOPIXEL_LED, neo.init()); TERN_(NEOPIXEL_LED, neo.init());
TERN_(PCA9533, PCA9533_init()); TERN_(PCA9533, PCA9533_init());

View File

@@ -40,6 +40,18 @@
#undef _NEOPIXEL_INCLUDE_ #undef _NEOPIXEL_INCLUDE_
#endif #endif
#if ENABLED(BLINKM)
#include "blinkm.h"
#endif
#if ENABLED(PCA9533)
#include "pca9533.h"
#endif
#if ENABLED(PCA9632)
#include "pca9632.h"
#endif
/** /**
* LEDcolor type for use with leds.set_color * LEDcolor type for use with leds.set_color
*/ */
@@ -107,6 +119,13 @@ typedef struct LEDColor {
class LEDLights { class LEDLights {
public: public:
#if ANY(LED_CONTROL_MENU, PRINTER_EVENT_LEDS, CASE_LIGHT_IS_COLOR_LED)
static LEDColor color; // last non-off color
static bool lights_on; // the last set color was "on"
#else
static constexpr bool lights_on = true;
#endif
LEDLights() {} // ctor LEDLights() {} // ctor
static void setup(); // init() static void setup(); // init()
@@ -142,15 +161,10 @@ public:
static LEDColor get_color() { return lights_on ? color : LEDColorOff(); } static LEDColor get_color() { return lights_on ? color : LEDColorOff(); }
#endif #endif
#if ANY(LED_CONTROL_MENU, PRINTER_EVENT_LEDS, CASE_LIGHT_IS_COLOR_LED)
static LEDColor color; // last non-off color
static bool lights_on; // the last set color was "on"
#endif
#if ENABLED(LED_CONTROL_MENU) #if ENABLED(LED_CONTROL_MENU)
static void toggle(); // swap "off" with color static void toggle(); // swap "off" with color
#endif #endif
#if EITHER(LED_CONTROL_MENU, CASE_LIGHT_USE_RGB_LED) #if EITHER(LED_CONTROL_MENU, CASE_LIGHT_USE_RGB_LED) || LED_POWEROFF_TIMEOUT > 0
static void update() { set_color(color); } static void update() { set_color(color); }
#endif #endif

View File

@@ -54,7 +54,8 @@ MMU2 mmu2;
#define MMU_CMD_TIMEOUT 45000UL // 45s timeout for mmu commands (except P0) #define MMU_CMD_TIMEOUT 45000UL // 45s timeout for mmu commands (except P0)
#define MMU_P0_TIMEOUT 3000UL // Timeout for P0 command: 3seconds #define MMU_P0_TIMEOUT 3000UL // Timeout for P0 command: 3seconds
#define MMU2_COMMAND(S) tx_str(F(S "\n")) #define MMU2_SEND(S) tx_str(F(S "\n"))
#define MMU2_RECV(S) rx_str(F(S "\n"))
#if ENABLED(MMU_EXTRUDER_SENSOR) #if ENABLED(MMU_EXTRUDER_SENSOR)
uint8_t mmu_idl_sens = 0; uint8_t mmu_idl_sens = 0;
@@ -131,7 +132,7 @@ void MMU2::reset() {
safe_delay(20); safe_delay(20);
WRITE(MMU2_RST_PIN, HIGH); WRITE(MMU2_RST_PIN, HIGH);
#else #else
MMU2_COMMAND("X0"); // Send soft reset MMU2_SEND("X0"); // Send soft reset
#endif #endif
} }
@@ -157,11 +158,9 @@ void MMU2::mmu_loop() {
case -1: case -1:
if (rx_start()) { if (rx_start()) {
prev_P0_request = millis(); // Initialize finda sensor timeout prev_P0_request = millis(); // Initialize finda sensor timeout
DEBUG_ECHOLNPGM("MMU => 'start'"); DEBUG_ECHOLNPGM("MMU => 'start'");
DEBUG_ECHOLNPGM("MMU <= 'S1'"); DEBUG_ECHOLNPGM("MMU <= 'S1'");
MMU2_SEND("S1"); // Read Version
MMU2_COMMAND("S1"); // Read Version
state = -2; state = -2;
} }
else if (millis() > 30000) { // 30sec after reset disable MMU else if (millis() > 30000) { // 30sec after reset disable MMU
@@ -173,10 +172,8 @@ void MMU2::mmu_loop() {
case -2: case -2:
if (rx_ok()) { if (rx_ok()) {
sscanf(rx_buffer, "%huok\n", &version); sscanf(rx_buffer, "%huok\n", &version);
DEBUG_ECHOLNPGM("MMU => ", version, "\nMMU <= 'S2'"); DEBUG_ECHOLNPGM("MMU => ", version, "\nMMU <= 'S2'");
MMU2_SEND("S2"); // Read Build Number
MMU2_COMMAND("S2"); // Read Build Number
state = -3; state = -3;
} }
break; break;
@@ -191,14 +188,12 @@ void MMU2::mmu_loop() {
#if ENABLED(MMU2_MODE_12V) #if ENABLED(MMU2_MODE_12V)
DEBUG_ECHOLNPGM("MMU <= 'M1'"); DEBUG_ECHOLNPGM("MMU <= 'M1'");
MMU2_SEND("M1"); // Stealth Mode
MMU2_COMMAND("M1"); // Stealth Mode
state = -5; state = -5;
#else #else
DEBUG_ECHOLNPGM("MMU <= 'P0'"); DEBUG_ECHOLNPGM("MMU <= 'P0'");
MMU2_SEND("P0"); // Read FINDA
MMU2_COMMAND("P0"); // Read FINDA
state = -4; state = -4;
#endif #endif
} }
@@ -209,10 +204,8 @@ void MMU2::mmu_loop() {
// response to M1 // response to M1
if (rx_ok()) { if (rx_ok()) {
DEBUG_ECHOLNPGM("MMU => ok"); DEBUG_ECHOLNPGM("MMU => ok");
DEBUG_ECHOLNPGM("MMU <= 'P0'"); DEBUG_ECHOLNPGM("MMU <= 'P0'");
MMU2_SEND("P0"); // Read FINDA
MMU2_COMMAND("P0"); // Read FINDA
state = -4; state = -4;
} }
break; break;
@@ -250,14 +243,13 @@ void MMU2::mmu_loop() {
else if (cmd == MMU_CMD_C0) { else if (cmd == MMU_CMD_C0) {
// continue loading // continue loading
DEBUG_ECHOLNPGM("MMU <= 'C0'"); DEBUG_ECHOLNPGM("MMU <= 'C0'");
MMU2_COMMAND("C0"); MMU2_SEND("C0");
state = 3; // wait for response state = 3; // wait for response
} }
else if (cmd == MMU_CMD_U0) { else if (cmd == MMU_CMD_U0) {
// unload current // unload current
DEBUG_ECHOLNPGM("MMU <= 'U0'"); DEBUG_ECHOLNPGM("MMU <= 'U0'");
MMU2_SEND("U0");
MMU2_COMMAND("U0");
state = 3; // wait for response state = 3; // wait for response
} }
else if (WITHIN(cmd, MMU_CMD_E0, MMU_CMD_E0 + EXTRUDERS - 1)) { else if (WITHIN(cmd, MMU_CMD_E0, MMU_CMD_E0 + EXTRUDERS - 1)) {
@@ -270,7 +262,7 @@ void MMU2::mmu_loop() {
else if (cmd == MMU_CMD_R0) { else if (cmd == MMU_CMD_R0) {
// recover after eject // recover after eject
DEBUG_ECHOLNPGM("MMU <= 'R0'"); DEBUG_ECHOLNPGM("MMU <= 'R0'");
MMU2_COMMAND("R0"); MMU2_SEND("R0");
state = 3; // wait for response state = 3; // wait for response
} }
else if (WITHIN(cmd, MMU_CMD_F0, MMU_CMD_F0 + EXTRUDERS - 1)) { else if (WITHIN(cmd, MMU_CMD_F0, MMU_CMD_F0 + EXTRUDERS - 1)) {
@@ -285,7 +277,7 @@ void MMU2::mmu_loop() {
cmd = MMU_CMD_NONE; cmd = MMU_CMD_NONE;
} }
else if (ELAPSED(millis(), prev_P0_request + 300)) { else if (ELAPSED(millis(), prev_P0_request + 300)) {
MMU2_COMMAND("P0"); // Read FINDA MMU2_SEND("P0"); // Read FINDA
state = 2; // wait for response state = 2; // wait for response
} }
@@ -314,7 +306,7 @@ void MMU2::mmu_loop() {
if (mmu_idl_sens) { if (mmu_idl_sens) {
if (FILAMENT_PRESENT() && mmu_loading_flag) { if (FILAMENT_PRESENT() && mmu_loading_flag) {
DEBUG_ECHOLNPGM("MMU <= 'A'"); DEBUG_ECHOLNPGM("MMU <= 'A'");
MMU2_COMMAND("A"); // send 'abort' request MMU2_SEND("A"); // send 'abort' request
mmu_idl_sens = 0; mmu_idl_sens = 0;
DEBUG_ECHOLNPGM("MMU IDLER_SENSOR = 0 - ABORT"); DEBUG_ECHOLNPGM("MMU IDLER_SENSOR = 0 - ABORT");
} }
@@ -327,9 +319,9 @@ void MMU2::mmu_loop() {
const bool keep_trying = !mmu2s_triggered && last_cmd == MMU_CMD_C0; const bool keep_trying = !mmu2s_triggered && last_cmd == MMU_CMD_C0;
if (keep_trying) { if (keep_trying) {
// MMU ok received but filament sensor not triggered, retrying... // MMU ok received but filament sensor not triggered, retrying...
DEBUG_ECHOLNPGM("MMU => 'ok' (filament not present in gears)"); DEBUG_ECHOLNPGM("MMU => 'ok' (no filament in gears)");
DEBUG_ECHOLNPGM("MMU <= 'C0' (keep trying)"); DEBUG_ECHOLNPGM("MMU <= 'C0' (keep trying)");
MMU2_COMMAND("C0"); MMU2_SEND("C0");
} }
#else #else
constexpr bool keep_trying = false; constexpr bool keep_trying = false;
@@ -361,7 +353,7 @@ void MMU2::mmu_loop() {
*/ */
bool MMU2::rx_start() { bool MMU2::rx_start() {
// check for start message // check for start message
return rx_str(F("start\n")); return MMU2_RECV("start");
} }
/** /**
@@ -440,7 +432,7 @@ void MMU2::clear_rx_buffer() {
* Check if we received 'ok' from MMU * Check if we received 'ok' from MMU
*/ */
bool MMU2::rx_ok() { bool MMU2::rx_ok() {
if (rx_str(F("ok\n"))) { if (MMU2_RECV("ok")) {
prev_P0_request = millis(); prev_P0_request = millis();
return true; return true;
} }
@@ -585,7 +577,7 @@ static void mmu2_not_responding() {
command(MMU_CMD_T0 + index); command(MMU_CMD_T0 + index);
manage_response(true, true); manage_response(true, true);
mmu_continue_loading(); mmu_continue_loading();
command(MMU_CMD_C0); //command(MMU_CMD_C0);
extruder = index; extruder = index;
active_extruder = 0; active_extruder = 0;
@@ -653,13 +645,34 @@ static void mmu2_not_responding() {
} }
void MMU2::mmu_continue_loading() { void MMU2::mmu_continue_loading() {
// Try to load the filament a limited number of times
bool fil_present = 0;
for (uint8_t i = 0; i < MMU_LOADING_ATTEMPTS_NR; i++) { for (uint8_t i = 0; i < MMU_LOADING_ATTEMPTS_NR; i++) {
DEBUG_ECHOLNPGM("Additional load attempt #", i); DEBUG_ECHOLNPGM("Load attempt #", i + 1);
if (FILAMENT_PRESENT()) break;
// Done as soon as filament is present
fil_present = FILAMENT_PRESENT();
if (fil_present) break;
// Attempt to load the filament, 1mm at a time, for 3s
command(MMU_CMD_C0); command(MMU_CMD_C0);
stepper.enable_extruder();
const millis_t expire_ms = millis() + 3000;
do {
current_position.e += 1;
line_to_current_position(MMU_LOAD_FEEDRATE);
planner.synchronize();
// When (T0 rx->ok) load is ready, but in fact it did not load
// successfully or an overload created pressure in the extruder.
// Send (C0) to load more and move E_AXIS a little to release pressure.
if ((fil_present = FILAMENT_PRESENT())) MMU2_SEND("A");
} while (!fil_present && PENDING(millis(), expire_ms));
stepper.disable_extruder();
manage_response(true, true); manage_response(true, true);
} }
if (!FILAMENT_PRESENT()) {
// Was the filament still missing in the last check?
if (!fil_present) {
DEBUG_ECHOLNPGM("Filament never reached sensor, runout"); DEBUG_ECHOLNPGM("Filament never reached sensor, runout");
filament_runout(); filament_runout();
} }
@@ -682,7 +695,7 @@ static void mmu2_not_responding() {
command(MMU_CMD_T0 + index); command(MMU_CMD_T0 + index);
manage_response(true, true); manage_response(true, true);
command(MMU_CMD_C0); command(MMU_CMD_C0);
extruder = index; //filament change is finished extruder = index; // Filament change is finished
active_extruder = 0; active_extruder = 0;
stepper.enable_extruder(); stepper.enable_extruder();
SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder); SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder);
@@ -861,7 +874,7 @@ void MMU2::filament_runout() {
if (cmd == MMU_CMD_NONE && last_cmd == MMU_CMD_C0) { if (cmd == MMU_CMD_NONE && last_cmd == MMU_CMD_C0) {
if (present && !mmu2s_triggered) { if (present && !mmu2s_triggered) {
DEBUG_ECHOLNPGM("MMU <= 'A'"); DEBUG_ECHOLNPGM("MMU <= 'A'");
tx_str(F("A\n")); MMU2_SEND("A");
} }
// Slowly spin the extruder during C0 // Slowly spin the extruder during C0
else { else {

View File

@@ -86,6 +86,7 @@ private:
#endif #endif
#if ENABLED(MMU_EXTRUDER_SENSOR) #if ENABLED(MMU_EXTRUDER_SENSOR)
#define MMU_LOAD_FEEDRATE 19.02f // (mm/s)
static void mmu_continue_loading(); static void mmu_continue_loading();
#endif #endif

View File

@@ -474,9 +474,7 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool
if (unload_length) if (unload_length)
unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT); unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT);
#if ENABLED(DUAL_X_CARRIAGE) TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext));
set_duplication_enabled(saved_ext_dup_mode, saved_ext);
#endif
// Disable the Extruder for manual change // Disable the Extruder for manual change
disable_active_extruder(); disable_active_extruder();
@@ -593,9 +591,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
} }
idle_no_sleep(); idle_no_sleep();
} }
#if ENABLED(DUAL_X_CARRIAGE) TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext));
set_duplication_enabled(saved_ext_dup_mode, saved_ext);
#endif
} }
/** /**

View File

@@ -53,7 +53,7 @@ PowerMonitor power_monitor; // Single instance - this calls the constructor
void PowerMonitor::draw_current() { void PowerMonitor::draw_current() {
const float amps = getAmps(); const float amps = getAmps();
lcd_put_u8str(amps < 100 ? ftostr31ns(amps) : ui16tostr4rj((uint16_t)amps)); lcd_put_u8str(amps < 100 ? ftostr31ns(amps) : ui16tostr4rj((uint16_t)amps));
lcd_put_lchar('A'); lcd_put_u8str(F("A"));
} }
#endif #endif
@@ -61,7 +61,7 @@ PowerMonitor power_monitor; // Single instance - this calls the constructor
void PowerMonitor::draw_voltage() { void PowerMonitor::draw_voltage() {
const float volts = getVolts(); const float volts = getVolts();
lcd_put_u8str(volts < 100 ? ftostr31ns(volts) : ui16tostr4rj((uint16_t)volts)); lcd_put_u8str(volts < 100 ? ftostr31ns(volts) : ui16tostr4rj((uint16_t)volts));
lcd_put_lchar('V'); lcd_put_u8str(F("V"));
} }
#endif #endif
@@ -69,7 +69,7 @@ PowerMonitor power_monitor; // Single instance - this calls the constructor
void PowerMonitor::draw_power() { void PowerMonitor::draw_power() {
const float power = getPower(); const float power = getPower();
lcd_put_u8str(power < 100 ? ftostr31ns(power) : ui16tostr4rj((uint16_t)power)); lcd_put_u8str(power < 100 ? ftostr31ns(power) : ui16tostr4rj((uint16_t)power));
lcd_put_lchar('W'); lcd_put_u8str(F("W"));
} }
#endif #endif

View File

@@ -153,6 +153,9 @@ class PrintJobRecovery {
static void prepare(); static void prepare();
static void setup() { static void setup() {
#if PIN_EXISTS(OUTAGECON)
OUT_WRITE(OUTAGECON_PIN, HIGH);
#endif
#if PIN_EXISTS(POWER_LOSS) #if PIN_EXISTS(POWER_LOSS)
#if ENABLED(POWER_LOSS_PULLUP) #if ENABLED(POWER_LOSS_PULLUP)
SET_INPUT_PULLUP(POWER_LOSS_PIN); SET_INPUT_PULLUP(POWER_LOSS_PIN);

View File

@@ -42,7 +42,7 @@ void Repeat::add_marker(const uint32_t sdpos, const uint16_t count) {
SERIAL_ECHO_MSG("!Too many markers."); SERIAL_ECHO_MSG("!Too many markers.");
else { else {
marker[index].sdpos = sdpos; marker[index].sdpos = sdpos;
marker[index].counter = count ?: -1; marker[index].counter = count ? count - 1 : -1;
index++; index++;
DEBUG_ECHOLNPGM("Add Marker ", index, " at ", sdpos, " (", count, ")"); DEBUG_ECHOLNPGM("Add Marker ", index, " at ", sdpos, " (", count, ")");
} }

View File

@@ -30,9 +30,7 @@
#include "spindle_laser_types.h" #include "spindle_laser_types.h"
#if HAS_BEEPER
#include "../libs/buzzer.h" #include "../libs/buzzer.h"
#endif
// Inline laser power // Inline laser power
#include "../module/planner.h" #include "../module/planner.h"

View File

@@ -112,7 +112,7 @@ void GcodeSuite::M48() {
set_bed_leveling_enabled(false); set_bed_leveling_enabled(false);
#endif #endif
TERN_(HAS_PTC, ptc.set_enabled(!parser.seen('C') || parser.value_bool())); TERN_(HAS_PTC, ptc.set_enabled(parser.boolval('C', true)));
// Work with reasonable feedrates // Work with reasonable feedrates
remember_feedrate_scaling_off(); remember_feedrate_scaling_off();

View File

@@ -167,8 +167,6 @@
if (parser.seenval('T')) draw_area_max.y = parser.value_linear_units(); if (parser.seenval('T')) draw_area_max.y = parser.value_linear_units();
if (parser.seenval('B')) draw_area_min.y = parser.value_linear_units(); if (parser.seenval('B')) draw_area_min.y = parser.value_linear_units();
if (parser.seenval('H')) polargraph_max_belt_len = parser.value_linear_units(); if (parser.seenval('H')) polargraph_max_belt_len = parser.value_linear_units();
draw_area_size.x = draw_area_max.x - draw_area_min.x;
draw_area_size.y = draw_area_max.y - draw_area_min.y;
} }
void GcodeSuite::M665_report(const bool forReplay/*=true*/) { void GcodeSuite::M665_report(const bool forReplay/*=true*/) {

View File

@@ -43,13 +43,14 @@
* S[linear] Swap length * S[linear] Swap length
* B[linear] Extra Swap resume length * B[linear] Extra Swap resume length
* E[linear] Extra Prime length (as used by M217 Q) * E[linear] Extra Prime length (as used by M217 Q)
* P[linear/min] Prime speed * G[linear] Cutting wipe retract length (<=100mm)
* R[linear/min] Retract speed * R[linear/min] Retract speed
* U[linear/min] UnRetract speed * U[linear/min] UnRetract speed
* P[linear/min] Prime speed
* V[linear] 0/1 Enable auto prime first extruder used * V[linear] 0/1 Enable auto prime first extruder used
* W[linear] 0/1 Enable park & Z Raise * W[linear] 0/1 Enable park & Z Raise
* X[linear] Park X (Requires TOOLCHANGE_PARK) * X[linear] Park X (Requires TOOLCHANGE_PARK)
* Y[linear] Park Y (Requires TOOLCHANGE_PARK) * Y[linear] Park Y (Requires TOOLCHANGE_PARK and NUM_AXES >= 2)
* I[linear] Park I (Requires TOOLCHANGE_PARK and NUM_AXES >= 4) * I[linear] Park I (Requires TOOLCHANGE_PARK and NUM_AXES >= 4)
* J[linear] Park J (Requires TOOLCHANGE_PARK and NUM_AXES >= 5) * J[linear] Park J (Requires TOOLCHANGE_PARK and NUM_AXES >= 5)
* K[linear] Park K (Requires TOOLCHANGE_PARK and NUM_AXES >= 6) * K[linear] Park K (Requires TOOLCHANGE_PARK and NUM_AXES >= 6)
@@ -79,6 +80,7 @@ void GcodeSuite::M217() {
if (parser.seenval('B')) { const float v = parser.value_linear_units(); toolchange_settings.extra_resume = constrain(v, -10, 10); } if (parser.seenval('B')) { const float v = parser.value_linear_units(); toolchange_settings.extra_resume = constrain(v, -10, 10); }
if (parser.seenval('E')) { const float v = parser.value_linear_units(); toolchange_settings.extra_prime = constrain(v, 0, max_extrude); } if (parser.seenval('E')) { const float v = parser.value_linear_units(); toolchange_settings.extra_prime = constrain(v, 0, max_extrude); }
if (parser.seenval('P')) { const int16_t v = parser.value_linear_units(); toolchange_settings.prime_speed = constrain(v, 10, 5400); } if (parser.seenval('P')) { const int16_t v = parser.value_linear_units(); toolchange_settings.prime_speed = constrain(v, 10, 5400); }
if (parser.seenval('G')) { const int16_t v = parser.value_linear_units(); toolchange_settings.wipe_retract = constrain(v, 0, 100); }
if (parser.seenval('R')) { const int16_t v = parser.value_linear_units(); toolchange_settings.retract_speed = constrain(v, 10, 5400); } if (parser.seenval('R')) { const int16_t v = parser.value_linear_units(); toolchange_settings.retract_speed = constrain(v, 10, 5400); }
if (parser.seenval('U')) { const int16_t v = parser.value_linear_units(); toolchange_settings.unretract_speed = constrain(v, 10, 5400); } if (parser.seenval('U')) { const int16_t v = parser.value_linear_units(); toolchange_settings.unretract_speed = constrain(v, 10, 5400); }
#if TOOLCHANGE_FS_FAN >= 0 && HAS_FAN #if TOOLCHANGE_FS_FAN >= 0 && HAS_FAN
@@ -164,21 +166,24 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
SERIAL_ECHOPGM(" M217"); SERIAL_ECHOPGM(" M217");
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP) #if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
SERIAL_ECHOPGM(" S", LINEAR_UNIT(toolchange_settings.swap_length)); SERIAL_ECHOPGM_P(
SERIAL_ECHOPGM_P(SP_B_STR, LINEAR_UNIT(toolchange_settings.extra_resume), PSTR(" S"), LINEAR_UNIT(toolchange_settings.swap_length),
SP_B_STR, LINEAR_UNIT(toolchange_settings.extra_resume),
SP_E_STR, LINEAR_UNIT(toolchange_settings.extra_prime), SP_E_STR, LINEAR_UNIT(toolchange_settings.extra_prime),
SP_P_STR, LINEAR_UNIT(toolchange_settings.prime_speed)); SP_P_STR, LINEAR_UNIT(toolchange_settings.prime_speed),
SERIAL_ECHOPGM(" R", LINEAR_UNIT(toolchange_settings.retract_speed), PSTR(" G"), LINEAR_UNIT(toolchange_settings.wipe_retract),
" U", LINEAR_UNIT(toolchange_settings.unretract_speed), PSTR(" R"), LINEAR_UNIT(toolchange_settings.retract_speed),
" F", toolchange_settings.fan_speed, PSTR(" U"), LINEAR_UNIT(toolchange_settings.unretract_speed),
" D", toolchange_settings.fan_time); PSTR(" F"), toolchange_settings.fan_speed,
PSTR(" D"), toolchange_settings.fan_time
);
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
SERIAL_ECHOPGM(" A", migration.automode); SERIAL_ECHOPGM(" A", migration.automode, " L", LINEAR_UNIT(migration.last));
SERIAL_ECHOPGM(" L", LINEAR_UNIT(migration.last));
#endif #endif
#if ENABLED(TOOLCHANGE_PARK) #if ENABLED(TOOLCHANGE_PARK)
{
SERIAL_ECHOPGM(" W", LINEAR_UNIT(toolchange_settings.enable_park)); SERIAL_ECHOPGM(" W", LINEAR_UNIT(toolchange_settings.enable_park));
SERIAL_ECHOPGM_P( SERIAL_ECHOPGM_P(
SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x) SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x)
@@ -196,6 +201,7 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
) )
#endif #endif
); );
}
#endif #endif
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)

Some files were not shown because too many files have changed in this diff Show More