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_size = 2
[{*.py,*.conf,*.sublime-project}]
[{*.py}]
indent_style = space
indent_size = 4
[{*.conf,*.sublime-project}]
indent_style = tab
indent_size = 4

1
.gitignore vendored
View File

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

View File

@@ -27,7 +27,7 @@ tests-single-ci:
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
export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
export PATH="./buildroot/bin/:./buildroot/tests/:${PATH}" \
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
&& run_tests . $(TEST_TARGET) "$(ONLY_TEST)"
.PHONY: tests-single-local
@@ -38,7 +38,7 @@ tests-single-local-docker:
.PHONY: tests-single-local-docker
tests-all-local:
export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
export PATH="./buildroot/bin/:./buildroot/tests/:${PATH}" \
&& 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
.PHONY: tests-all-local

View File

@@ -35,8 +35,7 @@
*
* Advanced settings can be found in Configuration_adv.h
*/
#define CONFIGURATION_H_VERSION 02010100
#define CONFIGURATION_H_VERSION 02010200
#define ANYCUBIC_TOUCHSCREEN
#if DISABLED(KNUTWURST_4MAXP2)
#define ANYCUBIC_FILAMENT_RUNOUT_SENSOR
@@ -65,7 +64,7 @@
*
*/
#if ENABLED(KNUTWURST_MEGA_P)
// #define KNUTWURST_MEGA_P_LASER
// #define KNUTWURST_MEGA_P_LASER
#endif
@@ -222,6 +221,8 @@
// Choose your own or use a service like https://www.uuidgenerator.net/version4
// #define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
// @section stepper drivers
/**
* Stepper Drivers
*
@@ -346,6 +347,8 @@
// #define SINGLENOZZLE_STANDBY_FAN
#endif
// @section multi-material
/**
* Multi-Material Unit
* Set to one of these predefined models:
@@ -358,6 +361,7 @@
*
* Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
* See additional options in Configuration_adv.h.
* :["PRUSA_MMU1", "PRUSA_MMU2", "PRUSA_MMU2S", "EXTENDABLE_EMU_MMU2", "EXTENDABLE_EMU_MMU2S"]
*/
// #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
* 60 : 100kΩ Maker's Tool Works Kapton Bed Thermistor - beta 3950
* 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950
* 66 : 4.7MΩ Dyze Design High Temperature Thermistor
* 66 : 4.7MΩ Dyze Design / Trianglelab T-D500 500°C High Temperature Thermistor
* 67 : 500kΩ SliceEngineering 450°C Thermistor
* 68 : PT100 amplifier board from Dyze Design
* 70 : 100kΩ bq Hephestos 2
@@ -619,6 +623,7 @@
* 110 : Pt100 with 1kΩ pullup (atypical)
* 147 : Pt100 with 4.7kΩ pullup
* 1010 : Pt1000 with 1kΩ pullup (atypical)
* 1022 : Pt1000 with 2.2kΩ pullup
* 1047 : Pt1000 with 4.7kΩ pullup (E3D)
* 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage.
* NOTE: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21.
@@ -672,6 +677,10 @@
#define MAX31865_SENSOR_OHMS_1 100
#define MAX31865_CALIBRATION_OHMS_1 430
#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
#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
@@ -1020,7 +1029,7 @@
// #define POLARGRAPH
#if ENABLED(POLARGRAPH)
#define POLARGRAPH_MAX_BELT_LEN 1035.0
#define POLAR_SEGMENTS_PER_SECOND 5
#define DEFAULT_SEGMENTS_PER_SECOND 5
#endif
// @section delta
@@ -1032,28 +1041,26 @@
// Make delta curves from many straight lines (linear interpolation).
// This is a trade-off between visible corners (not enough segments)
// 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
// #define DELTA_HOME_TO_SAFE_ZONE
// 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
// #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
// NOTE NB all values for DELTA_* values MUST be floating point, so always have a decimal point in them
#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
#endif
#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)
#endif
@@ -1098,7 +1105,7 @@
// #define MP_SCARA
#if EITHER(MORGAN_SCARA, MP_SCARA)
// 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.
#define SCARA_LINKAGE_1 150 // (mm)
@@ -1134,18 +1141,18 @@
// Enable for TPARA kinematics and configure below
// #define AXEL_TPARA
#if ENABLED(AXEL_TPARA)
#define DEBUG_ROBOT_KINEMATICS
#define ROBOT_SEGMENTS_PER_SECOND 200
#define DEBUG_TPARA_KINEMATICS
#define DEFAULT_SEGMENTS_PER_SECOND 200
// Length of inner and outer support arms. Measure arm lengths precisely.
#define ROBOT_LINKAGE_1 120 // (mm)
#define ROBOT_LINKAGE_2 120 // (mm)
#define TPARA_LINKAGE_1 120 // (mm)
#define TPARA_LINKAGE_2 120 // (mm)
// 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.
#define ROBOT_OFFSET_X 0 // (mm)
#define ROBOT_OFFSET_Y 0 // (mm)
#define ROBOT_OFFSET_Z 0 // (mm)
#define TPARA_OFFSET_X 0 // (mm)
#define TPARA_OFFSET_Y 0 // (mm)
#define TPARA_OFFSET_Z 0 // (mm)
#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_INACTIVE_EXTRUDER // Keep only the active extruder enabled
// @section machine
// @section motion
#if DISABLED(KNUTWURST_TMC)
#if ANY(KNUTWURST_MEGA, KNUTWURST_MEGA_S, KNUTWURST_MEGA_X)
@@ -2519,17 +2526,21 @@
#endif
#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.
// The height can be set with M420 Z<height>
/**
* Gradually reduce leveling correction until a set height is reached,
* 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
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
#define DEFAULT_LEVELING_FADE_HEIGHT 0.0 // (mm) Default fade height.
#endif
// For Cartesian machines, instead of dividing moves on mesh boundaries,
// split up moves into short segments like a Delta. This follows the
// contours of the bed more closely than edge-to-edge straight moves.
/**
* For Cartesian machines, instead of dividing moves on mesh boundaries,
* 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 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_SIDE_AD 200
// Or, set the default skew factors directly here
// to override the above measurements:
#define XY_SKEW_FACTOR 0.0
// Or, set the XY skew factor directly:
// #define XY_SKEW_FACTOR 0.0
// #define SKEW_CORRECTION_FOR_Z
#if ENABLED(SKEW_CORRECTION_FOR_Z)
@@ -2769,8 +2779,10 @@
#define YZ_DIAG_AC 282.8427124746
#define YZ_DIAG_BD 282.8427124746
#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
// Enable this option for M852 to set skew at runtime
@@ -2828,7 +2840,7 @@
// @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_TEMP_HOTEND 180
@@ -2986,7 +2998,7 @@
*/
#define 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
// @section security
@@ -3368,7 +3380,7 @@
//
// 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
@@ -3623,6 +3635,7 @@
// #define ANYCUBIC_LCD_CHIRON
#if EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
// #define ANYCUBIC_LCD_DEBUG
// #define ANYCUBIC_LCD_GCODE_EXT // Add ".gcode" to menu entries for DGUS clone compatibility
#endif
//
@@ -3691,7 +3704,7 @@
// #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
@@ -3758,6 +3771,10 @@
// #define TFT_COLOR_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)
// #define MKS_WIFI_MODULE // MKS WiFi module
#endif
@@ -3790,10 +3807,11 @@
//
// #define TOUCH_SCREEN
#if ENABLED(TOUCH_SCREEN)
#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_EDIT 50 // (ms) Button repeat delay for edit screens
#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
@@ -3884,16 +3902,19 @@
* luminance values can be set from 0 to 255.
* For NeoPixel LED an overall brightness parameter is also available.
*
* *** CAUTION ***
* === CAUTION ===
* LED Strips require a MOSFET Chip between PWM lines and LEDs,
* as the Arduino cannot handle the current the LEDs will require.
* Failure to follow this precaution can destroy your Arduino!
*
* NOTE: A separate 5V power supply is required! The NeoPixel LED needs
* 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 RGBW_LED
@@ -3902,6 +3923,10 @@
// #define RGB_LED_G_PIN 43
// #define RGB_LED_B_PIN 35
// #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
// Support for Adafruit NeoPixel LED driver
@@ -3923,6 +3948,7 @@
#define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip
#define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255)
#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
// #define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel
#endif

View File

@@ -30,7 +30,7 @@
*
* Basic settings can be found in Configuration.h
*/
#define CONFIGURATION_ADV_H_VERSION 02010100
#define CONFIGURATION_ADV_H_VERSION 02010200
// @section develop
@@ -48,7 +48,7 @@
* 3 = schema.json - The entire configuration schema. (13 = pattern groups)
* 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_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 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_2 2
// #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.
@@ -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_1 0.0f
// #define MAX31865_WIRE_OHMS_2 0.0f
/**
* Hephestos 2 24V heated bed upgrade kit.
@@ -507,18 +509,22 @@
// #define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0
#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
// hot end to reach the target temperature, but the time it takes to reach
// the minimum temperature your thermistor can read. The lower the better/safer.
// This shouldn't need to be more than 30 seconds (30000)
/**
* 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
* hot end to reach the target temperature, but the time it takes to reach
* 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
// @section extruder
// Extruder runout prevention.
// If the machine is idle and the temperature over MINTEMP
// then extrude some filament every couple of SECONDS.
/**
* Extruder runout prevention.
* If the machine is idle and the temperature over MINTEMP
* then extrude some filament every couple of SECONDS.
*/
// #define EXTRUDER_RUNOUT_PREVENT
#if ENABLED(EXTRUDER_RUNOUT_PREVENT)
#define EXTRUDER_RUNOUT_MINTEMP 190
@@ -558,6 +564,7 @@
#define USE_CONTROLLER_FAN
#if ENABLED(USE_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_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.)
@@ -574,10 +581,14 @@
#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
// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu)
// #define FAN_KICKSTART_TIME 100
/**
* Fan Kickstart
* When part cooling or controller fans first start, run at a speed that
* 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.
// #define FAN_OFF_PWM 1
@@ -907,6 +918,7 @@
#if DISABLED(KNUTWURST_CHIRON)
#define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (linear=mm, rotational=°) Backoff from endstops after homing
#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 HOME_Y_BEFORE_X // If G28 contains XY home Y before X
@@ -1358,7 +1370,7 @@
//
// 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)
// #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
// #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
// #define LCD_SHOW_E_TOTAL
@@ -1458,37 +1467,45 @@
// #define LED_USER_PRESET_STARTUP // Have the printer display the user preset color on startup
#endif
#if ENABLED(NEO2_COLOR_PRESETS)
#define NEO2_USER_PRESET_RED 255 // User defined RED value
#define NEO2_USER_PRESET_GREEN 128 // User defined GREEN value
#define NEO2_USER_PRESET_BLUE 0 // User defined BLUE value
#define NEO2_USER_PRESET_WHITE 255 // User defined WHITE value
#define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity
// #define NEO2_USER_PRESET_STARTUP // Have the printer display the user preset color on startup for the second strip
#define NEO2_USER_PRESET_RED 255 // User defined RED value
#define NEO2_USER_PRESET_GREEN 128 // User defined GREEN value
#define NEO2_USER_PRESET_BLUE 0 // User defined BLUE value
#define NEO2_USER_PRESET_WHITE 255 // User defined WHITE value
#define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity
// #define NEO2_USER_PRESET_STARTUP // Have the printer display the user preset color on startup for the second strip
#endif
#endif
#endif // if EITHER(HAS_DISPLAY, DWIN_LCD_PROUI)
#endif // HAS_DISPLAY || DWIN_LCD_PROUI
// LCD Print Progress options
#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
#if CAN_SHOW_REMAINING_TIME
// #define SHOW_REMAINING_TIME // Display estimated time to completion
#if ENABLED(SHOW_REMAINING_TIME)
// #define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation
// #define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time
#endif
// Add 'M73' to set print job progress, overrides Marlin's built-in estimate
// #define SET_PROGRESS_MANUALLY
#if ENABLED(SET_PROGRESS_MANUALLY)
#define SET_PROGRESS_PERCENT // Add 'P' parameter to set percentage done
#define SET_REMAINING_TIME // Add 'R' parameter to set remaining time
// #define SET_INTERACTION_TIME // Add 'C' parameter to set time until next filament change or other user interaction
// #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
#if EITHER(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI)
// #define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits
// LCD Print Progress options. Multiple times may be displayed in turn.
#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
// #define PRINT_PROGRESS_SHOW_DECIMALS // Show/report progress with decimal digits, not all UIs support this
#if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
// #define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing
#if ENABLED(LCD_PROGRESS_BAR)
#define PROGRESS_BAR_BAR_TIME 2000 // (ms) Amount of time to show the bar
#define PROGRESS_BAR_MSG_TIME 3000 // (ms) Amount of time to show the status message
#define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever)
#define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever)
// #define PROGRESS_MSG_ONCE // Show the message for MSG_TIME then clear it
// #define LCD_PROGRESS_BAR_TEST // Add a menu item to test the progress bar
#endif
@@ -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_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
@@ -1776,7 +1794,7 @@
* Adds the menu item Configuration > LCD Timeout (m) to set a wait period
* 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
@@ -1830,14 +1848,8 @@
#endif // HAS_MARLINUI_U8GLIB
#if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI
// Show SD percentage next to the progress bar
// #define SHOW_SD_PERCENT
// 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
#define MENU_HOLLOW_FRAME // Enable to save many cycles by drawing a hollow frame on Menu Screens
// #define OVERLAY_GFX_REVERSE // Swap the CW/CCW indicators in the graphics overlay
#endif
//
@@ -2098,11 +2110,16 @@
*/
#define LIN_ADVANCE
#if ENABLED(LIN_ADVANCE)
// #define EXTRA_LIN_ADVANCE_K // Enable for second linear advance constants
#define LIN_ADVANCE_K 0.0 // Unit: mm compression per 1mm/s extruder speed
// #define LA_DEBUG // If enabled, this will generate debug information output over USB.
#define EXPERIMENTAL_SCURVE // Enable this option to permit S-Curve Acceleration
// #define ALLOW_LOW_EJERK // Allow a DEFAULT_EJERK value of <10. Recommended for direct drive hotends.
#if ENABLED(DISTINCT_E_FACTORS)
#define ADVANCE_K { 0.0 } // (mm) Compression length per 1mm/s extruder speed, per extruder
#else
#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 EXPERIMENTAL_I2S_LA // Allow I2S_STEPPER_STREAM to be used with LA. Performance degrades as the LA step rate reaches ~20kHz.
#endif
// @section leveling
@@ -2580,7 +2597,7 @@
// Longer prime to clean out a SINGLENOZZLE
#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_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
#define TOOLCHANGE_FS_FAN -1 // Fan index or -1 to skip
@@ -4209,7 +4226,7 @@
/**
* 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)
#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT)

View File

@@ -307,20 +307,22 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1154)
else ifeq ($(HARDWARE_MOTHERBOARD),1155)
# Tenlog D3 Hero IDEX printer
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)
# 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)
# 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)
# 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)
# Longer LKx PRO / Alfawise Uxx Pro (PRO version)
# Longer LK1 PRO / Alfawise U20 Pro (PRO version)
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)
# Pxmalion Core I3
# Zonestar zrib V5.3 (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1163)
# Pxmalion Core I3
else ifeq ($(HARDWARE_MOTHERBOARD),1164)
#
# RAMBo and derivatives

View File

@@ -28,7 +28,7 @@
/**
* 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

View File

@@ -32,6 +32,7 @@
#include <HardwareSerial.h>
#else
#include "MarlinSerial.h"
#define BOARD_NO_NATIVE_USB
#endif
#include <stdint.h>
@@ -106,36 +107,36 @@ typedef Servo hal_servo_t;
#define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0)
#else
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
#if !WITHIN(SERIAL_PORT, 0, 3)
#error "SERIAL_PORT must be from 0 to 3."
#endif
#define MYSERIAL1 customizedSerial1
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
#error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial."
#if !WITHIN(SERIAL_PORT_2, 0, 3)
#error "SERIAL_PORT_2 must be from 0 to 3."
#endif
#define MYSERIAL2 customizedSerial2
#endif
#ifdef SERIAL_PORT_3
#if !WITHIN(SERIAL_PORT_3, -1, 3)
#error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial."
#if !WITHIN(SERIAL_PORT_3, 0, 3)
#error "SERIAL_PORT_3 must be from 0 to 3."
#endif
#define MYSERIAL3 customizedSerial3
#endif
#endif
#ifdef MMU2_SERIAL_PORT
#if !WITHIN(MMU2_SERIAL_PORT, -1, 3)
#error "MMU2_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
#if !WITHIN(MMU2_SERIAL_PORT, 0, 3)
#error "MMU2_SERIAL_PORT must be from 0 to 3"
#endif
#define MMU2_SERIAL mmuSerial
#endif
#ifdef LCD_SERIAL_PORT
#if !WITHIN(LCD_SERIAL_PORT, -1, 3)
#error "LCD_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
#if !WITHIN(LCD_SERIAL_PORT, 0, 3)
#error "LCD_SERIAL_PORT must be from 0 to 3."
#endif
#define LCD_SERIAL lcdSerial
#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);
// Calculate frequencies of test prescaler and resolution values
const uint32_t f_diff = _MAX(f, f_desired) - _MIN(f, f_desired),
f_fast_temp = (F_CPU) / (p * (1 + res_fast_temp)),
const uint16_t 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_pc_temp = (F_CPU) / (2 * p * res_pc_temp),
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

View File

@@ -293,11 +293,11 @@ enum ClockSource2 : uint8_t {
#if HAS_MOTOR_CURRENT_PWM
#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)
#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
#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
#else
#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 \
|| BTN_EN1 == N || BTN_EN2 == N \
)
#if CONF_SERIAL_IS(0)
#if SERIAL_IN_USE(0)
// D0-D1. No known conflicts.
#endif
#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__)
#if CONF_SERIAL_IS(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."
#endif
#else
#if CONF_SERIAL_IS(1) && (CHECK_SERIAL_PIN(10) || CHECK_SERIAL_PIN(11))
#error "Serial Port 1 pin D10 and/or D11 conflicts with another pin on the board."
#if SERIAL_IN_USE(1)
#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__)
#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."
#endif
#else
#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."
#endif
#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."
#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."
#endif
#undef CHECK_SERIAL_PIN

View File

@@ -210,7 +210,7 @@ public:
static void adc_init() {}
// 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!
static void adc_start(const uint8_t ch) { adc_result = analogRead(ch); }

View File

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

View File

@@ -41,7 +41,7 @@
practice, we need alignment to 256 bytes to make this work in all
cases */
__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.

View File

@@ -36,15 +36,15 @@
|| X_DIR_PIN == N || Y_DIR_PIN == N || Z_DIR_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
#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."
#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."
#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."
#endif
#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 GET_ARRAY_PIN(p) pin_array[p].pin
#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 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) && \

View File

@@ -6,14 +6,14 @@
#
import pioutil
if pioutil.is_pio_build():
import platform
current_OS = platform.system()
import platform
current_OS = platform.system()
if current_OS == 'Windows':
if current_OS == 'Windows':
Import("env")
Import("env")
# Use bossac.exe on Windows
env.Replace(
UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE"
)
# Use bossac.exe on Windows
env.Replace(
UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE"
)

View File

@@ -62,7 +62,7 @@ void usb_task_idle(void) {
// Attend SD card access from the USB MSD -- Prioritize access to improve speed
int delay = 2;
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
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) {
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);
dma.rw_pos = 0;
while (dma.rw_pos < DMA_SAMPLE_COUNT) {
// Fill with the port data post pulse_phase until the next step
if (remaining) {
if (nextMainISR && TERN1(LIN_ADVANCE, nextAdvanceISR))
i2s_push_sample();
remaining--;
}
else {
// 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 if (nextAdvanceISR == Stepper::LA_ADV_NEVER)
nextAdvanceISR = Stepper::la_interval;
#endif
if (!nextMainISR) {
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."
#endif
#if BOTH(I2S_STEPPER_STREAM, BABYSTEPPING) && DISABLED(INTEGRATED_BABYSTEPPING)
#error "BABYSTEPPING on I2S stream requires INTEGRATED_BABYSTEPPING."
#endif
#if USING_PULLDOWNS
#error "PULLDOWN pin mode is not available on ESP32 boards."
#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."
#endif

View File

@@ -32,6 +32,13 @@
#include "HAL.h"
#include "SPI.h"
#if ENABLED(SDSUPPORT)
#include "../../sd/cardreader.h"
#if ENABLED(ESP3D_WIFISUPPORT)
#include "sd_ESP32.h"
#endif
#endif
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) {
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 (msg == U8G_COM_MSG_INIT) msgInitCount--;
if (msgInitCount) return -1;

View File

@@ -318,8 +318,16 @@ void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
// Enable DMA
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
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
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);
}
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() {
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)
// 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
#endif

View File

@@ -155,6 +155,7 @@ public:
void read(uint8_t *buf, uint32_t len);
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

View File

@@ -26,7 +26,7 @@
#include "tft_spi.h"
SPIClass TFT_SPI::SPIx(1);
SPIClass TFT_SPI::SPIx(TFT_SPI_DEVICE);
void TFT_SPI::Init() {
#if PIN_EXISTS(TFT_RESET)
@@ -38,40 +38,10 @@ void TFT_SPI::Init() {
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
#endif
SET_OUTPUT(TFT_DC_PIN);
SET_OUTPUT(TFT_CS_PIN);
WRITE(TFT_DC_PIN, HIGH);
WRITE(TFT_CS_PIN, HIGH);
OUT_WRITE(TFT_DC_PIN, HIGH);
OUT_WRITE(TFT_CS_PIN, HIGH);
/**
* 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.setModule(TFT_SPI_DEVICE);
SPIx.setClock(SPI_CLOCK_MAX_TFT);
SPIx.setBitOrder(MSBFIRST);
SPIx.setDataMode(SPI_MODE0);
@@ -114,17 +84,62 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
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();
}
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

View File

@@ -27,6 +27,18 @@
#include <lpc17xx_ssp.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
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif
@@ -34,17 +46,19 @@
#define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
#endif
#define DATASIZE_8BIT SSP_DATABIT_8
#define DATASIZE_16BIT SSP_DATABIT_16
#define TFT_IO_DRIVER TFT_SPI
#define DATASIZE_8BIT SSP_DATABIT_8
#define DATASIZE_16BIT SSP_DATABIT_16
#define TFT_IO_DRIVER TFT_SPI
#define DMA_MAX_SIZE 0xFFF
#define DMA_MINC_ENABLE 1
#define DMA_MINC_DISABLE 0
#define DMA_MINC_ENABLE 1
#define DMA_MINC_DISABLE 0
class TFT_SPI {
private:
static uint32_t ReadID(uint16_t Reg);
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);
public:
@@ -56,22 +70,20 @@ public:
static void Abort();
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 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 WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &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); }
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 uint16_t Data; Data = Color;
//LPC dma can only write 0xFFF bytes at once.
#define MAX_DMA_SIZE (0xFFF - 1)
while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > MAX_DMA_SIZE ? MAX_DMA_SIZE : Count);
Count = Count > MAX_DMA_SIZE ? Count - MAX_DMA_SIZE : 0;
Transmit(DMA_MINC_DISABLE, &Color, Count > DMA_MAX_SIZE ? DMA_MAX_SIZE : Count);
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
void XPT2046::Init() {
SET_INPUT(TOUCH_MISO_PIN);
SET_OUTPUT(TOUCH_MOSI_PIN);
SET_OUTPUT(TOUCH_SCK_PIN);
#if DISABLED(TOUCH_BUTTONS_HW_SPI)
SET_INPUT(TOUCH_MISO_PIN);
SET_OUTPUT(TOUCH_MOSI_PIN);
SET_OUTPUT(TOUCH_SCK_PIN);
#endif
OUT_WRITE(TOUCH_CS_PIN, HIGH);
#if PIN_EXISTS(TOUCH_INT)

View File

@@ -9,127 +9,127 @@ from __future__ import print_function
import pioutil
if pioutil.is_pio_build():
target_filename = "FIRMWARE.CUR"
target_drive = "REARM"
target_filename = "FIRMWARE.CUR"
target_drive = "REARM"
import platform
import platform
current_OS = platform.system()
Import("env")
current_OS = platform.system()
Import("env")
def print_error(e):
print('\nUnable to find destination disk (%s)\n' \
'Please select it in platformio.ini using the upload_port keyword ' \
'(https://docs.platformio.org/en/latest/projectconf/section_env_upload.html) ' \
'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \
%(e, env.get('PIOENV')))
def print_error(e):
print('\nUnable to find destination disk (%s)\n' \
'Please select it in platformio.ini using the upload_port keyword ' \
'(https://docs.platformio.org/en/latest/projectconf/section_env_upload.html) ' \
'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \
%(e, env.get('PIOENV')))
def before_upload(source, target, env):
try:
from pathlib import Path
#
# Find a disk for upload
#
upload_disk = 'Disk not found'
target_file_found = False
target_drive_found = False
if current_OS == 'Windows':
#
# platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
# Windows - doesn't care about the disk's name, only cares about the drive letter
import subprocess,string
from ctypes import windll
from pathlib import PureWindowsPath
def before_upload(source, target, env):
try:
from pathlib import Path
#
# Find a disk for upload
#
upload_disk = 'Disk not found'
target_file_found = False
target_drive_found = False
if current_OS == 'Windows':
#
# platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
# Windows - doesn't care about the disk's name, only cares about the drive letter
import subprocess,string
from ctypes import windll
from pathlib import PureWindowsPath
# getting list of drives
# https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
drives = []
bitmask = windll.kernel32.GetLogicalDrives()
for letter in string.ascii_uppercase:
if bitmask & 1:
drives.append(letter)
bitmask >>= 1
# getting list of drives
# https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
drives = []
bitmask = windll.kernel32.GetLogicalDrives()
for letter in string.ascii_uppercase:
if bitmask & 1:
drives.append(letter)
bitmask >>= 1
for drive in drives:
final_drive_name = drive + ':'
# print ('disc check: {}'.format(final_drive_name))
try:
volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
except Exception as e:
print ('error:{}'.format(e))
continue
else:
if target_drive in volume_info and not target_file_found: # set upload if not found target file yet
target_drive_found = True
upload_disk = PureWindowsPath(final_drive_name)
if target_filename in volume_info:
if not target_file_found:
upload_disk = PureWindowsPath(final_drive_name)
target_file_found = True
for drive in drives:
final_drive_name = drive + ':'
# print ('disc check: {}'.format(final_drive_name))
try:
volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
except Exception as e:
print ('error:{}'.format(e))
continue
else:
if target_drive in volume_info and not target_file_found: # set upload if not found target file yet
target_drive_found = True
upload_disk = PureWindowsPath(final_drive_name)
if target_filename in volume_info:
if not target_file_found:
upload_disk = PureWindowsPath(final_drive_name)
target_file_found = True
elif current_OS == 'Linux':
#
# platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
#
import getpass
user = getpass.getuser()
mpath = Path('media', user)
drives = [ x for x in mpath.iterdir() if x.is_dir() ]
if target_drive in drives: # If target drive is found, use it.
target_drive_found = True
upload_disk = mpath / target_drive
else:
for drive in drives:
try:
fpath = mpath / drive
files = [ x for x in fpath.iterdir() if x.is_file() ]
except:
continue
else:
if target_filename in files:
upload_disk = mpath / drive
target_file_found = True
break
#
# set upload_port to drive if found
#
elif current_OS == 'Linux':
#
# platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
#
import getpass
user = getpass.getuser()
mpath = Path('/media', user)
drives = [ x for x in mpath.iterdir() if x.is_dir() ]
if target_drive in drives: # If target drive is found, use it.
target_drive_found = True
upload_disk = mpath / target_drive
else:
for drive in drives:
try:
fpath = mpath / drive
filenames = [ x.name for x in fpath.iterdir() if x.is_file() ]
except:
continue
else:
if target_filename in filenames:
upload_disk = mpath / drive
target_file_found = True
break
#
# set upload_port to drive if found
#
if target_file_found or target_drive_found:
env.Replace(
UPLOAD_FLAGS="-P$UPLOAD_PORT"
)
if target_file_found or target_drive_found:
env.Replace(
UPLOAD_FLAGS="-P$UPLOAD_PORT"
)
elif current_OS == 'Darwin': # MAC
#
# platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
#
dpath = Path('/Volumes') # human readable names
drives = [ x for x in dpath.iterdir() ]
if target_drive in drives and not target_file_found: # set upload if not found target file yet
target_drive_found = True
upload_disk = dpath / target_drive
for drive in drives:
try:
fpath = dpath / drive # will get an error if the drive is protected
files = [ x for x in fpath.iterdir() ]
except:
continue
else:
if target_filename in files:
if not target_file_found:
upload_disk = dpath / drive
target_file_found = True
elif current_OS == 'Darwin': # MAC
#
# platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
#
dpath = Path('/Volumes') # human readable names
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
target_drive_found = True
upload_disk = dpath / target_drive
for drive in drives:
try:
fpath = dpath / drive # will get an error if the drive is protected
filenames = [ x.name for x in fpath.iterdir() if x.is_file() ]
except:
continue
else:
if target_filename in filenames:
upload_disk = dpath / drive
target_file_found = True
break
#
# Set upload_port to drive if found
#
if target_file_found or target_drive_found:
env.Replace(UPLOAD_PORT=str(upload_disk))
print('\nUpload disk: ', upload_disk, '\n')
else:
print_error('Autodetect Error')
#
# Set upload_port to drive if found
#
if target_file_found or target_drive_found:
env.Replace(UPLOAD_PORT=str(upload_disk))
print('\nUpload disk: ', upload_disk, '\n')
else:
print_error('Autodetect Error')
except Exception as e:
print_error(str(e))
except Exception as e:
print_error(str(e))
env.AddPreAction("upload", before_upload)
env.AddPreAction("upload", before_upload)

View File

@@ -44,7 +44,7 @@
*
* 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

View File

@@ -51,7 +51,7 @@ enum XPTCoordinate : uint8_t {
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
};
#if !defined(XPT2046_Z1_THRESHOLD)
#ifndef XPT2046_Z1_THRESHOLD
#define XPT2046_Z1_THRESHOLD 10
#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 // IS_U8GLIB_ST7920
#endif // TARGET_LPC1768
#endif // __PLAT_NATIVE_SIM__

View File

@@ -1,8 +1,9 @@
/**
* Marlin 3D Printer Firmware
*
* 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
* 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/>.
*
*/
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef __SAMD51__
#include "../../inc/MarlinConfig.h"

View File

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

View File

@@ -1,8 +1,9 @@
/**
* Marlin 3D Printer Firmware
*
* 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
* 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.
*

View File

@@ -1,8 +1,9 @@
/**
* Marlin 3D Printer Firmware
*
* 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
* 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/>.
*
*/
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef ADAFRUIT_GRAND_CENTRAL_M4
/**

View File

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

View File

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

View File

@@ -1,8 +1,9 @@
/**
* Marlin 3D Printer Firmware
*
* 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
* 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
*/

View File

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

View File

@@ -1,8 +1,9 @@
/**
* Marlin 3D Printer Firmware
*
* 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
* 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/>.
*
*/
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef __SAMD51__
#include "../../inc/MarlinConfig.h"

View File

@@ -1,8 +1,9 @@
/**
* Marlin 3D Printer Firmware
*
* 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
* 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/>.
*
*/
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef __SAMD51__
#include "../../inc/MarlinConfig.h"

View File

@@ -1,8 +1,9 @@
/**
* Marlin 3D Printer Firmware
*
* 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
* 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/>.
*
*/
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef __SAMD51__
#include "../../inc/MarlinConfig.h"

View File

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

View File

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

View File

@@ -1,8 +1,9 @@
/**
* Marlin 3D Printer Firmware
*
* 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
* 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/>.
*
*/
#pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
/**
* Test SAMD51 specific configuration values for errors at compile-time.

View File

@@ -1,8 +1,9 @@
/**
* Marlin 3D Printer Firmware
*
* 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
* it under the terms of the GNU General Public License as published by
@@ -20,6 +21,10 @@
*/
#pragma once
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#define NUMBER_PINS_TOTAL PINS_COUNT
#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 GET_ARRAY_PIN(p) pin_array[p].pin
#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 IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P)!=-1)
#define pwm_status(pin) digitalPinHasPWM(pin)

View File

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

View File

@@ -1,8 +1,9 @@
/**
* Marlin 3D Printer Firmware
*
* 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
* 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/>.
*
*/
/**
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*/
#ifdef __SAMD51__
// --------------------------------------------------------------------------

View File

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

View File

@@ -95,7 +95,7 @@
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");
#endif
#endif // FLASH_EEPROM_LEVELING
static bool eeprom_data_written = false;
@@ -189,15 +189,15 @@ bool PersistentStore::access_finish() {
UNLOCK_FLASH();
uint32_t offset = 0;
uint32_t address = SLOT_ADDRESS(current_slot);
uint32_t address_end = address + MARLIN_EEPROM_SIZE;
uint32_t data = 0;
uint32_t offset = 0,
address = SLOT_ADDRESS(current_slot),
address_end = address + MARLIN_EEPROM_SIZE,
data = 0;
bool success = true;
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);
if (status == HAL_OK) {
address += sizeof(uint32_t);
@@ -221,7 +221,8 @@ bool PersistentStore::access_finish() {
return success;
#else
#else // !FLASH_EEPROM_LEVELING
// 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.
// 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());
eeprom_data_written = false;
#endif
#endif // !FLASH_EEPROM_LEVELING
}
return true;

View File

@@ -27,3 +27,8 @@
#elif EITHER(I2C_EEPROM, SPI_EEPROM)
#define USE_SHARED_EEPROM 1
#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."
#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)
#error "FLASH_EEPROM_LEVELING is currently only supported on STM32F4 hardware."
#endif
@@ -55,3 +50,62 @@
#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."
#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

@@ -102,17 +102,18 @@ const XrefInfo pin_xref[] PROGMEM = {
#define PIN_NUM_ALPHA_LEFT(P) (((P & 0x000F) < 10) ? ('0' + (P & 0x000F)) : '1')
#define PIN_NUM_ALPHA_RIGHT(P) (((P & 0x000F) > 9) ? ('0' + (P & 0x000F) - 10) : 0 )
#define PORT_NUM(P) ((P >> 4) & 0x0007)
#define PORT_ALPHA(P) ('A' + (P >> 4))
#define PORT_ALPHA(P) ('A' + (P >> 4))
/**
* 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
#endif
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS + TERN0(HAS_HIGH_ANALOG_PINS, NUM_ANALOG_INPUTS)
#define VALID_PIN(ANUM) ((ANUM) >= 0 && (ANUM) < NUMBER_PINS_TOTAL)
#define NUM_ANALOG_LAST ((NUM_ANALOG_FIRST) + (NUM_ANALOG_INPUTS) - 1)
#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 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)
@@ -168,7 +169,7 @@ bool GET_PINMODE(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;
const uint32_t ind = digitalPinToAnalogInput(Ard_num);
@@ -206,8 +207,11 @@ void port_print(const pin_t Ard_num) {
SERIAL_ECHO_SP(7);
// Print number to be used with M42
int calc_p = Ard_num % (NUM_DIGITAL_PINS + 1);
if (Ard_num > NUM_DIGITAL_PINS && calc_p > 7) calc_p += 8;
int calc_p = Ard_num;
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_CHAR(' ');
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.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
}
sw_iic.stop();
}

View File

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

View File

@@ -147,21 +147,36 @@ uint32_t TFT_FSMC::ReadID(tft_data_t Reg) {
}
bool TFT_FSMC::isBusy() {
#if defined(STM32F1xx)
volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET;
#ifdef STM32F1xx
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
#define __IS_DMA_CONFIGURED(__HANDLE__) ((__HANDLE__)->Instance->CPAR != 0)
#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
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)
Abort();
}
else
Abort();
return dmaEnabled;
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();
return false;
}
void TFT_FSMC::Abort() {
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) {
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;
HAL_DMA_Init(&DMAtx);
DataTransferBegin();

View File

@@ -41,6 +41,7 @@
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO_DRIVER TFT_FSMC
#define DMA_MAX_SIZE 0xFFFF
#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;
@@ -59,13 +60,14 @@ class TFT_FSMC {
static uint32_t ReadID(tft_data_t Reg);
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);
public:
static void Init();
static uint32_t GetID();
static bool isBusy();
static void Abort() { __HAL_DMA_DISABLE(&DMAtx); }
static void Abort();
static void DataTransferBegin(uint16_t DataWidth = TFT_DATASIZE) {}
static void DataTransferEnd() {};
@@ -73,13 +75,14 @@ class TFT_FSMC {
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 WriteSequence(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 WriteSequence_DMA(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, 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 uint16_t Data; Data = Color;
while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
Transmit(DMA_MINC_DISABLE, &Color, Count > DMA_MAX_SIZE ? DMA_MAX_SIZE : Count);
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;
}
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) {
Transmit(*Data);

View File

@@ -32,6 +32,7 @@
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO_DRIVER TFT_LTDC
#define DMA_MAX_SIZE 0xFFFF
#define TFT_DATASIZE DATASIZE_16BIT
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 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 TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
static void Transmit(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public:
static void Init();
@@ -63,13 +64,15 @@ class TFT_LTDC {
static void WriteData(uint16_t Data);
static void WriteReg(uint16_t Reg);
static void WriteSequence(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); }
// Non-blocking DMA data transfer is not implemented for LTDC interface
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 uint16_t Data; Data = Color;
while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
Transmit(DMA_PINC_DISABLE, &Color, Count > DMA_MAX_SIZE ? DMA_MAX_SIZE : Count);
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++) {
#if TFT_MISO_PIN != TFT_MOSI_PIN
//if (hspi->Init.Direction == SPI_DIRECTION_2LINES) {
while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {}
SPIx.Instance->DR = 0;
//}
while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {}
SPIx.Instance->DR = 0;
#endif
while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_RXNE)) {}
Data = (Data << 8) | SPIx.Instance->DR;
}
__HAL_SPI_DISABLE(&SPIx);
DataTransferEnd();
SPIx.Init.BaudRatePrescaler = BaudRatePrescaler;
@@ -179,36 +176,44 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
}
bool TFT_SPI::isBusy() {
#if defined(STM32F1xx)
volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET;
#ifdef STM32F1xx
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
#define __IS_DMA_CONFIGURED(__HANDLE__) ((__HANDLE__)->Instance->CPAR != 0)
#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
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)
Abort();
if (!__IS_DMA_CONFIGURED(&DMAtx)) return false;
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
Abort();
return dmaEnabled;
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();
return false;
}
void TFT_SPI::Abort() {
// Wait for any running spi
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_Abort(&DMAtx); // Abort DMA transfer if any
HAL_DMA_DeInit(&DMAtx);
HAL_SPI_DeInit(&SPIx);
// Deselect CS
DataTransferEnd();
CLEAR_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN);
DataTransferEnd(); // Stop SPI and deselect CS
}
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);
#endif
__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_BSY)) {}
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
#if TFT_MISO_PIN != TFT_MOSI_PIN
__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) {
// Wait last dma finish, to start another
while (isBusy()) { /* nada */ }
DMAtx.Init.MemInc = MemoryIncrease;
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;
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)
void TFT_SPI::TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
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
}
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 // HAS_SPI_TFT

View File

@@ -39,46 +39,47 @@
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO_DRIVER TFT_SPI
#define DMA_MAX_SIZE 0xFFFF
class TFT_SPI {
private:
static SPI_HandleTypeDef SPIx;
static DMA_HandleTypeDef DMAtx;
static uint32_t ReadID(uint16_t Reg);
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);
#if ENABLED(USE_SPI_DMA_TC)
static void TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
#endif
public:
static DMA_HandleTypeDef DMAtx;
static void Init();
static uint32_t GetID();
static bool isBusy();
static void Abort();
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 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 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)
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
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 uint16_t Data; Data = Color;
while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
Transmit(DMA_MINC_DISABLE, &Color, Count > DMA_MAX_SIZE ? DMA_MAX_SIZE : Count);
Count = Count > DMA_MAX_SIZE ? Count - DMA_MAX_SIZE : 0;
}
}
};

View File

@@ -526,23 +526,22 @@ void SPIClass::onReceive(void(*callback)()) {
_currentSetting->receiveCallback = callback;
if (callback) {
switch (_currentSetting->spi_d->clk_id) {
#if BOARD_NR_SPI >= 1
case RCC_SPI1:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi1EventCallback);
break;
#endif
#if BOARD_NR_SPI >= 2
case RCC_SPI2:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi2EventCallback);
break;
#endif
#if BOARD_NR_SPI >= 3
case RCC_SPI3:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi3EventCallback);
break;
#endif
default:
ASSERT(0);
#if BOARD_NR_SPI >= 1
case RCC_SPI1:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi1EventCallback);
break;
#endif
#if BOARD_NR_SPI >= 2
case RCC_SPI2:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi2EventCallback);
break;
#endif
#if BOARD_NR_SPI >= 3
case RCC_SPI3:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi3EventCallback);
break;
#endif
default: ASSERT(0);
}
}
else {
@@ -554,23 +553,22 @@ void SPIClass::onTransmit(void(*callback)()) {
_currentSetting->transmitCallback = callback;
if (callback) {
switch (_currentSetting->spi_d->clk_id) {
#if BOARD_NR_SPI >= 1
case RCC_SPI1:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi1EventCallback);
break;
#endif
#if BOARD_NR_SPI >= 2
case RCC_SPI2:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi2EventCallback);
break;
#endif
#if BOARD_NR_SPI >= 3
case RCC_SPI3:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi3EventCallback);
break;
#endif
default:
ASSERT(0);
#if BOARD_NR_SPI >= 1
case RCC_SPI1:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi1EventCallback);
break;
#endif
#if BOARD_NR_SPI >= 2
case RCC_SPI2:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi2EventCallback);
break;
#endif
#if BOARD_NR_SPI >= 3
case RCC_SPI3:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi3EventCallback);
break;
#endif
default: ASSERT(0);
}
}
else {

View File

@@ -33,6 +33,15 @@
#include <stdint.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
// - beginTransaction()
// - endTransaction()

View File

@@ -215,22 +215,47 @@ uint32_t TFT_FSMC::GetID() {
}
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;
}
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) {
// 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)
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);
while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {};
dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & (DMA_CCR_TEIE | DMA_CCR_TCIE)) == 0) {}
Abort();
#endif
}

View File

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

View File

@@ -26,7 +26,7 @@
#include "tft_spi.h"
SPIClass TFT_SPI::SPIx(1);
SPIClass TFT_SPI::SPIx(TFT_SPI_DEVICE);
void TFT_SPI::Init() {
#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
* 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
#else
#define SPI_CLOCK_MAX SPI_CLOCK_DIV2
@@ -62,7 +62,7 @@ void TFT_SPI::Init() {
case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
default: clock = SPI_CLOCK_DIV2; // Default from the SPI library
}
SPIx.setModule(1);
SPIx.setModule(TFT_SPI_DEVICE);
SPIx.setClockDivider(clock);
SPIx.setBitOrder(MSBFIRST);
SPIx.setDataMode(SPI_MODE0);
@@ -71,7 +71,7 @@ void TFT_SPI::Init() {
void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
SPIx.setDataSize(DataSize);
SPIx.begin();
OUT_WRITE(TFT_CS_PIN, LOW);
WRITE(TFT_CS_PIN, LOW);
}
#ifdef TFT_DEFAULT_DRIVER
@@ -113,15 +113,53 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
#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::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
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);
DataTransferEnd();
}

View File

@@ -25,6 +25,27 @@
#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
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif
@@ -32,17 +53,19 @@
#define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
#endif
#define DATASIZE_8BIT DATA_SIZE_8BIT
#define DATASIZE_16BIT DATA_SIZE_16BIT
#define TFT_IO_DRIVER TFT_SPI
#define DATASIZE_8BIT DATA_SIZE_8BIT
#define DATASIZE_16BIT DATA_SIZE_16BIT
#define TFT_IO_DRIVER TFT_SPI
#define DMA_MAX_SIZE 0xFFFF
#define DMA_MINC_ENABLE 1
#define DMA_MINC_DISABLE 0
#define DMA_MINC_ENABLE DMA_MINC_MODE
#define DMA_MINC_DISABLE 0
class TFT_SPI {
private:
static uint32_t ReadID(uint16_t Reg);
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);
public:
@@ -58,15 +81,16 @@ public:
static void DataTransferAbort();
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 WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &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); }
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 uint16_t Data; Data = Color;
while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
Transmit(DMA_MINC_DISABLE, &Color, Count > DMA_MAX_SIZE ? DMA_MAX_SIZE : Count);
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 GET_ARRAY_PIN(p) pin_array[p].pin
#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 IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && (P) <= analogInputToDigitalPin(13)) || ((P) >= analogInputToDigitalPin(14) && (P) <= analogInputToDigitalPin(17))
#define pwm_status(pin) HAL_pwm_status(pin)

View File

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

View File

@@ -33,8 +33,9 @@
void UnwPrintf(const char *format, ...) {
va_list args;
va_start( args, format );
vprintf(format, args );
va_start(args, format);
vprintf(format, args);
va_end(args);
}
#endif

View File

@@ -83,10 +83,10 @@
#else
#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
#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
#define Servo_VERSION 2 // software version of this library

View File

@@ -49,8 +49,10 @@
#include "../DUE/ServoTimers.h"
#elif defined(__SAMD51__)
#include "../SAMD51/ServoTimers.h"
#elif defined(__SAMD21__)
#include "../SAMD21/ServoTimers.h"
#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
// Macros

View File

@@ -353,7 +353,7 @@ void startOrResumeJob() {
TERN_(GCODE_REPEAT_MARKERS, repeat.reset());
TERN_(CANCEL_OBJECTS, cancelable.reset());
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();
#endif
}
@@ -582,7 +582,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
}
#endif
#if HAS_FREEZE_PIN
#if ENABLED(FREEZE_FEATURE)
stepper.frozen = READ(FREEZE_PIN) == FREEZE_STATE;
#endif

View File

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

View File

@@ -125,6 +125,8 @@
|| AXIS_DRIVER_TYPE(A,TMC2660) \
|| 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
// is considered sensitive
#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_OPENROOT_FAIL "openRoot failed"
#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_OPEN_FILE_FAIL "open failed, File: "
#define STR_SD_FILE_OPENED "File opened: "

View File

@@ -21,7 +21,7 @@
*/
#pragma once
#if !defined(__has_include)
#ifndef __has_include
#define __has_include(...) 1
#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)
// 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_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
@@ -732,6 +738,7 @@
#define MAPLIST(OP,V...) EVAL(_MAPLIST(OP,V))
// 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 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>
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_CODE(V...) CODE_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 clear(const int n) { b &= ~(bits_t)_BV(n); }
bool test(const int n) const { return TEST(b, n); }
const bool operator[](const int n) { return test(n); }
const bool operator[](const int n) const { return test(n); }
bool operator[](const int n) { return test(n); }
bool operator[](const int n) const { return test(n); }
int size() const { return sizeof(b); }
};
@@ -226,8 +228,8 @@ typedef const_float_t const_celsius_float_t;
// Helpers
#define _RECIP(N) ((N) ? 1.0f / static_cast<float>(N) : 0.0f)
#define _ABS(N) ((N) < 0 ? -(N) : (N))
#define _LS(N) (N = (T)(uint32_t(N) << v))
#define _RS(N) (N = (T)(uint32_t(N) >> v))
#define _LS(N) (N = (T)(uint32_t(N) << p))
#define _RS(N) (N = (T)(uint32_t(N) >> p))
#define FI FORCE_INLINE
// Forward declarations
@@ -307,9 +309,9 @@ typedef abce_float_t abce_pos_t;
void toLogical(xy_pos_t &raw);
void toLogical(xyz_pos_t &raw);
void toLogical(xyze_pos_t &raw);
void toNative(xy_pos_t &raw);
void toNative(xyz_pos_t &raw);
void toNative(xyze_pos_t &raw);
void toNative(xy_pos_t &lpos);
void toNative(xyz_pos_t &lpos);
void toNative(xyze_pos_t &lpos);
//
// Paired XY coordinates, counters, flags, etc.
@@ -347,6 +349,10 @@ struct XYval {
FI operator T* () { return pos; }
// If any element is true then it's true
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
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) 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 float &v) const { XYval<T> ls = *this; ls.x *= v; ls.y *= v; 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 int &v) const { XYval<T> ls = *this; ls.x *= v; ls.y *= v; 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 float &v) const { XYval<T> ls = *this; ls.x /= v; ls.y /= v; 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 int &v) const { XYval<T> ls = *this; ls.x /= v; ls.y /= v; 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 &v) 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 &v) 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 float &p) const { XYval<T> ls = *this; ls.x *= p; ls.y *= p; 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 &p) const { XYval<T> ls = *this; ls.x *= p; ls.y *= p; 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 &p) const { XYval<T> ls = *this; ls.x /= p; ls.y /= p; 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 &p) const { XYval<T> ls = *this; ls.x /= p; ls.y /= p; 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 &p) const { 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 &p) const { 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 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 float &v) { x *= v; y *= v; return *this; }
FI XYval<T>& operator*=(const int &v) { x *= v; y *= v; return *this; }
FI XYval<T>& operator>>=(const int &v) { _RS(x); _RS(y); return *this; }
FI XYval<T>& operator<<=(const int &v) { _LS(x); _LS(y); return *this; }
FI XYval<T>& operator*=(const float &p) { x *= p; y *= p; return *this; }
FI XYval<T>& operator*=(const int &p) { x *= p; y *= p; return *this; }
FI XYval<T>& operator>>=(const int &p) { _RS(x); _RS(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.
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 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 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 XYZval<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; }
#endif
#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
#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
// Length reduced to one dimension
@@ -506,6 +506,10 @@ struct XYZval {
FI operator T* () { return pos; }
// 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); }
// 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
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) 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 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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 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 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 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 &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 &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 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 &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 &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 &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.
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) { 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; }
#endif
#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
#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
// Setters taking struct types and arrays
@@ -654,11 +656,15 @@ struct XYZEval {
#endif
// Length reduced to one dimension
FI T magnitude() const { return (T)sqrtf(LOGICAL_AXIS_GANG(+ e*e, + x*x, + y*y, + z*z, + i*i, + j*j, + k*k, + u*u, + v*v, + w*w)); }
FI T magnitude() const { return (T)sqrtf(LOGICAL_AXIS_GANG(+ e*e, + x*x, + y*y, + z*z, + i*i, + j*j, + k*k, + u*u, + v*v, + w*w)); }
// Pointer to the data as a simple array
FI operator T* () { return pos; }
FI operator T* () { return pos; }
// 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
FI XYZEval<T> copy() const { XYZEval<T> v = *this; return v; }
@@ -684,76 +690,76 @@ struct XYZEval {
FI operator const XYZval<T>&() const { return *(const XYZval<T>*)this; }
// Accessor via an AxisEnum (or any integer) [index]
FI T& operator[](const int n) { return pos[n]; }
FI const T& operator[](const int n) const { return pos[n]; }
FI T& operator[](const int n) { return pos[n]; }
FI const T& operator[](const int n) const { return pos[n]; }
// Assignment operator overrides do the expected thing
FI XYZEval<T>& operator= (const T v) { set(LOGICAL_AXIS_LIST_1(v)); return *this; }
FI XYZEval<T>& operator= (const XYval<T> &rs) { set(rs.x, rs.y); return *this; }
FI XYZEval<T>& operator= (const XYZval<T> &rs) { set(NUM_AXIS_ELEM(rs)); return *this; }
FI XYZEval<T>& operator= (const T v) { set(LOGICAL_AXIS_LIST_1(v)); return *this; }
FI XYZEval<T>& operator= (const XYval<T> &rs) { set(rs.x, rs.y); return *this; }
FI XYZEval<T>& operator= (const XYZval<T> &rs) { set(NUM_AXIS_ELEM(rs)); return *this; }
// Override other operators to get intuitive behaviors
FI XYZEval<T> operator+ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
FI XYZEval<T> operator+ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
FI XYZEval<T> operator- (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
FI XYZEval<T> operator- (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
FI XYZEval<T> operator* (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
FI XYZEval<T> operator* (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
FI XYZEval<T> operator/ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
FI XYZEval<T> operator/ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
FI XYZEval<T> operator+ (const XYZval<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 XYZEval<T> operator+ (const XYZval<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 XYZEval<T> operator- (const XYZval<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 XYZEval<T> operator- (const XYZval<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 XYZEval<T> operator* (const XYZval<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 XYZEval<T> operator* (const XYZval<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 XYZEval<T> operator/ (const XYZval<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 XYZEval<T> operator/ (const XYZval<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 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) 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) 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) 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 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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 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+ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
FI XYZEval<T> operator+ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
FI XYZEval<T> operator- (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
FI XYZEval<T> operator- (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
FI XYZEval<T> operator* (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
FI XYZEval<T> operator* (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
FI XYZEval<T> operator/ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
FI XYZEval<T> operator/ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
FI XYZEval<T> operator+ (const XYZval<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 XYZEval<T> operator+ (const XYZval<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 XYZEval<T> operator- (const XYZval<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 XYZEval<T> operator- (const XYZval<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 XYZEval<T> operator* (const XYZval<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 XYZEval<T> operator* (const XYZval<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 XYZEval<T> operator/ (const XYZval<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 XYZEval<T> operator/ (const XYZval<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 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) 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) 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) 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 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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 XYZEval<T> operator-() { return LOGICAL_AXIS_ARRAY(-e, -x, -y, -z, -i, -j, -k, -u, -v, -w); }
// Modifier operators
FI XYZEval<T>& operator+=(const XYval<T> &rs) { x += rs.x; y += rs.y; return *this; }
FI XYZEval<T>& operator-=(const XYval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
FI XYZEval<T>& operator*=(const XYval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
FI XYZEval<T>& operator/=(const XYval<T> &rs) { x /= rs.x; y /= rs.y; return *this; }
FI XYZEval<T>& operator+=(const XYZval<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 XYZEval<T>& operator-=(const XYZval<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 XYZEval<T>& operator*=(const XYZval<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 XYZEval<T>& operator/=(const XYZval<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 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 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 &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 XYval<T> &rs) { x += rs.x; y += rs.y; return *this; }
FI XYZEval<T>& operator-=(const XYval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
FI XYZEval<T>& operator*=(const XYval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
FI XYZEval<T>& operator/=(const XYval<T> &rs) { x /= rs.x; y /= rs.y; return *this; }
FI XYZEval<T>& operator+=(const XYZval<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 XYZEval<T>& operator-=(const XYZval<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 XYZEval<T>& operator*=(const XYZval<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 XYZEval<T>& operator/=(const XYZval<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 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 &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 &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 &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.
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) { return !operator==(rs); }
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
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 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 XYZEval<T> &rs) const { return !operator==(rs); }
};
#undef _RECIP

View File

@@ -96,22 +96,23 @@ void BDS_Leveling::process() {
const float z_sensor = (tmp & 0x3FF) / 100.0f;
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);
if ( cur_z < config_state * 0.1f
&& config_state > 0
&& old_cur_z == cur_z
&& old_buf_z == current_position.z
&& z_sensor < (MAX_BD_HEIGHT)
) {
babystep.set_mm(Z_AXIS, cur_z - z_sensor);
#if ENABLED(DEBUG_OUT_BD)
SERIAL_ECHOLNPGM("BD:", z_sensor, ", Z:", cur_z, "|", current_position.z);
#endif
}
else {
babystep.set_mm(Z_AXIS, 0);
//if (old_cur_z <= cur_z) Z_DIR_WRITE(!INVERT_Z_DIR);
stepper.set_directions();
}
#if ENABLED(BABYSTEPPING)
if (cur_z < config_state * 0.1f
&& config_state > 0
&& old_cur_z == cur_z
&& old_buf_z == current_position.z
&& z_sensor < (MAX_BD_HEIGHT)
) {
babystep.set_mm(Z_AXIS, cur_z - z_sensor);
#if ENABLED(DEBUG_OUT_BD)
SERIAL_ECHOLNPGM("BD:", z_sensor, ", Z:", cur_z, "|", current_position.z);
#endif
}
else {
babystep.set_mm(Z_AXIS, 0); //if (old_cur_z <= cur_z) Z_DIR_WRITE(!INVERT_Z_DIR);
stepper.set_directions();
}
#endif
old_cur_z = cur_z;
old_buf_z = current_position.z;
endstops.bdp_state_update(z_sensor <= 0.01f);

View File

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

View File

@@ -260,7 +260,7 @@ bool unified_bed_leveling::sanity_check() {
*/
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")
#if HAS_HOTEND
@@ -280,7 +280,7 @@ bool unified_bed_leveling::sanity_check() {
#endif
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
"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
#if ENABLED(EXTENSIBLE_UI)
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
}
break;

View File

@@ -336,9 +336,9 @@
#if IS_SCARA
#define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
#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)
#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
#ifdef 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.y, 0, GRID_MAX_CELLS_Y);
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_x0y1 = z_values[icell.x ][icell.y+1], // z at lower right corner
z_x1y1 = z_values[icell.x+1][icell.y+1]; // z at upper right corner
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
z_x1y0 = z_values[ncellx ][icell.y], // z at upper left corner
z_x0y1 = z_values[icell.x][ncelly ], // z at lower 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_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/probe.h"
void stop();
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../core/debug_out.h"

View File

@@ -40,6 +40,9 @@ uint8_t ControllerFan::speed;
void ControllerFan::setup() {
SET_OUTPUT(CONTROLLER_FAN_PIN);
#ifdef CONTROLLER_FAN2_PIN
SET_OUTPUT(CONTROLLER_FAN2_PIN);
#endif
init();
}
@@ -72,6 +75,22 @@ void ControllerFan::update() {
? 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)
thermalManager.soft_pwm_controller_speed = speed;
#else
@@ -79,6 +98,13 @@ void ControllerFan::update() {
hal.set_pwm_duty(pin_t(CONTROLLER_FAN_PIN), speed);
else
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
}
}

View File

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

View File

@@ -49,7 +49,7 @@ class EmergencyParser {
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 {
EP_RESET,
EP_N,
@@ -58,6 +58,9 @@ public:
EP_M10, EP_M108,
EP_M11, EP_M112,
EP_M4, EP_M41, EP_M410,
#if ENABLED(SDSUPPORT)
EP_M5, EP_M52, EP_M524,
#endif
#if ENABLED(HOST_PROMPT_SUPPORT)
EP_M8, EP_M87, EP_M876, EP_M876S, EP_M876SN,
#endif
@@ -76,6 +79,10 @@ public:
static bool killed_by_M112;
static bool quickstop_by_M410;
#if ENABLED(SDSUPPORT)
static bool sd_abort_by_M524;
#endif
#if ENABLED(HOST_PROMPT_SUPPORT)
static uint8_t M876_reason;
#endif
@@ -145,6 +152,9 @@ public:
case ' ': break;
case '1': state = EP_M1; break;
case '4': state = EP_M4; break;
#if ENABLED(SDSUPPORT)
case '5': state = EP_M5; break;
#endif
#if ENABLED(HOST_PROMPT_SUPPORT)
case '8': state = EP_M8; break;
#endif
@@ -165,6 +175,11 @@ public:
case EP_M4: state = (c == '1') ? EP_M41 : 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)
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_M112: killed_by_M112 = 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)
case EP_M876SN: hostui.handle_response(M876_reason); break;
#endif

View File

@@ -111,20 +111,29 @@ void HostUI::action(FSTR_P const fstr, const bool 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);
PORT_REDIRECT(SerialMask::All);
SERIAL_CHAR(' ');
SERIAL_ECHOF(fstr);
if (pgm)
SERIAL_ECHOPGM_P(str);
else
SERIAL_ECHO(str);
if (extra_char != '\0') SERIAL_CHAR(extra_char);
SERIAL_EOL();
}
void HostUI::prompt_begin(const PromptReason reason, FSTR_P const fstr, const char extra_char/*='\0'*/) {
prompt_end();
host_prompt_reason = reason;
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_show() { prompt(F("show")); }
@@ -133,14 +142,26 @@ void HostUI::action(FSTR_P const fstr, const bool eol) {
if (btn2) prompt_button(btn2);
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*/) {
prompt_begin(reason, fstr);
_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*/) {
prompt_begin(reason, fstr, extra_char);
_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)
void HostUI::filament_load_prompt() {

View File

@@ -79,7 +79,14 @@ class HostUI {
#if ENABLED(HOST_PROMPT_SUPPORT)
private:
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(FSTR_P const btn1, FSTR_P const btn2);
@@ -93,10 +100,17 @@ class HostUI {
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_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_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, 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, 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) {
if (host_prompt_reason == PROMPT_NOT_DEFINED) prompt_do(reason, pstr, btn1, btn2);
}

View File

@@ -30,18 +30,6 @@
#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)
#include "../../feature/caselight.h"
#endif
@@ -69,6 +57,44 @@ void LEDLights::setup() {
#if ENABLED(RGBW_LED)
if (PWM_PIN(RGB_LED_W_PIN)) SET_PWM(RGB_LED_W_PIN); else SET_OUTPUT(RGB_LED_W_PIN);
#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
TERN_(NEOPIXEL_LED, neo.init());
TERN_(PCA9533, PCA9533_init());

View File

@@ -40,6 +40,18 @@
#undef _NEOPIXEL_INCLUDE_
#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
*/
@@ -107,6 +119,13 @@ typedef struct LEDColor {
class LEDLights {
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
static void setup(); // init()
@@ -142,15 +161,10 @@ public:
static LEDColor get_color() { return lights_on ? color : LEDColorOff(); }
#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)
static void toggle(); // swap "off" with color
#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); }
#endif

View File

@@ -54,7 +54,8 @@ MMU2 mmu2;
#define MMU_CMD_TIMEOUT 45000UL // 45s timeout for mmu commands (except P0)
#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)
uint8_t mmu_idl_sens = 0;
@@ -131,7 +132,7 @@ void MMU2::reset() {
safe_delay(20);
WRITE(MMU2_RST_PIN, HIGH);
#else
MMU2_COMMAND("X0"); // Send soft reset
MMU2_SEND("X0"); // Send soft reset
#endif
}
@@ -157,11 +158,9 @@ void MMU2::mmu_loop() {
case -1:
if (rx_start()) {
prev_P0_request = millis(); // Initialize finda sensor timeout
DEBUG_ECHOLNPGM("MMU => 'start'");
DEBUG_ECHOLNPGM("MMU <= 'S1'");
MMU2_COMMAND("S1"); // Read Version
MMU2_SEND("S1"); // Read Version
state = -2;
}
else if (millis() > 30000) { // 30sec after reset disable MMU
@@ -173,10 +172,8 @@ void MMU2::mmu_loop() {
case -2:
if (rx_ok()) {
sscanf(rx_buffer, "%huok\n", &version);
DEBUG_ECHOLNPGM("MMU => ", version, "\nMMU <= 'S2'");
MMU2_COMMAND("S2"); // Read Build Number
MMU2_SEND("S2"); // Read Build Number
state = -3;
}
break;
@@ -191,14 +188,12 @@ void MMU2::mmu_loop() {
#if ENABLED(MMU2_MODE_12V)
DEBUG_ECHOLNPGM("MMU <= 'M1'");
MMU2_COMMAND("M1"); // Stealth Mode
MMU2_SEND("M1"); // Stealth Mode
state = -5;
#else
DEBUG_ECHOLNPGM("MMU <= 'P0'");
MMU2_COMMAND("P0"); // Read FINDA
MMU2_SEND("P0"); // Read FINDA
state = -4;
#endif
}
@@ -209,10 +204,8 @@ void MMU2::mmu_loop() {
// response to M1
if (rx_ok()) {
DEBUG_ECHOLNPGM("MMU => ok");
DEBUG_ECHOLNPGM("MMU <= 'P0'");
MMU2_COMMAND("P0"); // Read FINDA
MMU2_SEND("P0"); // Read FINDA
state = -4;
}
break;
@@ -250,14 +243,13 @@ void MMU2::mmu_loop() {
else if (cmd == MMU_CMD_C0) {
// continue loading
DEBUG_ECHOLNPGM("MMU <= 'C0'");
MMU2_COMMAND("C0");
MMU2_SEND("C0");
state = 3; // wait for response
}
else if (cmd == MMU_CMD_U0) {
// unload current
DEBUG_ECHOLNPGM("MMU <= 'U0'");
MMU2_COMMAND("U0");
MMU2_SEND("U0");
state = 3; // wait for response
}
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) {
// recover after eject
DEBUG_ECHOLNPGM("MMU <= 'R0'");
MMU2_COMMAND("R0");
MMU2_SEND("R0");
state = 3; // wait for response
}
else if (WITHIN(cmd, MMU_CMD_F0, MMU_CMD_F0 + EXTRUDERS - 1)) {
@@ -285,7 +277,7 @@ void MMU2::mmu_loop() {
cmd = MMU_CMD_NONE;
}
else if (ELAPSED(millis(), prev_P0_request + 300)) {
MMU2_COMMAND("P0"); // Read FINDA
MMU2_SEND("P0"); // Read FINDA
state = 2; // wait for response
}
@@ -314,7 +306,7 @@ void MMU2::mmu_loop() {
if (mmu_idl_sens) {
if (FILAMENT_PRESENT() && mmu_loading_flag) {
DEBUG_ECHOLNPGM("MMU <= 'A'");
MMU2_COMMAND("A"); // send 'abort' request
MMU2_SEND("A"); // send 'abort' request
mmu_idl_sens = 0;
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;
if (keep_trying) {
// 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)");
MMU2_COMMAND("C0");
MMU2_SEND("C0");
}
#else
constexpr bool keep_trying = false;
@@ -361,7 +353,7 @@ void MMU2::mmu_loop() {
*/
bool MMU2::rx_start() {
// 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
*/
bool MMU2::rx_ok() {
if (rx_str(F("ok\n"))) {
if (MMU2_RECV("ok")) {
prev_P0_request = millis();
return true;
}
@@ -585,7 +577,7 @@ static void mmu2_not_responding() {
command(MMU_CMD_T0 + index);
manage_response(true, true);
mmu_continue_loading();
command(MMU_CMD_C0);
//command(MMU_CMD_C0);
extruder = index;
active_extruder = 0;
@@ -653,13 +645,34 @@ static void mmu2_not_responding() {
}
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++) {
DEBUG_ECHOLNPGM("Additional load attempt #", i);
if (FILAMENT_PRESENT()) break;
DEBUG_ECHOLNPGM("Load attempt #", i + 1);
// 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);
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);
}
if (!FILAMENT_PRESENT()) {
// Was the filament still missing in the last check?
if (!fil_present) {
DEBUG_ECHOLNPGM("Filament never reached sensor, runout");
filament_runout();
}
@@ -682,7 +695,7 @@ static void mmu2_not_responding() {
command(MMU_CMD_T0 + index);
manage_response(true, true);
command(MMU_CMD_C0);
extruder = index; //filament change is finished
extruder = index; // Filament change is finished
active_extruder = 0;
stepper.enable_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 (present && !mmu2s_triggered) {
DEBUG_ECHOLNPGM("MMU <= 'A'");
tx_str(F("A\n"));
MMU2_SEND("A");
}
// Slowly spin the extruder during C0
else {

View File

@@ -86,6 +86,7 @@ private:
#endif
#if ENABLED(MMU_EXTRUDER_SENSOR)
#define MMU_LOAD_FEEDRATE 19.02f // (mm/s)
static void mmu_continue_loading();
#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)
unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT);
#if ENABLED(DUAL_X_CARRIAGE)
set_duplication_enabled(saved_ext_dup_mode, saved_ext);
#endif
TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext));
// Disable the Extruder for manual change
disable_active_extruder();
@@ -593,9 +591,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
}
idle_no_sleep();
}
#if ENABLED(DUAL_X_CARRIAGE)
set_duplication_enabled(saved_ext_dup_mode, saved_ext);
#endif
TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext));
}
/**

View File

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

View File

@@ -153,6 +153,9 @@ class PrintJobRecovery {
static void prepare();
static void setup() {
#if PIN_EXISTS(OUTAGECON)
OUT_WRITE(OUTAGECON_PIN, HIGH);
#endif
#if PIN_EXISTS(POWER_LOSS)
#if ENABLED(POWER_LOSS_PULLUP)
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.");
else {
marker[index].sdpos = sdpos;
marker[index].counter = count ?: -1;
marker[index].counter = count ? count - 1 : -1;
index++;
DEBUG_ECHOLNPGM("Add Marker ", index, " at ", sdpos, " (", count, ")");
}

View File

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

View File

@@ -112,7 +112,7 @@ void GcodeSuite::M48() {
set_bed_leveling_enabled(false);
#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
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('B')) draw_area_min.y = 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*/) {

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