Merge branch 'bugfix-2.1.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.1.x-April5

This commit is contained in:
Andrew 2025-12-13 22:01:38 -05:00
commit bb730c1344
427 changed files with 8122 additions and 6616 deletions

View file

@ -41,11 +41,11 @@
]
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// , "forwardPorts": []
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",
// , "postCreateCommand": "pip3 install --user -r requirements.txt"
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
// "remoteUser": "vscode"
// , "remoteUser": "vscode"
}

View file

@ -58,7 +58,7 @@ jobs:
- at90usb1286_dfu
# AVR Extended
- FYSETC_F6
- mega2560ext
- melzi_optiboot
- rambo
- sanguino1284p

View file

@ -305,6 +305,18 @@
#endif
/**
* Differential Extruder
*
* The X and E steppers work together to create a differential drive system.
* Simple : E steps = X + E ; X steps = X (E drives a loop, X stays the same)
* Balanced: E steps = X + E/2 ; X steps = X - E/2 (Dual loop system)
*/
//#define DIFFERENTIAL_EXTRUDER
#if ENABLED(DIFFERENTIAL_EXTRUDER)
//#define BALANCED_DIFFERENTIAL_EXTRUDER
#endif
/**
* Switching Toolhead
*
@ -706,13 +718,13 @@
#if ENABLED(PID_PARAMS_PER_HOTEND)
// Specify up to one value per hotend here, according to your setup.
// If there are fewer values, the last one applies to the remaining hotends.
#define DEFAULT_Kp_LIST { 22.20, 22.20 }
#define DEFAULT_Ki_LIST { 1.08, 1.08 }
#define DEFAULT_Kd_LIST { 114.00, 114.00 }
#define DEFAULT_KP_LIST { 22.20, 22.20 }
#define DEFAULT_KI_LIST { 1.08, 1.08 }
#define DEFAULT_KD_LIST { 114.00, 114.00 }
#else
#define DEFAULT_Kp 22.20
#define DEFAULT_Ki 1.08
#define DEFAULT_Kd 114.00
#define DEFAULT_KP 22.20
#define DEFAULT_KI 1.08
#define DEFAULT_KD 114.00
#endif
#else
#define BANG_MAX 255 // Limit hotend current while in bang-bang mode; 255=full current
@ -810,9 +822,9 @@
// 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
// from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#define DEFAULT_bedKp 10.00
#define DEFAULT_bedKi 0.023
#define DEFAULT_bedKd 305.4
#define DEFAULT_BED_KP 10.00
#define DEFAULT_BED_KI 0.023
#define DEFAULT_BED_KD 305.4
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
#else
@ -893,9 +905,9 @@
// Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element
// and placed inside the small Creality printer enclosure tent.
#define DEFAULT_chamberKp 37.04
#define DEFAULT_chamberKi 1.40
#define DEFAULT_chamberKd 655.17
#define DEFAULT_CHAMBER_KP 37.04
#define DEFAULT_CHAMBER_KI 1.40
#define DEFAULT_CHAMBER_KD 655.17
// M309 P37.04 I1.04 D655.17
// FIND YOUR OWN: "M303 E-2 C8 S50" to run autotune on the chamber at 50 degreesC for 8 cycles.
@ -1053,7 +1065,8 @@
// Delta radius and diagonal rod adjustments
//#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 } // (mm)
//#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 } // (mm)
#endif
#endif // DELTA
// @section scara
@ -1109,17 +1122,37 @@
#define TPARA_LINKAGE_1 120 // (mm)
#define TPARA_LINKAGE_2 120 // (mm)
// TPARA tower offset (position of Tower relative to bed zero position)
// Height of the Shoulder axis (pivot) relative to the tower floor
#define TPARA_SHOULDER_AXIS_HEIGHT 135.0 // (mm)
// The position of the last linkage relative to the robot arm origin
// (intersection of the base axis and floor) when at the home position
#define TPARA_ARM_X_HOME_POS 28.75 // (mm) Measured from shoulder axis to tool holder axis in home position
#define TPARA_ARM_Y_HOME_POS 0 // (mm)
#define TPARA_ARM_Z_HOME_POS 250.00 // (mm) Measured from tool holder axis to the floor
// TPARA Workspace offset relative to the tower (position of workspace origin relative to robot Tower origin )
// This needs to be reasonably accurate as it defines the printbed position in the TPARA space.
#define TPARA_OFFSET_X 0 // (mm)
#define TPARA_OFFSET_Y 0 // (mm)
#define TPARA_OFFSET_Z 0 // (mm)
#define TPARA_OFFSET_X 127.0 // (mm) to coincide with minimum radius MIDDLE_DEAD_ZONE_R, and W(0,0,0) is reachable
#define TPARA_OFFSET_Y 0.0 // (mm)
#define TPARA_OFFSET_Z 0.0 // (mm)
// TPARA tool connection point offset, relative to the tool moving frame origin which is in the last linkage axis,
// (TCP: tool center/connection point) of the robot,
// the plane of measured offset must be alligned with home position plane
#define TPARA_TCP_OFFSET_X 27.0 // (mm) Tool flange: 27 (distance from pivot to bolt holes), extruder tool: 50.0,
#define TPARA_TCP_OFFSET_Y 0.0 // (mm)
#define TPARA_TCP_OFFSET_Z -65.0 // (mm) Tool flange (bottom): -6 (caution as Z 0 posiion will crash second linkage to the floor, -35 is safe for testing with no tool), extruder tool (depends on extruder): -65.0
#define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly
// Radius around the center where the arm cannot reach
#define MIDDLE_DEAD_ZONE_R 0 // (mm)
#endif
// For now use a hardcoded uniform limit, although it should be calculated, or fix a limit for each axis angle
#define MIDDLE_DEAD_ZONE_R 100 // (mm)
// Max angle between L1 and L2
#define TPARA_MAX_L1L2_ANGLE 140.0f // (degrees)
#endif // AXEL_TPARA
// @section polar
@ -1395,6 +1428,11 @@
* See https://github.com/synthetos/TinyG/wiki/Jerk-Controlled-Motion-Explained
*/
//#define S_CURVE_ACCELERATION
#if ENABLED(S_CURVE_ACCELERATION)
// Define to use 4th instead of 6th order motion curve
//#define S_CURVE_FACTOR 0.25 // Initial and final acceleration factor, ideally 0.1 to 0.4.
// Shouldn't generally require tuning.
#endif
//===========================================================================
//============================= Z Probe Options =============================
@ -1623,7 +1661,7 @@
* Nozzle-to-Probe offsets { X, Y, Z }
*
* X and Y offset
* Use a caliper or ruler to measure the distance from the tip of
* Use a caliper or ruler to measure the distance (in mm) from the tip of
* the Nozzle to the center-point of the Probe in the X and Y axes.
*
* Z offset
@ -1659,7 +1697,7 @@
* | [-] |
* O-- FRONT --+
*/
#define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 }
#define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 } // (mm) X, Y, Z distance from Nozzle tip to Probe trigger-point
// Enable and set to use a specific tool for probing. Disable to allow any tool.
#define PROBING_TOOL 0
@ -1667,6 +1705,8 @@
//#define PROBE_TOOLCHANGE_NO_MOVE // Suppress motion on probe tool-change
#endif
//#define PROBE_WAKEUP_TIME_MS 30 // (ms) Time for the probe to wake up
// Most probes should stay away from the edges of the bed, but
// with NOZZLE_AS_PROBE this can be negative for a wider probing area.
#define PROBING_MARGIN 10

View file

@ -415,14 +415,19 @@
// A well-chosen Kc value should add just enough power to melt the increased material volume.
//#define PID_EXTRUSION_SCALING
#if ENABLED(PID_EXTRUSION_SCALING)
#define DEFAULT_Kc (100) // heating power = Kc * e_speed
#define LPQ_MAX_LEN 50
#define DEFAULT_KC 100 // heating power = Kc * e_speed
#if ENABLED(PID_PARAMS_PER_HOTEND)
// Specify up to one value per hotend here, according to your setup.
// If there are fewer values, the last one applies to the remaining hotends.
#define DEFAULT_KC_LIST { DEFAULT_KC, DEFAULT_KC } // heating power = Kc * e_speed
#endif
#endif
/**
* Add an additional term to the heater power, proportional to the fan speed.
* A well-chosen Kf value should add just enough power to compensate for power-loss from the cooling fan.
* You can either just add a constant compensation with the DEFAULT_Kf value
* You can either just add a constant compensation with the DEFAULT_KF value
* or follow the instruction below to get speed-dependent compensation.
*
* Constant compensation (use only with fan speeds of 0% and 100%)
@ -453,21 +458,26 @@
#if ENABLED(PID_FAN_SCALING_ALTERNATIVE_DEFINITION)
// The alternative definition is used for an easier configuration.
// Just figure out Kf at full speed (255) and PID_FAN_SCALING_MIN_SPEED.
// DEFAULT_Kf and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly.
// DEFAULT_KF and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly.
#define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_Kf
#define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf
#define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_KF
#define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_KF
#define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING
#define DEFAULT_Kf (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED)
#define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0
#define DEFAULT_KF (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED)
#define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_KF)/255.0
#else
#define PID_FAN_SCALING_LIN_FACTOR (0) // Power-loss due to cooling = Kf * (fan_speed)
#define DEFAULT_Kf 10 // A constant value added to the PID-tuner
#define DEFAULT_KF 10 // A constant value added to the PID-tuner
#define PID_FAN_SCALING_MIN_SPEED 10 // Minimum fan speed at which to enable PID_FAN_SCALING
#endif
#endif
#if ENABLED(PID_PARAMS_PER_HOTEND)
// Specify up to one value per hotend here, according to your setup.
// If there are fewer values, the last one applies to the remaining hotends.
#define DEFAULT_KF_LIST { DEFAULT_KF, DEFAULT_KF }
#endif
#endif
/**
@ -486,15 +496,15 @@
#define AUTOTEMP
#if ENABLED(AUTOTEMP)
#define AUTOTEMP_OLDWEIGHT 0.98 // Factor used to weight previous readings (0.0 < value < 1.0)
#define AUTOTEMP_MIN 210
#define AUTOTEMP_MAX 250
#define AUTOTEMP_MIN 210
#define AUTOTEMP_MAX 250
#define AUTOTEMP_FACTOR 0.1f
// Turn on AUTOTEMP on M104/M109 by default using proportions set here
//#define AUTOTEMP_PROPORTIONAL
#if ENABLED(AUTOTEMP_PROPORTIONAL)
#define AUTOTEMP_MIN_P 0 // (°C) Added to the target temperature
#define AUTOTEMP_MAX_P 5 // (°C) Added to the target temperature
#define AUTOTEMP_FACTOR_P 1 // Apply this F parameter by default (overridden by M104/M109 F)
#define AUTOTEMP_MIN_P 0 // (°C) Added to the target temperature
#define AUTOTEMP_MAX_P 5 // (°C) Added to the target temperature
#define AUTOTEMP_FACTOR_P 1 // Apply this F parameter by default (overridden by M104/M109 F)
#endif
#endif
@ -1150,12 +1160,26 @@
#if ENABLED(FT_MOTION)
//#define FTM_IS_DEFAULT_MOTION // Use FT Motion as the factory default?
//#define FT_MOTION_MENU // Provide a MarlinUI menu to set M493 and M494 parameters
//#define FTM_HOME_AND_PROBE // Use FT Motion for homing / probing. Disable if FT Motion breaks these functions.
#define FTM_DEFAULT_DYNFREQ_MODE dynFreqMode_DISABLED // Default mode of dynamic frequency calculation. (DISABLED, Z_BASED, MASS_BASED)
//#define NO_STANDARD_MOTION // Disable the standard motion system entirely to save Flash and RAM
#if DISABLED(NO_STANDARD_MOTION)
//#define FTM_HOME_AND_PROBE // Use FT Motion for homing / probing. Disable if FT Motion breaks these functions.
#endif
#define FTM_LINEAR_ADV_DEFAULT_ENA false // Default linear advance enable (true) or disable (false)
#define FTM_LINEAR_ADV_DEFAULT_K 0.0f // Default linear advance gain. (Acceleration-based scaling factor.)
//#define FTM_DYNAMIC_FREQ // Enable for linear adjustment of XY shaping frequency according to Z or E
#if ENABLED(FTM_DYNAMIC_FREQ)
#define FTM_DEFAULT_DYNFREQ_MODE dynFreqMode_DISABLED // Default mode of dynamic frequency calculation. (DISABLED, Z_BASED, MASS_BASED)
#endif
// Disable unused shapers if you need more free space
#define FTM_SHAPER_ZV
#define FTM_SHAPER_ZVD
#define FTM_SHAPER_ZVDD
#define FTM_SHAPER_ZVDDD
#define FTM_SHAPER_EI
#define FTM_SHAPER_2HEI
#define FTM_SHAPER_3HEI
#define FTM_SHAPER_MZV
#define FTM_DEFAULT_SHAPER_X ftMotionShaper_NONE // Default shaper mode on X axis (NONE, ZV, ZVD, ZVDD, ZVDDD, EI, 2HEI, 3HEI, MZV)
#define FTM_SHAPING_DEFAULT_FREQ_X 37.0f // (Hz) Default peak frequency used by input shapers
@ -1180,6 +1204,8 @@
#define FTM_SHAPING_ZETA_E 0.03f // Zeta used by input shapers for E axis
#define FTM_SHAPING_V_TOL_E 0.05f // Vibration tolerance used by EI input shapers for E axis
//#define FTM_RESONANCE_TEST // Sine sweep motion for resonance study
//#define FTM_SMOOTHING // Smoothing can reduce artifacts and make steppers quieter
// on sharp corners, but too much will round corners.
#if ENABLED(FTM_SMOOTHING)
@ -1192,42 +1218,26 @@
// smoothing acceleration peaks, which may also smooth curved surfaces.
#endif
#define FTM_TRAJECTORY_TYPE TRAPEZOIDAL // Block acceleration profile (TRAPEZOIDAL, POLY5, POLY6)
// TRAPEZOIDAL: Continuous Velocity. Max acceleration is respected.
// POLY5: Like POLY6 with 1.5x but cpu cheaper.
// POLY6: Continuous Acceleration (aka S_CURVE).
// POLY trajectories not only reduce resonances without rounding corners, but also
// reduce extruder strain due to linear advance.
#define FTM_POLYS // Disable POLY5/6 to save ~3k of Flash. Preserves TRAPEZOIDAL.
#if ENABLED(FTM_POLYS)
#define FTM_TRAJECTORY_TYPE TRAPEZOIDAL // Block acceleration profile (TRAPEZOIDAL, POLY5, POLY6)
// TRAPEZOIDAL: Continuous Velocity. Max acceleration is respected.
// POLY5: Like POLY6 with 1.5x but uses less CPU.
// POLY6: Continuous Acceleration (aka S_CURVE).
// POLY trajectories not only reduce resonances without rounding corners, but also
// reduce extruder strain due to linear advance.
#define FTM_POLY6_ACCELERATION_OVERSHOOT 1.875f // Max acceleration overshoot factor for POLY6 (1.25 to 1.875)
#define FTM_POLY6_ACCELERATION_OVERSHOOT 1.875f // Max acceleration overshoot factor for POLY6 (1.25 to 1.875)
#endif
/**
* Advanced configuration
*/
#define FTM_UNIFIED_BWS // DON'T DISABLE unless you use Ulendo FBS (not implemented)
#if ENABLED(FTM_UNIFIED_BWS)
#define FTM_BW_SIZE 100 // Unified Window and Batch size with a ratio of 2
#else
#define FTM_WINDOW_SIZE 200 // Custom Window size for trajectory generation needed by Ulendo FBS
#define FTM_BATCH_SIZE 100 // Custom Batch size for trajectory generation needed by Ulendo FBS
#endif
#define FTM_BUFFER_SIZE 128 // Window size for trajectory generation, must be a power of 2 (e.g 64, 128, 256, ...)
// The total buffered time in seconds is (FTM_BUFFER_SIZE/FTM_FS)
#define FTM_FS 1000 // (Hz) Frequency for trajectory generation.
#define FTM_MIN_SHAPE_FREQ 20 // (Hz) Minimum shaping frequency, lower consumes more RAM
#define FTM_FS 1000 // (Hz) Frequency for trajectory generation
#if DISABLED(COREXY)
#define FTM_STEPPER_FS 20000 // (Hz) Frequency for stepper I/O update
// Use this to adjust the time required to consume the command buffer.
// Try increasing this value if stepper motion is choppy.
#define FTM_STEPPERCMD_BUFF_SIZE 3000 // Size of the stepper command buffers
#else
// CoreXY motion needs a larger buffer size. These values are based on our testing.
#define FTM_STEPPER_FS 30000
#define FTM_STEPPERCMD_BUFF_SIZE 6000
#endif
#define FTM_MIN_SHAPE_FREQ 10 // (Hz) Minimum shaping frequency, lower consumes more RAM
#endif // FT_MOTION
/**
@ -1647,7 +1657,7 @@
#if HAS_MARLINUI_U8GLIB
//#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash.
#endif
#if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, HAS_MARLINUI_HD44780)
#if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, HAS_MARLINUI_HD44780, HAS_GRAPHICAL_TFT)
//#define SHOW_CUSTOM_BOOTSCREEN // Show the bitmap in Marlin/_Bootscreen.h on startup.
#endif
#endif
@ -1803,6 +1813,14 @@
#define PE_LEDS_COMPLETED_TIME (30*60) // (seconds) Time to keep the LED "done" color before restoring normal illumination
#endif
/**
* Priming for the Remaining Time estimate
* Long processes at the start of a G-code file can skew the Remaining Time estimate.
* Enable these options to start this estimation at a later point in the G-code file.
*/
//#define REMAINING_TIME_PRIME // Provide G-code 'M75 R' to prime the Remaining Time estimate
//#define REMAINING_TIME_AUTOPRIME // Prime the Remaining Time estimate later (e.g., at the end of 'M109')
/**
* Continue after Power-Loss (Creality3D)
*
@ -1814,6 +1832,8 @@
//#define POWER_LOSS_RECOVERY
#if ENABLED(POWER_LOSS_RECOVERY)
#define PLR_ENABLED_DEFAULT false // Power-Loss Recovery enabled by default. (Set with 'M413 Sn' & M500)
//#define PLR_HEAT_BED_ON_REBOOT // Heat up bed immediately on reboot to mitigate object detaching/warping.
//#define PLR_HEAT_BED_EXTRA 0 // (°C) Relative increase of bed temperature for better adhesion (limited by max temp).
//#define PLR_BED_THRESHOLD BED_MAXTEMP // (°C) Skip user confirmation at or above this bed temperature (0 to disable)
//#define POWER_LOSS_PIN 44 // Pin to detect power-loss. Set to -1 to disable default pin on boards without module, or comment to use board default.
@ -2388,13 +2408,17 @@
* See https://marlinfw.org/docs/features/lin_advance.html for full instructions.
*/
//#define LIN_ADVANCE
#if ENABLED(LIN_ADVANCE)
#if ANY(LIN_ADVANCE, FT_MOTION)
#if ENABLED(DISTINCT_E_FACTORS)
#define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder
#define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder. Override with 'M900 T<tool> K<mm>'.
#else
#define ADVANCE_K 0.22 // (mm) Compression length applying to all extruders
#define ADVANCE_K 0.22 // (mm) Compression length for all extruders. Override with 'M900 K<mm>'.
#endif
//#define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with M900 L.
//#define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with 'M900 L'.
#endif
#if ENABLED(LIN_ADVANCE)
//#define LA_DEBUG // Print debug information to serial during operation. Disable for production use.
//#define EXPERIMENTAL_I2S_LA // Allow I2S_STEPPER_STREAM to be used with LA. Performance degrades as the LA step rate reaches ~20kHz.
@ -4106,13 +4130,17 @@
/**
* G-code Macros
*
* Add G-codes M810-M819 to define and run G-code macros.
* Macros are not saved to EEPROM.
* Add G-codes M810-M819 to define and run G-code macros
* and M820 to report the current set of macros.
* Macros are not saved to EEPROM unless enabled below.
*/
//#define GCODE_MACROS
#if ENABLED(GCODE_MACROS)
#define GCODE_MACROS_SLOTS 5 // Up to 10 may be used
#define GCODE_MACROS_SLOT_SIZE 50 // Maximum length of a single macro
#if ENABLED(EEPROM_SETTINGS)
//#define GCODE_MACROS_IN_EEPROM // Include macros in EEPROM
#endif
#endif
/**
@ -4134,22 +4162,27 @@
#define MAIN_MENU_ITEM_1_DESC "Home & UBL Info"
#define MAIN_MENU_ITEM_1_GCODE "G28\nG29 W"
//#define MAIN_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action
//#define MAIN_MENU_ITEM_1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed.
#define MAIN_MENU_ITEM_2_DESC "Preheat for " PREHEAT_1_LABEL
#define MAIN_MENU_ITEM_2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND)
//#define MAIN_MENU_ITEM_2_CONFIRM
//#define MAIN_MENU_ITEM_2_IMMEDIATE
//#define MAIN_MENU_ITEM_3_DESC "Preheat for " PREHEAT_2_LABEL
//#define MAIN_MENU_ITEM_3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND)
//#define MAIN_MENU_ITEM_3_CONFIRM
//#define MAIN_MENU_ITEM_3_IMMEDIATE
//#define MAIN_MENU_ITEM_4_DESC "Heat Bed/Home/Level"
//#define MAIN_MENU_ITEM_4_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29"
//#define MAIN_MENU_ITEM_4_CONFIRM
//#define MAIN_MENU_ITEM_4_IMMEDIATE
//#define MAIN_MENU_ITEM_5_DESC "Home & Info"
//#define MAIN_MENU_ITEM_5_GCODE "G28\nM503"
//#define MAIN_MENU_ITEM_5_CONFIRM
//#define MAIN_MENU_ITEM_5_IMMEDIATE
#endif
// @section custom config menu
@ -4166,22 +4199,27 @@
#define CONFIG_MENU_ITEM_1_DESC "Wifi ON"
#define CONFIG_MENU_ITEM_1_GCODE "M118 [ESP110] WIFI-STA pwd=12345678"
//#define CONFIG_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action
//#define CONFIG_MENU_ITEM_1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed.
#define CONFIG_MENU_ITEM_2_DESC "Bluetooth ON"
#define CONFIG_MENU_ITEM_2_GCODE "M118 [ESP110] BT pwd=12345678"
//#define CONFIG_MENU_ITEM_2_CONFIRM
//#define CONFIG_MENU_ITEM_2_IMMEDIATE
//#define CONFIG_MENU_ITEM_3_DESC "Radio OFF"
//#define CONFIG_MENU_ITEM_3_GCODE "M118 [ESP110] OFF pwd=12345678"
//#define CONFIG_MENU_ITEM_3_CONFIRM
//#define CONFIG_MENU_ITEM_3_IMMEDIATE
//#define CONFIG_MENU_ITEM_4_DESC "Wifi ????"
//#define CONFIG_MENU_ITEM_4_GCODE "M118 ????"
//#define CONFIG_MENU_ITEM_4_CONFIRM
//#define CONFIG_MENU_ITEM_4_IMMEDIATE
//#define CONFIG_MENU_ITEM_5_DESC "Wifi ????"
//#define CONFIG_MENU_ITEM_5_GCODE "M118 ????"
//#define CONFIG_MENU_ITEM_5_CONFIRM
//#define CONFIG_MENU_ITEM_5_IMMEDIATE
#endif
// @section custom buttons
@ -4198,6 +4236,7 @@
#define BUTTON1_WHEN_PRINTING false // Button allowed to trigger during printing?
#define BUTTON1_GCODE "G28"
#define BUTTON1_DESC "Homing" // Optional string to set the LCD status
//#define BUTTON1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed.
#endif
//#define BUTTON2_PIN -1
@ -4206,6 +4245,7 @@
#define BUTTON2_WHEN_PRINTING false
#define BUTTON2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND)
#define BUTTON2_DESC "Preheat for " PREHEAT_1_LABEL
//#define BUTTON2_IMMEDIATE
#endif
//#define BUTTON3_PIN -1
@ -4214,6 +4254,7 @@
#define BUTTON3_WHEN_PRINTING false
#define BUTTON3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND)
#define BUTTON3_DESC "Preheat for " PREHEAT_2_LABEL
//#define BUTTON3_IMMEDIATE
#endif
#endif

View file

@ -188,15 +188,15 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1033)
else ifeq ($(HARDWARE_MOTHERBOARD),1034)
# RAMPS 1.6+ (Power outputs: Hotend, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1035)
else ifeq ($(HARDWARE_MOTHERBOARD),1040)
# RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1036)
else ifeq ($(HARDWARE_MOTHERBOARD),1041)
# RAMPS 1.6+ (Power outputs: Hotend, Fan0, Fan1)
else ifeq ($(HARDWARE_MOTHERBOARD),1037)
else ifeq ($(HARDWARE_MOTHERBOARD),1042)
# RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1038)
else ifeq ($(HARDWARE_MOTHERBOARD),1043)
# RAMPS 1.6+ (Power outputs: Spindle, Controller Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1039)
else ifeq ($(HARDWARE_MOTHERBOARD),1044)
#
# RAMPS Derivatives - ATmega1280, ATmega2560
@ -286,60 +286,62 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1138)
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
# Creality: CR10S, CR20, CR-X
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
# Dagoma F5
# Creality CR-10 V2, CR-10 V3
else ifeq ($(HARDWARE_MOTHERBOARD),1141)
# Dagoma D6 (as found in the Dagoma DiscoUltimate V2 TMC)
# Dagoma F5
else ifeq ($(HARDWARE_MOTHERBOARD),1142)
# FYSETC F6 1.3
# Dagoma D6 (as found in the Dagoma DiscoUltimate V2 TMC)
else ifeq ($(HARDWARE_MOTHERBOARD),1143)
# FYSETC F6 1.4
# FYSETC F6 1.3
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
# Wanhao Duplicator i3 Plus
# FYSETC F6 1.4
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
# VORON Design
# Wanhao Duplicator i3 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
# Tronxy TRONXY-V3-1.0
# VORON Design
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
# Z-Bolt X Series
# Tronxy TRONXY-V3-1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
# TT OSCAR
# Z-Bolt X Series
else ifeq ($(HARDWARE_MOTHERBOARD),1149)
# BIQU Tango V1
# TT OSCAR
else ifeq ($(HARDWARE_MOTHERBOARD),1150)
# MKS GEN L V2
# BIQU Tango V1
else ifeq ($(HARDWARE_MOTHERBOARD),1151)
# MKS GEN L V2.1
# MKS GEN L V2
else ifeq ($(HARDWARE_MOTHERBOARD),1152)
# Copymaster 3D
# MKS GEN L V2.1
else ifeq ($(HARDWARE_MOTHERBOARD),1153)
# Ortur 4
# Copymaster 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1154)
# Tenlog D3 Hero IDEX printer
# Ortur 4
else ifeq ($(HARDWARE_MOTHERBOARD),1155)
# Tenlog D3, D5, D6 IDEX Printer
# 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, D5, D6 IDEX Printer
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)
# Pxmalion Core I3
# Longer LKx PRO / Alfawise Uxx Pro (PRO version)
else ifeq ($(HARDWARE_MOTHERBOARD),1162)
# Panowin Cutlass (as found in the Panowin F1)
# Pxmalion Core I3
else ifeq ($(HARDWARE_MOTHERBOARD),1163)
# Kodama Bardo V1.x (as found in the Kodama Trinus)
# Panowin Cutlass (as found in the Panowin F1)
else ifeq ($(HARDWARE_MOTHERBOARD),1164)
# XTLW MFF V1.0
# Kodama Bardo V1.x (as found in the Kodama Trinus)
else ifeq ($(HARDWARE_MOTHERBOARD),1165)
# XTLW MFF V2.0
# XTLW MFF V1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1166)
# E3D Rumba BigBox
# XTLW MFF V2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1167)
# E3D Rumba BigBox
else ifeq ($(HARDWARE_MOTHERBOARD),1168)
#
# RAMBo and derivatives
@ -408,32 +410,34 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1319)
else ifeq ($(HARDWARE_MOTHERBOARD),1320)
# Geeetech GT2560 Rev B for A20(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1321)
# Einstart retrofit
else ifeq ($(HARDWARE_MOTHERBOARD),1322)
# Wanhao 0ne+ i3 Mini
else ifeq ($(HARDWARE_MOTHERBOARD),1323)
# Overlord/Overlord Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1324)
# ADIMLab Gantry v1
else ifeq ($(HARDWARE_MOTHERBOARD),1325)
# ADIMLab Gantry v2
else ifeq ($(HARDWARE_MOTHERBOARD),1326)
# Leapfrog Xeed 2015
else ifeq ($(HARDWARE_MOTHERBOARD),1327)
# PICA Shield (original version)
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
# PICA Shield (rev C or later)
else ifeq ($(HARDWARE_MOTHERBOARD),1329)
# Intamsys 4.0 (Funmat HT)
else ifeq ($(HARDWARE_MOTHERBOARD),1330)
# Malyan M180 Mainboard Version 2 (no display function, direct G-code only)
else ifeq ($(HARDWARE_MOTHERBOARD),1331)
# Mega controller & Protoneer CNC Shield V3.00
else ifeq ($(HARDWARE_MOTHERBOARD),1332)
# WEEDO 62A board (TINA2, Monoprice Cadet, etc.)
else ifeq ($(HARDWARE_MOTHERBOARD),1333)
# Geeetech GT2560 V4.1B for A10(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1322)
# Einstart retrofit
else ifeq ($(HARDWARE_MOTHERBOARD),1323)
# Wanhao 0ne+ i3 Mini
else ifeq ($(HARDWARE_MOTHERBOARD),1324)
# Wanhao D9 MK2
else ifeq ($(HARDWARE_MOTHERBOARD),1325)
# Overlord/Overlord Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1326)
# ADIMLab Gantry v1
else ifeq ($(HARDWARE_MOTHERBOARD),1327)
# ADIMLab Gantry v2
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
# Leapfrog Xeed 2015
else ifeq ($(HARDWARE_MOTHERBOARD),1329)
# PICA Shield (original version)
else ifeq ($(HARDWARE_MOTHERBOARD),1330)
# PICA Shield (rev C or later)
else ifeq ($(HARDWARE_MOTHERBOARD),1331)
# Intamsys 4.0 (Funmat HT)
else ifeq ($(HARDWARE_MOTHERBOARD),1332)
# Malyan M180 Mainboard Version 2
else ifeq ($(HARDWARE_MOTHERBOARD),1333)
# Mega controller & Protoneer CNC Shield V3.00
else ifeq ($(HARDWARE_MOTHERBOARD),1334)
# WEEDO 62A board (TINA2, Monoprice Cadet, etc.)
else ifeq ($(HARDWARE_MOTHERBOARD),1335)
#
# ATmega1281, ATmega2561
@ -513,7 +517,7 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1511)
MCU ?= atmega1284p
PROG_MCU ?= m1284p
# ZoneStar ZMIB V2
else ifeq ($(HARDWARE_MOTHERBOARD),1511)
else ifeq ($(HARDWARE_MOTHERBOARD),1512)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
@ -627,6 +631,10 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1707)
MCU ?= at90usb1286
PROG_MCU ?= usb1286
#
# SAM3X8E ARM Cortex-M3
#
# UltiMachine Archim1 (with DRV8825 drivers)
else ifeq ($(HARDWARE_MOTHERBOARD),3023)
HARDWARE_VARIANT ?= archim

View file

@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
//#define STRING_DISTRIBUTION_DATE "2025-10-29"
//#define STRING_DISTRIBUTION_DATE "2025-12-14"
/**
* The protocol for communication to the host. Protocol indicates communication

View file

@ -119,7 +119,6 @@ void MarlinHAL::reboot() {
#if ENABLED(USE_WATCHDOG)
#include <avr/wdt.h>
#include "../../MarlinCore.h"
// Initialize watchdog with 8s timeout, if possible. Otherwise, make it 4s.
void MarlinHAL::watchdog_init() {
@ -154,7 +153,7 @@ void MarlinHAL::reboot() {
ISR(WDT_vect) {
sei(); // With the interrupt driven serial we need to allow interrupts.
SERIAL_ERROR_MSG(STR_WATCHDOG_FIRED);
minkill(); // interrupt-safe final kill and infinite loop
marlin.minkill(); // interrupt-safe final kill and infinite loop
}
#endif

View file

@ -206,7 +206,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask() {}
// Reset

View file

@ -41,7 +41,6 @@
#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
#include "MarlinSerial.h"
#include "../../MarlinCore.h"
#if ENABLED(DIRECT_STEPPING)
#include "../../feature/direct_stepping.h"

View file

@ -28,7 +28,7 @@
// ------------------------
typedef uint16_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFU
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT16_MAX)
// ------------------------
// Defines
@ -46,15 +46,14 @@ typedef uint16_t hal_timer_t;
#define MF_TIMER_TEMP 0
#endif
#define TEMP_TIMER_FREQUENCY (((F_CPU) + 0x2000) / 0x4000)
#define TEMP_TIMER_FREQUENCY (((F_CPU) + 0x2000) / 0x4000)
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_PRESCALE 8
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000)
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_PRESCALE 8
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
@ -111,8 +110,8 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
* (otherwise, characters will be lost due to UART overflow).
* Then: Stepper, Endstops, Temperature, and -finally- all others.
*/
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}
#ifndef HAL_STEP_TIMER_ISR

View file

@ -27,7 +27,6 @@
#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfig.h"
#include "../../MarlinCore.h"
#include <Wire.h>
#include "usb/usb_task.h"

View file

@ -132,7 +132,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask();
// Reset

View file

@ -31,7 +31,6 @@
#include "MarlinSerial.h"
#include "InterruptVectors.h"
#include "../../MarlinCore.h"
template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_r MarlinSerial<Cfg>::rx_buffer = { 0, 0, { 0 } };
template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_t MarlinSerial<Cfg>::tx_buffer = { 0 };

View file

@ -34,7 +34,7 @@
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFUL
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX)
#define HAL_TIMER_PRESCALER 2
#define HAL_TIMER_RATE ((F_CPU) / (HAL_TIMER_PRESCALER)) // frequency of timers peripherals
@ -52,19 +52,18 @@ typedef uint32_t hal_timer_t;
#define MF_TIMER_TONE 6 // index of timer to use for beeper tones
#endif
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of Stepper Timer ISR (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
@ -127,4 +126,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR;
}
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -0,0 +1,5 @@
# editorconfig.org
[{*.c,*.cpp,*.h}]
indent_style = tab
indent_size = 4

View file

@ -271,7 +271,7 @@ void MarlinHAL::adc_start(const pin_t pin) {
uint32_t mv;
esp_adc_cal_get_voltage((adc_channel_t)chan, &characteristics[attenuations[chan]], &mv);
adc_result = mv * isr_float_t(1023) / isr_float_t(ADC_REFERENCE_VOLTAGE) / isr_float_t(1000);
adc_result = (mv * 1023) * (1000.f / (ADC_REFERENCE_VOLTAGE));
// Change the attenuation level based on the new reading
adc_atten_t atten;

View file

@ -76,7 +76,6 @@
// Types
// ------------------------
typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs.
typedef int16_t pin_t;
typedef struct pwm_pin {
@ -194,7 +193,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask();
// Reset

View file

@ -156,38 +156,43 @@ void stepperTask(void *parameter) {
while (dma.rw_pos < DMA_SAMPLE_COUNT) {
#if ENABLED(FT_MOTION)
if (using_ftMotion) {
if (using_ftMotion) {
#if ENABLED(FT_MOTION)
if (!nextMainISR) stepper.ftMotion_stepper();
nextMainISR = 0;
}
#endif
#endif
}
else {
if (!using_ftMotion) {
if (!nextMainISR) {
stepper.pulse_phase_isr();
nextMainISR = stepper.block_phase_isr();
}
#if ENABLED(LIN_ADVANCE)
else if (!nextAdvanceISR) {
stepper.advance_isr();
nextAdvanceISR = stepper.la_interval;
#if HAS_STANDARD_MOTION
if (!nextMainISR) {
stepper.pulse_phase_isr();
nextMainISR = stepper.block_phase_isr();
}
#endif
else
i2s_push_sample();
#if ENABLED(LIN_ADVANCE)
else if (!nextAdvanceISR) {
stepper.advance_isr();
nextAdvanceISR = stepper.la_interval;
}
#endif
else
i2s_push_sample();
nextMainISR--;
nextMainISR--;
#if ENABLED(LIN_ADVANCE)
if (nextAdvanceISR == stepper.LA_ADV_NEVER)
nextAdvanceISR = stepper.la_interval;
#if ENABLED(LIN_ADVANCE)
if (nextAdvanceISR == stepper.LA_ADV_NEVER)
nextAdvanceISR = stepper.la_interval;
if (nextAdvanceISR && nextAdvanceISR != stepper.LA_ADV_NEVER)
nextAdvanceISR--;
#endif
#endif // HAS_STANDARD_MOTION
if (nextAdvanceISR && nextAdvanceISR != stepper.LA_ADV_NEVER)
nextAdvanceISR--;
#endif
}
}
}

View file

@ -30,41 +30,45 @@
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint64_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFF'FFFF'FFFF'FFFFULL
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT64_MAX)
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 0 // Timer Index for Stepper
#endif
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#define MF_TIMER_PULSE MF_TIMER_STEP // Timer Index for Pulse interval
#endif
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP 1 // Timer Index for Temperature
#endif
#ifndef MF_TIMER_PWM
#define MF_TIMER_PWM 2 // index of timer to use for PWM outputs
#define MF_TIMER_PWM 2 // Timer Index for PWM outputs
#endif
#ifndef MF_TIMER_TONE
#define MF_TIMER_TONE 3 // index of timer for beeper tones
#define MF_TIMER_TONE 3 // Timer Index for beeper tones
#endif
#define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals
#define HAL_TIMER_RATE APB_CLK_FREQ // Frequency of timer peripherals
#define TEMP_TIMER_PRESCALE 1000 // Prescaler for setting Temp Timer, 72Khz
#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency
#if ENABLED(I2S_STEPPER_STREAM)
#define STEPPER_TIMER_PRESCALE 1
#define STEPPER_TIMER_RATE 250'000 // 250khz, 4µs pulses of i2s word clock
#define STEPPER_TIMER_RATE 250'000 // 250khz, 4µs pulses of i2s word clock
#define STEPPER_TIMER_TICKS_PER_US 0.25 // (MHz) Stepper Timer ticks per µs
#else
#define STEPPER_TIMER_PRESCALE 40
#define STEPPER_TIMER_RATE ((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)) // frequency of stepper timer, 2MHz
#define STEPPER_TIMER_RATE ((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)) // (Hz) Frequency of Stepper Timer ISR, 2MHz
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1'000'000UL) // (MHz) Stepper Timer ticks per µs
#endif
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1'000'000) // stepper timer ticks per µs
#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
#define TONE_TIMER_PRESCALE 1000 // Arbitrary value, no idea what i'm doing here
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define TONE_TIMER_PRESCALE 1000 // Arbitrary value, no idea what i'm doing here
#define PWM_TIMER_PRESCALE 10
#if ENABLED(FAST_PWM_FAN)
@ -74,13 +78,9 @@ typedef uint64_t hal_timer_t;
#endif
#define MAX_PWM_PINS 32 // Number of PWM pin-slots
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
@ -135,5 +135,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -53,12 +53,15 @@ uint16_t MarlinHAL::adc_result;
// Initializes the Marlin HAL
void MarlinHAL::init() {
// Ensure F_CPU is a constant expression.
// If the compiler breaks here, it means that delay code that should compute at compile time will not work.
// So better safe than sorry here.
constexpr unsigned int cpuFreq = F_CPU;
UNUSED(cpuFreq);
#if PIN_EXISTS(LED)
OUT_WRITE(LED_PIN, LOW);
#endif
#if PIN_EXISTS(LED)
OUT_WRITE(LED_PIN, LOW);
#endif
SetTimerInterruptPriorities();

View file

@ -57,7 +57,6 @@
#define __bss_end __bss_end__
// Types
typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs.
typedef uint8_t pin_t; // Parity with mfl platform
// Servo

View file

@ -121,9 +121,10 @@ void HAL_timer_start(const uint8_t timer_number, const uint32_t frequency) {
if (is_step) {
timer.setPrescaler(STEPPER_TIMER_PRESCALE);
timer.setRolloverValue(_MIN(static_cast<hal_timer_t>(HAL_TIMER_TYPE_MAX),
(HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)),
TimerFormat::TICK);
timer.setRolloverValue(
_MIN(HAL_TIMER_TYPE_MAX, hal_timer_t((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE))),
TimerFormat::TICK
);
is_step_timer_initialized = true;
}
else {

View file

@ -29,26 +29,27 @@
// Defines
// ------------------------
// Timer configuration constants
#define STEPPER_TIMER_RATE 2000000
#define TEMP_TIMER_FREQUENCY 1000
// Timer instance definitions
#define MF_TIMER_STEP 3
#define MF_TIMER_TEMP 1
#define MF_TIMER_PULSE MF_TIMER_STEP
#define hal_timer_t uint32_t
#define HAL_TIMER_TYPE_MAX UINT16_MAX
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT16_MAX)
extern uint32_t GetStepperTimerClkFreq();
// Timer configuration constants
#define STEPPER_TIMER_RATE 2000000
#define TEMP_TIMER_FREQUENCY 1000
// Timer prescaler calculations
#define STEPPER_TIMER_PRESCALE (GetStepperTimerClkFreq() / STEPPER_TIMER_RATE) // Prescaler = 30
#define STEPPER_TIMER_PRESCALE (GetStepperTimerClkFreq() / STEPPER_TIMER_RATE) // Prescaler = 30
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs
// Pulse Timer (counter) calculations
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // Stepper timer ticks per µs
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
// Timer interrupt priorities
#define STEP_TIMER_IRQ_PRIORITY 2
@ -141,5 +142,5 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_number, const
}
}
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -67,7 +67,7 @@ public:
static void delay_ms(const int ms);
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask();
// Reset

View file

@ -83,7 +83,7 @@
#error "POSTMORTEM_DEBUGGING requires CORE_DISABLE_FAULT_HANDLER to be set."
#endif
#if defined(PANIC_ENABLE)
#ifdef PANIC_ENABLE
#if defined(PANIC_USART1_TX_PIN) || defined(PANIC_USART2_TX_PIN) || defined(PANIC_USART3_TX_PIN) || defined(PANIC_USART3_TX_PIN)
#error "HC32 HAL uses a custom panic handler. Do not define PANIC_USARTx_TX_PIN."
#endif

View file

@ -171,7 +171,7 @@ void core_hook_sysclock_init() {
panic("HRC is not 16 MHz");
}
#if defined(BOARD_XTAL_FREQUENCY)
#ifdef BOARD_XTAL_FREQUENCY
#warning "No valid XTAL frequency defined, falling back to HRC."
#endif

View file

@ -35,19 +35,19 @@ Timer0 temp_timer(&TIMER02A_config, &Temp_Handler);
*/
Timer0 step_timer(&TIMER02B_config, &Step_Handler);
void HAL_timer_start(const timer_channel_t timer_num, const uint32_t frequency) {
if (timer_num == TEMP_TIMER_NUM) {
void HAL_timer_start(const timer_channel_t timer_ch, const uint32_t frequency) {
if (timer_ch == MF_TIMER_TEMP) {
CORE_DEBUG_PRINTF("HAL_timer_start: temp timer, f=%ld\n", long(frequency));
timer_num->start(frequency, TEMP_TIMER_PRESCALE);
timer_num->setCallbackPriority(TEMP_TIMER_PRIORITY);
timer_ch->start(frequency, TEMP_TIMER_PRESCALE);
timer_ch->setCallbackPriority(TEMP_TIMER_PRIORITY);
}
else if (timer_num == STEP_TIMER_NUM) {
else if (timer_ch == MF_TIMER_STEP) {
CORE_DEBUG_PRINTF("HAL_timer_start: step timer, f=%ld\n", long(frequency));
timer_num->start(frequency, STEPPER_TIMER_PRESCALE);
timer_num->setCallbackPriority(STEP_TIMER_PRIORITY);
timer_ch->start(frequency, STEPPER_TIMER_PRESCALE);
timer_ch->setCallbackPriority(STEP_TIMER_PRIORITY);
}
else {
CORE_ASSERT_FAIL("HAL_timer_start: invalid timer_num")
CORE_ASSERT_FAIL("HAL_timer_start: invalid timer_ch")
}
}

View file

@ -27,7 +27,7 @@
//
typedef Timer0 *timer_channel_t;
typedef uint16_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFU
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT16_MAX)
//
// Timer instances
@ -54,75 +54,68 @@ extern Timer0 step_timer;
#define HAL_TIMER_RATE F_PCLK1
// Temperature timer
#define TEMP_TIMER_NUM (&temp_timer)
#define MF_TIMER_TEMP (&temp_timer)
#define TEMP_TIMER_PRIORITY DDL_IRQ_PRIORITY_02
#define TEMP_TIMER_PRESCALE 16UL // 12.5MHz
#define TEMP_TIMER_PRESCALE 16UL // 12.5MHz
#define TEMP_TIMER_RATE 1000 // 1kHz
#define TEMP_TIMER_FREQUENCY TEMP_TIMER_RATE // 1kHz also
// Stepper timer
#define STEP_TIMER_NUM (&step_timer)
#define MF_TIMER_STEP (&step_timer)
#define STEP_TIMER_PRIORITY DDL_IRQ_PRIORITY_00 // Top priority, nothing else uses it
#define STEPPER_TIMER_PRESCALE 16UL // 12.5MHz
#define STEPPER_TIMER_PRESCALE 16UL // 12.5MHz
#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // 50MHz / 16 = 3.125MHz
#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000UL) // Integer 3
#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // 50MHz / 16 = 3.125MHz
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // Integer 3
// Pulse timer (== stepper timer)
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
//
// Channel aliases
//
#define MF_TIMER_TEMP TEMP_TIMER_NUM
#define MF_TIMER_STEP STEP_TIMER_NUM
#define MF_TIMER_PULSE PULSE_TIMER_NUM
#define MF_TIMER_PULSE MF_TIMER_STEP
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
//
// HAL functions
//
void HAL_timer_start(const timer_channel_t timer_num, const uint32_t frequency);
void HAL_timer_start(const timer_channel_t timer_ch, const uint32_t frequency);
// Inlined since they are somewhat critical
#define MARLIN_HAL_TIMER_INLINE_ATTR __attribute__((always_inline)) inline
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_enable_interrupt(const timer_channel_t timer_num) {
timer_num->resume();
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_enable_interrupt(const timer_channel_t timer_ch) {
timer_ch->resume();
}
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_disable_interrupt(const timer_channel_t timer_num) {
timer_num->pause();
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_disable_interrupt(const timer_channel_t timer_ch) {
timer_ch->pause();
}
MARLIN_HAL_TIMER_INLINE_ATTR bool HAL_timer_interrupt_enabled(const timer_channel_t timer_num) {
return timer_num->isPaused();
MARLIN_HAL_TIMER_INLINE_ATTR bool HAL_timer_interrupt_enabled(const timer_channel_t timer_ch) {
return timer_ch->isPaused();
}
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_set_compare(const timer_channel_t timer_num, const hal_timer_t compare) {
timer_num->setCompareValue(compare);
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_set_compare(const timer_channel_t timer_ch, const hal_timer_t compare) {
timer_ch->setCompareValue(compare);
}
MARLIN_HAL_TIMER_INLINE_ATTR hal_timer_t HAL_timer_get_count(const timer_channel_t timer_num) {
return timer_num->getCount();
MARLIN_HAL_TIMER_INLINE_ATTR hal_timer_t HAL_timer_get_count(const timer_channel_t timer_ch) {
return timer_ch->getCount();
}
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_isr_prologue(const timer_channel_t timer_num) {
timer_num->clearInterruptFlag();
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_isr_prologue(const timer_channel_t timer_ch) {
timer_ch->clearInterruptFlag();
}
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_isr_epilogue(const timer_channel_t timer_num) {}
inline void HAL_timer_isr_epilogue(const timer_channel_t) {}
//
// HAL function aliases
//
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM);
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP);
//
// HAL ISR callbacks
@ -131,8 +124,8 @@ void Step_Handler();
void Temp_Handler();
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() void Step_Handler()
#define HAL_STEP_TIMER_ISR() void Step_Handler()
#endif
#ifndef HAL_TEMP_TIMER_ISR
#define HAL_TEMP_TIMER_ISR() void Temp_Handler()
#define HAL_TEMP_TIMER_ISR() void Temp_Handler()
#endif

View file

@ -126,7 +126,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask() {}
// Reset

View file

@ -34,7 +34,7 @@
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFUL
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX)
#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals
@ -49,21 +49,20 @@ typedef uint32_t hal_timer_t;
#endif
#define TEMP_TIMER_RATE 1000000
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of Stepper Timer ISR (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
@ -93,5 +92,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -160,7 +160,7 @@ public:
static bool watchdog_timed_out() IF_DISABLED(USE_WATCHDOG, { return false; });
static void watchdog_clear_timeout_flag() IF_DISABLED(USE_WATCHDOG, {});
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask();
// Reset

View file

@ -49,6 +49,8 @@
#include <Servo.h>
#include "../../MarlinCore.h"
class libServo: public Servo {
public:
void move(const int value) {

View file

@ -57,9 +57,9 @@
#define _HAL_TIMER_ISR(T) __HAL_TIMER_ISR(T)
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFUL
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX)
#define HAL_TIMER_RATE ((F_CPU) / 4) // frequency of timers peripherals
#define HAL_TIMER_RATE ((F_CPU) / 4) // (Hz) Frequency of timers peripherals
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 0 // Timer Index for Stepper
@ -74,22 +74,21 @@ typedef uint32_t hal_timer_t;
#define MF_TIMER_PWM 3 // Timer Index for PWM
#endif
#define TEMP_TIMER_RATE 1000000
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define TEMP_TIMER_RATE 1000000 // 1MHz
#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
@ -171,4 +170,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
}
}
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -197,7 +197,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask();
// Reset

View file

@ -28,6 +28,8 @@
#include "../shared/Marduino.h"
#include <pinmapping.h>
#define NO_COMPILE_TIME_PWM
#define SET_DIR_INPUT(IO) Gpio::setDir(IO, 1)
#define SET_DIR_OUTPUT(IO) Gpio::setDir(IO, 0)

View file

@ -34,7 +34,7 @@
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint64_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFF'FFFF'FFFF'FFFFULL
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT64_MAX)
#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals
@ -52,22 +52,21 @@ typedef uint64_t hal_timer_t;
#endif
#define SYSTICK_TIMER_FREQUENCY 1000
#define TEMP_TIMER_RATE 1'000'000
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define TEMP_TIMER_RATE 1'000'000 // (Hz) Temperature Timer count rate
#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR call frequency
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1'000'000) // stepper timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of Stepper Timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1'000'000) // (MHz) Stepper Timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
@ -88,5 +87,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -32,17 +32,123 @@
extern "C" {
#include "pico/bootrom.h"
#include "hardware/watchdog.h"
#include "pico/multicore.h"
#include "hardware/adc.h"
#include "pico/time.h"
}
#if HAS_SD_HOST_DRIVE
#include "msc_sd.h"
#include "usbd_cdc_if.h"
#endif
// Core 1 watchdog configuration
#define CORE1_MAX_RESETS 5 // Maximum number of Core 1 resets before halting system
// ------------------------
// Public Variables
// ------------------------
volatile uint32_t adc_accumulators[5] = {0}; // Accumulators for oversampling (sum of readings)
volatile uint8_t adc_counts[5] = {0}; // Count of readings accumulated per channel
volatile uint16_t adc_values[5] = {512, 512, 512, 512, 512}; // Final oversampled ADC values (averages) - initialized to mid-range
// Core 1 watchdog monitoring
volatile uint32_t core1_last_heartbeat = 0; // Timestamp of Core 1's last activity
volatile bool core1_watchdog_triggered = false; // Flag to indicate Core 1 reset
volatile uint8_t core1_reset_count = 0; // Count of Core 1 resets - halt system if >= CORE1_MAX_RESETS
volatile uint8_t current_pin;
volatile bool MarlinHAL::adc_has_result;
volatile uint8_t adc_channels_enabled[5] = {false}; // Track which ADC channels are enabled
// Helper function for LED blinking patterns
void blink_led_pattern(uint8_t blink_count, uint32_t blink_duration_us = 100000) {
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
for (uint8_t i = 0; i < blink_count; i++) {
WRITE(LED_PIN, HIGH);
busy_wait_us(blink_duration_us);
WRITE(LED_PIN, LOW);
if (i < blink_count - 1) { // Don't delay after the last blink
busy_wait_us(blink_duration_us);
}
}
#endif
}
// Core 1 ADC reading task - dynamically reads all enabled channels with oversampling
void core1_adc_task() {
static uint32_t last_led_toggle = 0;
const uint8_t OVERSAMPLENR = 16; // Standard Marlin oversampling count
// Signal successful Core 1 startup/restart
SERIAL_ECHO_MSG("Core 1 ADC task started");
while (true) {
// Update heartbeat timestamp at start of each scan cycle
core1_last_heartbeat = time_us_32();
// Scan all enabled ADC channels
for (uint8_t channel = 0; channel < 5; channel++) {
if (!adc_channels_enabled[channel]) continue;
// Enable temperature sensor if reading channel 4
if (channel == 4) {
adc_set_temp_sensor_enabled(true);
}
// Select and read the channel
adc_select_input(channel);
busy_wait_us(100); // Settling delay
adc_fifo_drain();
adc_run(true);
// Wait for conversion with timeout
uint32_t timeout = 10000;
while (adc_fifo_is_empty() && timeout--) {
busy_wait_us(1);
}
adc_run(false);
uint16_t reading = adc_fifo_is_empty() ? 0 : adc_fifo_get();
// Accumulate readings for oversampling
adc_accumulators[channel] += reading;
adc_counts[channel]++;
// Update the averaged value with current accumulation (provides immediate valid data)
adc_values[channel] = adc_accumulators[channel] / adc_counts[channel];
// When we reach the full oversampling count, reset accumulator for next cycle
if (adc_counts[channel] >= OVERSAMPLENR) {
adc_accumulators[channel] = 0;
adc_counts[channel] = 0;
}
// Disable temp sensor after reading to save power
if (channel == 4) {
adc_set_temp_sensor_enabled(false);
}
}
// Core 1 LED indicator: Double blink every 2 seconds to show Core 1 is active
uint32_t now = time_us_32();
if (now - last_led_toggle >= 2000000) { // 2 seconds
last_led_toggle = now;
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
// Triple blink pattern if watchdog was triggered (shows Core 1 was reset)
if (core1_watchdog_triggered) {
core1_watchdog_triggered = false; // Clear flag
blink_led_pattern(3); // Triple blink for watchdog reset
} else {
blink_led_pattern(2); // Normal double blink
}
#endif
}
// Delay between full scan cycles
busy_wait_us(10000); // 10ms between scans
}
}
volatile uint16_t adc_result;
// ------------------------
@ -56,7 +162,7 @@ void MarlinHAL::init() {
// Ensure F_CPU is a constant expression.
// If the compiler breaks here, it means that delay code that should compute at compile time will not work.
// So better safe than sorry here.
constexpr int cpuFreq = F_CPU;
constexpr unsigned int cpuFreq = F_CPU;
UNUSED(cpuFreq);
#if HAS_MEDIA && DISABLED(ONBOARD_SDIO) && PIN_EXISTS(SD_SS)
@ -118,9 +224,28 @@ void MarlinHAL::reboot() { watchdog_reboot(0, 0, 1); }
}
void MarlinHAL::watchdog_refresh() {
// If Core 1 has reset CORE1_MAX_RESETS+ times, stop updating watchdog to halt system
if (core1_reset_count >= CORE1_MAX_RESETS) {
SERIAL_ECHO_MSG("Core 1 reset limit exceeded (", core1_reset_count, " resets) - halting system for safety");
return; // Don't update watchdog - system will halt
}
watchdog_update();
// Check Core 1 watchdog (15 second timeout)
uint32_t now = time_us_32();
if (now - core1_last_heartbeat > 15000000) { // 15 seconds
// Core 1 appears stuck - reset it
multicore_reset_core1();
multicore_launch_core1(core1_adc_task);
core1_watchdog_triggered = true; // Signal for LED indicator
core1_reset_count++; // Increment reset counter
SERIAL_ECHO_MSG("Core 1 ADC watchdog triggered - resetting Core 1 (attempt ", core1_reset_count, ")");
}
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
TOGGLE(LED_PIN); // heartbeat indicator
// Core 0 LED indicator: Single toggle every watchdog refresh (shows Core 0 activity)
TOGGLE(LED_PIN);
#endif
}
@ -130,43 +255,35 @@ void MarlinHAL::reboot() { watchdog_reboot(0, 0, 1); }
// ADC
// ------------------------
volatile bool MarlinHAL::adc_has_result = false;
void MarlinHAL::adc_init() {
analogReadResolution(HAL_ADC_RESOLUTION);
::adc_init();
adc_fifo_setup(true, false, 1, false, false);
irq_set_exclusive_handler(ADC_IRQ_FIFO, adc_exclusive_handler);
irq_set_enabled(ADC_IRQ_FIFO, true);
adc_irq_set_enabled(true);
// Launch Core 1 for continuous ADC reading
multicore_launch_core1(core1_adc_task);
adc_has_result = true; // Results are always available with continuous sampling
}
void MarlinHAL::adc_enable(const pin_t pin) {
if (pin >= A0 && pin <= A3)
if (pin >= A0 && pin <= A3) {
adc_gpio_init(pin);
else if (pin == HAL_ADC_MCU_TEMP_DUMMY_PIN)
adc_set_temp_sensor_enabled(true);
}
void MarlinHAL::adc_start(const pin_t pin) {
adc_has_result = false;
// Select an ADC input. 0...3 are GPIOs 26...29 respectively.
adc_select_input(pin == HAL_ADC_MCU_TEMP_DUMMY_PIN ? 4 : pin - A0);
adc_run(true);
}
void MarlinHAL::adc_exclusive_handler() {
adc_run(false); // Disable since we only want one result
irq_clear(ADC_IRQ_FIFO); // Clear the IRQ
if (adc_fifo_get_level() >= 1) {
adc_result = adc_fifo_get(); // Pop the result
adc_fifo_drain();
adc_has_result = true; // Signal the end of the conversion
adc_channels_enabled[pin - A0] = true; // Mark this channel as enabled
}
else if (pin == HAL_ADC_MCU_TEMP_DUMMY_PIN) {
adc_channels_enabled[4] = true; // Mark MCU temp channel as enabled
}
}
uint16_t MarlinHAL::adc_value() { return adc_result; }
void MarlinHAL::adc_start(const pin_t pin) {
// Just store which pin we need to read - values are continuously updated by Core 1
current_pin = pin;
}
uint16_t MarlinHAL::adc_value() {
// Return the latest ADC value from Core 1's continuous readings
const uint8_t channel = (current_pin == HAL_ADC_MCU_TEMP_DUMMY_PIN) ? 4 : (current_pin - A0);
return adc_values[channel];
}
// Reset the system to initiate a firmware flash
void flashFirmware(const int16_t) { hal.reboot(); }

View file

@ -40,6 +40,11 @@
#include "msc_sd.h"
#endif
// ADC index 4 is the MCU temperature
#define HAL_ADC_MCU_TEMP_DUMMY_PIN 127
#define TEMP_SOC_PIN HAL_ADC_MCU_TEMP_DUMMY_PIN // ADC4 is internal temp sensor
#include "temp_soc.h"
//
// Serial Ports
//
@ -85,8 +90,6 @@ typedef libServo hal_servo_t;
#else
#define HAL_ADC_RESOLUTION 12
#endif
// ADC index 4 is the MCU temperature
#define HAL_ADC_MCU_TEMP_DUMMY_PIN 127
//
// Pin Mapping for M42, M43, M226
@ -141,7 +144,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask() { TERN_(HAS_SD_HOST_DRIVE, tuh_task()); }
// Reset
@ -164,9 +167,6 @@ public:
// Begin ADC sampling on the given pin. Called from Temperature::isr!
static void adc_start(const pin_t pin);
// This ADC runs a periodic task
static void adc_exclusive_handler();
// Is the ADC ready for reading?
static volatile bool adc_has_result;
static bool adc_ready() { return adc_has_result; }

View file

@ -44,15 +44,15 @@ static void TXBegin() {
#endif
}
static void TX(char b){
#if SERIAL_PORT == -1
USBSerial
#elif SERIAL_PORT == 0
USBSerial
#elif SERIAL_PORT == 1
Serial1
#endif
.write(b);
static void TX(char b) {
#if SERIAL_PORT == -1
USBSerial
#elif SERIAL_PORT == 0
USBSerial
#elif SERIAL_PORT == 1
Serial1
#endif
.write(b);
}
// A SW memory barrier, to ensure GCC does not overoptimize loops

View file

@ -31,28 +31,48 @@
// NOTE: The Bigtreetech SKR Pico has an onboard W25Q16 flash module
// Use EEPROM.h for compatibility, for now.
#include <EEPROM.h>
// RP2040 Flash-based EEPROM emulation using internal flash memory
#include <hardware/flash.h>
#include <hardware/sync.h>
static bool eeprom_data_written = false;
// Flash sector size is already defined in hardware/flash.h as FLASH_SECTOR_SIZE
// Place EEPROM emulation at the end of flash, before the filesystem
// This assumes 2MB flash, adjust if using different flash size
#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE)
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE size_t(E2END + 1)
#endif
static uint8_t eeprom_buffer[MARLIN_EEPROM_SIZE];
static bool eeprom_data_written = false;
static bool eeprom_initialized = false;
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
bool PersistentStore::access_start() {
EEPROM.begin(); // Avoid EEPROM.h warning (do nothing)
eeprom_buffer_fill();
if (!eeprom_initialized) {
// Read from flash into buffer
const uint8_t *flash_data = (const uint8_t *)(XIP_BASE + FLASH_TARGET_OFFSET);
memcpy(eeprom_buffer, flash_data, MARLIN_EEPROM_SIZE);
eeprom_initialized = true;
}
return true;
}
bool PersistentStore::access_finish() {
if (eeprom_data_written) {
TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT());
hal.isr_off();
eeprom_buffer_flush();
hal.isr_on();
// Disable interrupts during flash write
const uint32_t intstate = save_and_disable_interrupts();
// Erase and program the sector
flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE);
flash_range_program(FLASH_TARGET_OFFSET, eeprom_buffer, MARLIN_EEPROM_SIZE);
// Restore interrupts
restore_interrupts(intstate);
TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT());
eeprom_data_written = false;
}
@ -62,8 +82,8 @@ bool PersistentStore::access_finish() {
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
while (size--) {
uint8_t v = *value;
if (v != eeprom_buffered_read_byte(pos)) {
eeprom_buffered_write_byte(pos, v);
if (pos < (int)MARLIN_EEPROM_SIZE && v != eeprom_buffer[pos]) {
eeprom_buffer[pos] = v;
eeprom_data_written = true;
}
crc16(crc, &v, 1);
@ -75,7 +95,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
const uint8_t c = eeprom_buffered_read_byte(pos);
const uint8_t c = (pos < (int)MARLIN_EEPROM_SIZE) ? eeprom_buffer[pos] : 0xFF;
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

View file

@ -25,7 +25,7 @@
#include "HAL.h"
#ifndef NUM_DIGITAL_PINS
#error "Expected NUM_DIGITAL_PINS not found"
#error "Expected NUM_DIGITAL_PINS not found."
#endif
/**
@ -74,6 +74,27 @@
* signal. The Arduino pin number is listed by the M43 I command.
*/
/**
* Pins Debugging for RP2040
*
* - NUMBER_PINS_TOTAL
* - MULTI_NAME_PAD
* - getPinByIndex(index)
* - printPinNameByIndex(index)
* - getPinIsDigitalByIndex(index)
* - digitalPinToAnalogIndex(pin)
* - getValidPinMode(pin)
* - isValidPin(pin)
* - isAnalogPin(pin)
* - digitalRead_mod(pin)
* - pwm_status(pin)
* - printPinPWM(pin)
* - printPinPort(pin)
* - printPinNumber(pin)
* - printPinAnalog(pin)
*/
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
#define NUM_ANALOG_FIRST A0
#define MODE_PIN_INPUT 0 // Input mode (reset state)
@ -81,66 +102,66 @@
#define MODE_PIN_ALT 2 // Alternate function mode
#define MODE_PIN_ANALOG 3 // Analog mode
#define PIN_NUM(P) (P & 0x000F)
#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 getPinByIndex(x) pin_array[x].pin
#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define getPinIsDigitalByIndex(x) pin_array[x].is_digital
#define digitalPinToAnalogIndex(P) digital_pin_to_analog_pin(P)
/**
* Translation of routines & variables used by pinsDebug.h
*/
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
#define VALID_PIN(ANUM) (pin_t(ANUM) >= 0 && pin_t(ANUM) < NUMBER_PINS_TOTAL)
#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)
#define DIGITAL_PIN_TO_ANALOG_PIN(ANUM) -1 // will report analog pin number in the print port routine
uint8_t get_pin_mode(const pin_t pin) {
// Check if pin is in alternate function mode (I2C, SPI, etc.)
const uint32_t gpio_func = gpio_get_function(pin);
// x is a variable used to search pin_array
#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital)
#define GET_ARRAY_PIN(x) ((pin_t) pin_array[x].pin)
#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin
uint8_t get_pin_mode(const pin_t Ard_num) {
uint dir = gpio_get_dir( Ard_num);
if (dir) return MODE_PIN_OUTPUT;
else return MODE_PIN_INPUT;
// GPIO_FUNC_I2C is typically function 3 on RP2040
if ( gpio_func == GPIO_FUNC_I2C
|| gpio_func == GPIO_FUNC_SPI
|| gpio_func == GPIO_FUNC_UART
|| gpio_func == GPIO_FUNC_PWM
) {
return MODE_PIN_ALT;
}
// For GPIO mode, check direction
return gpio_get_dir(pin) ? MODE_PIN_OUTPUT : MODE_PIN_INPUT;
}
bool getValidPinMode(const pin_t Ard_num) {
const uint8_t pin_mode = get_pin_mode(Ard_num);
bool getValidPinMode(const pin_t pin) {
const uint8_t pin_mode = get_pin_mode(pin);
return pin_mode == MODE_PIN_OUTPUT || pin_mode == MODE_PIN_ALT; // assume all alt definitions are PWM
}
int8_t digital_pin_to_analog_pin(pin_t Ard_num) {
Ard_num -= NUM_ANALOG_FIRST;
return (Ard_num >= 0 && Ard_num < NUM_ANALOG_INPUTS) ? Ard_num : -1;
#define isValidPin(P) WITHIN(P, 0, pin_t(NUMBER_PINS_TOTAL - 1))
int8_t digital_pin_to_analog_pin(pin_t pin) {
pin -= NUM_ANALOG_FIRST;
return (WITHIN(pin, 0, NUM_ANALOG_INPUTS - 1)) ? pin : -1;
}
bool isAnalogPin(const pin_t Ard_num) {
return digital_pin_to_analog_pin(Ard_num) != -1;
bool isAnalogPin(const pin_t pin) {
return digital_pin_to_analog_pin(pin) != -1;
}
bool is_digital(const pin_t x) {
const uint8_t pin_mode = get_pin_mode(x);
return pin_mode == MODE_PIN_INPUT || pin_mode == MODE_PIN_OUTPUT;
#define digitalRead_mod(A) extDigitalRead(A) // must use Arduino pin numbers when doing reads
#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3d "), P); SERIAL_ECHO(buffer); }while(0)
#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0)
#define MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin
//bool is_digital(const pin_t pin) {
// const uint8_t pin_mode = get_pin_mode(pin);
// return pin_mode == MODE_PIN_INPUT || pin_mode == MODE_PIN_OUTPUT;
//}
bool pwm_status(const pin_t pin) {
// Check if this pin is configured for PWM
return PWM_PIN(pin) && get_pin_mode(pin) == MODE_PIN_ALT;
}
void printPinPort(const pin_t Ard_num) {
SERIAL_ECHOPGM("Pin: ");
SERIAL_ECHO(Ard_num);
}
bool pwm_status(const pin_t Ard_num) {
return get_pin_mode(Ard_num) == MODE_PIN_ALT;
}
void printPinPWM(const pin_t Ard_num) {
if (PWM_PIN(Ard_num)) {
void printPinPWM(const pin_t pin) {
if (pwm_status(pin)) {
// RP2040 has hardware PWM on specific pins
char buffer[22];
sprintf_P(buffer, PSTR("PWM: pin %d "), pin);
SERIAL_ECHO(buffer);
}
}
void printPinPort(const pin_t pin) {}

View file

@ -0,0 +1,30 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// RP2040 internal temperature sensor
// Formula: T = 27 - (ADC_voltage - 0.706) / 0.001721
// ADC_voltage = (RAW / OVERSAMPLENR) * 3.3 / 4096 (RAW is accumulated over OVERSAMPLENR samples)
// T = 27 - ((RAW / OVERSAMPLENR) * 3.3 / 4096 - 0.706) / 0.001721
// Simplified: T = 437.423 - (RAW / OVERSAMPLENR) * 0.46875
#define TEMP_SOC_SENSOR(RAW) (437.423f - ((RAW) / OVERSAMPLENR) * 0.46875f)

View file

@ -41,7 +41,7 @@
#define _HAL_TIMER_ISR(T) __HAL_TIMER_ISR(T)
typedef uint64_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFF'FFFF'FFFF'FFFFULL
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT64_MAX)
#define HAL_TIMER_RATE (1'000'000ULL) // fixed value as we use a microsecond timesource
#ifndef MF_TIMER_STEP
@ -58,21 +58,20 @@ typedef uint64_t hal_timer_t;
#endif
#define TEMP_TIMER_RATE HAL_TIMER_RATE
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency
#define STEPPER_TIMER_RATE HAL_TIMER_RATE / 10 // 100khz roughly
#define STEPPER_TIMER_TICKS_PER_US (0.1) // fixed value as we use a microsecond timesource
#define STEPPER_TIMER_PRESCALE (10)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
@ -86,10 +85,10 @@ typedef uint64_t hal_timer_t;
//#define STEP_TIMER_PTR _HAL_TIMER(MF_TIMER_STEP)
//#define TEMP_TIMER_PTR _HAL_TIMER(MF_TIMER_TEMP)
extern alarm_pool_t* HAL_timer_pool_0;
extern alarm_pool_t* HAL_timer_pool_1;
extern alarm_pool_t* HAL_timer_pool_2;
extern alarm_pool_t* HAL_timer_pool_3;
extern alarm_pool_t *HAL_timer_pool_0;
extern alarm_pool_t *HAL_timer_pool_1;
extern alarm_pool_t *HAL_timer_pool_2;
extern alarm_pool_t *HAL_timer_pool_3;
extern struct repeating_timer HAL_timer_0;
@ -120,28 +119,23 @@ void HAL_timer_stop(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, hal_timer_t compare) {
if (timer_num == MF_TIMER_STEP){
if (compare == HAL_TIMER_TYPE_MAX){
HAL_timer_stop(timer_num);
return;
}
if (timer_num == MF_TIMER_STEP && compare == HAL_TIMER_TYPE_MAX) {
HAL_timer_stop(timer_num);
return;
}
compare = compare *10; //Dirty fix, figure out a proper way
compare *= 10; // Dirty fix, figure out a proper way
switch (timer_num) {
case 0:
alarm_pool_add_alarm_in_us(HAL_timer_pool_0, compare, HAL_timer_alarm_pool_0_callback, 0, false);
break;
case 1:
alarm_pool_add_alarm_in_us(HAL_timer_pool_1, compare, HAL_timer_alarm_pool_1_callback, 0, false);
break;
case 2:
alarm_pool_add_alarm_in_us(HAL_timer_pool_2, compare, HAL_timer_alarm_pool_2_callback, 0, false);
break;
case 3:
alarm_pool_add_alarm_in_us(HAL_timer_pool_3, compare, HAL_timer_alarm_pool_3_callback, 0, false);
break;
@ -151,27 +145,20 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, hal_time
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
return 0;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
if (timer_num == MF_TIMER_STEP) return 0ull;
return time_us_64();
}
FORCE_INLINE static void HAL_timer_enable_interrupt(const uint8_t timer_num) {
HAL_timer_irq_en[timer_num] = 1;
}
FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) {
HAL_timer_irq_en[timer_num] = 0;
}
FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
return HAL_timer_irq_en[timer_num]; //lucky coincidence that timer_num and rp2040 irq num matches
return HAL_timer_irq_en[timer_num]; // Lucky coincidence that timer_num and rp2040 IRQ num matches
}
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
return;
}
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -0,0 +1,28 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* RP2040 LCD-specific defines
*/
uint8_t u8g_com_rp2040_ssd_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); // u8g_com_rp2040_ssd_i2c.cpp
#define U8G_COM_SSD_I2C_HAL u8g_com_rp2040_ssd_i2c_fn

View file

@ -0,0 +1,108 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* 2-Wire I2C COM Driver
*
* Handles Hardware I2C on valid pin combinations.
* Wire library is used for Hardware I2C.
*
* Hardware I2C uses pins defined in pins_arduino.h.
*/
#ifdef __PLAT_RP2040__
#include "../../../inc/MarlinConfig.h"
#if HAS_U8GLIB_I2C_OLED
#include <U8glib-HAL.h>
#include <Wire.h>
#ifndef MASTER_ADDRESS
#define MASTER_ADDRESS 0x01
#endif
/**
* BUFFER_LENGTH is defined in libraries\Wire\utility\WireBase.h
* Default value is 32
* Increase this value to 144 to send U8G_COM_MSG_WRITE_SEQ in single block
*/
#ifndef BUFFER_LENGTH
#define BUFFER_LENGTH 32
#endif
#if BUFFER_LENGTH > 144
#error "BUFFER_LENGTH should not be greater than 144."
#endif
#define I2C_MAX_LENGTH (BUFFER_LENGTH - 1)
uint8_t u8g_com_rp2040_ssd_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
// Hardware I2C flag
//static bool i2c_initialized = false; // Flag to only run init/linking code once
//if (!i2c_initialized) { // Init runtime linkages
// i2c_initialized = true; // Only do this once
//}
static uint8_t control;
// Use the global Wire instance (already initialized with correct pins for RP2040)
switch (msg) {
case U8G_COM_MSG_INIT:
Wire.setClock(400000);
// Wire already initialized in MarlinUI::init(), no need to call begin() again
break;
case U8G_COM_MSG_ADDRESS: // Define cmd (arg_val = 0) or data mode (arg_val = 1)
control = arg_val ? 0x40 : 0x00;
break;
case U8G_COM_MSG_WRITE_BYTE:
::Wire.beginTransmission(0x3C);
::Wire.write(control);
::Wire.write(arg_val);
::Wire.endTransmission();
break;
case U8G_COM_MSG_WRITE_SEQ: {
uint8_t* dataptr = (uint8_t*)arg_ptr;
while (arg_val > 0) {
::Wire.beginTransmission(0x3C);
::Wire.write(control);
if (arg_val <= I2C_MAX_LENGTH) {
::Wire.write(dataptr, arg_val);
arg_val = 0;
}
else {
::Wire.write(dataptr, I2C_MAX_LENGTH);
arg_val -= I2C_MAX_LENGTH;
dataptr += I2C_MAX_LENGTH;
}
::Wire.endTransmission();
}
break;
}
}
return 1;
}
#endif // HAS_U8GLIB_I2C_OLED
#endif // __PLAT_RP2040__

View file

@ -144,7 +144,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask() {}
// Reset

View file

@ -165,7 +165,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
tc->COUNT32.INTENCLR.reg = TC_INTENCLR_OVF; // disable overflow interrupt
// TCn clock setup
GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)) ;
GCLK->CLKCTRL.reg = uint16_t(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5));
SYNC (GCLK->STATUS.bit.SYNCBUSY);
tcReset(tc); // reset TC

View file

@ -33,7 +33,7 @@
// --------------------------------------------------------------------------
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFUL
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX)
#define HAL_TIMER_RATE F_CPU // frequency of timers peripherals
@ -49,15 +49,14 @@ typedef uint32_t hal_timer_t;
#define MF_TIMER_TEMP MF_TIMER_RTC // Timer Index for Temperature
#endif
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000) // stepper timer ticks per µs
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of Stepper Timer ISR (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000) // (MHz) Stepper Timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
@ -143,9 +142,8 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
Rtc * const rtc = timer_config[timer_num].pRtc;
// Clear interrupt flag
rtc->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0| RTC_MODE0_INTFLAG_OVF;
}
else if (timer_config[timer_num].type == TimerType::tcc){
else if (timer_config[timer_num].type == TimerType::tcc) {
Tcc * const tc = timer_config[timer_num].pTcc;
// Clear interrupt flag
tc->INTFLAG.reg = TCC_INTFLAG_OVF;
@ -157,4 +155,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
}
}
#define HAL_timer_isr_epilogue(timer_num)
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -121,7 +121,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask() {}
// Reset

View file

@ -32,7 +32,7 @@
// --------------------------------------------------------------------------
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFUL
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX)
#define HAL_TIMER_RATE F_CPU // frequency of timers peripherals
@ -48,15 +48,14 @@ typedef uint32_t hal_timer_t;
#define MF_TIMER_TEMP MF_TIMER_RTC // Timer Index for Temperature
#endif
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000) // stepper timer ticks per µs
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of Stepper Timer ISR (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000) // (MHz) Stepper Timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
@ -145,4 +144,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
}
}
#define HAL_timer_isr_epilogue(timer_num)
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -66,7 +66,7 @@ void MarlinHAL::init() {
// Ensure F_CPU is a constant expression.
// If the compiler breaks here, it means that delay code that should compute at compile time will not work.
// So better safe than sorry here.
constexpr int cpuFreq = F_CPU;
constexpr unsigned int cpuFreq = F_CPU;
UNUSED(cpuFreq);
#if HAS_MEDIA && DISABLED(ONBOARD_SDIO) && PIN_EXISTS(SD_SS)
@ -114,7 +114,7 @@ void MarlinHAL::idletask() {
void MarlinHAL::reboot() { NVIC_SystemReset(); }
uint8_t MarlinHAL::get_reset_source() {
return
return (
#ifdef RCC_FLAG_IWDGRST // Some sources may not exist...
RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) ? RST_WATCHDOG :
#endif
@ -134,7 +134,7 @@ uint8_t MarlinHAL::get_reset_source() {
RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) ? RST_POWER_ON :
#endif
0
;
);
}
void MarlinHAL::clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }

View file

@ -63,8 +63,6 @@
// Types
// ------------------------
typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs.
typedef int32_t pin_t; // Parity with platform/ststm32
class libServo;
@ -157,7 +155,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask();
// Reset

View file

@ -136,10 +136,8 @@ const XrefInfo pin_xref[] PROGMEM = {
#define printPinNumber(Q)
#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0)
#define digitalPinToAnalogIndex(P) -1 // will report analog pin number in the print port routine
// x is a variable used to search pin_array
#define getPinIsDigitalByIndex(x) ((bool) pin_array[x].is_digital)
#define getPinByIndex(x) ((pin_t) pin_array[x].pin)
#define getPinIsDigitalByIndex(x) bool(pin_array[x].is_digital)
#define getPinByIndex(x) pin_t(pin_array[x].pin)
#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin
@ -229,8 +227,7 @@ void printPinPort(const pin_t pin) {
calc_p -= NUM_ANALOG_FIRST;
if (calc_p > 7) calc_p += 8;
}
SERIAL_ECHOPGM(" M42 P", calc_p);
SERIAL_CHAR(' ');
SERIAL_ECHO(F(" M42 P"), calc_p, C(' '));
if (calc_p < 100) {
SERIAL_CHAR(' ');
if (calc_p < 10)

View file

@ -141,7 +141,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
*/
timer_instance[timer_num]->setPrescaleFactor(STEPPER_TIMER_PRESCALE); //the -1 is done internally
timer_instance[timer_num]->setOverflow(_MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* /frequency */), TICK_FORMAT);
timer_instance[timer_num]->setOverflow(_MIN(HAL_TIMER_TYPE_MAX, hal_timer_t((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* / frequency */)), TICK_FORMAT);
break;
case MF_TIMER_TEMP: // TEMP TIMER - any available 16bit timer
timer_instance[timer_num] = new HardwareTimer(TEMP_TIMER_DEV);

View file

@ -38,7 +38,7 @@
// of adding a run-time check and HAL_TIMER_TYPE_MAX is refactored to allow unique
// values for each timer.
#define hal_timer_t uint32_t
#define HAL_TIMER_TYPE_MAX UINT16_MAX
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT16_MAX)
// Marlin timer_instance[] content (unrelated to timer selection)
#define MF_TIMER_STEP 0 // Timer Index for Stepper
@ -51,20 +51,20 @@
#define TEMP_TIMER_FREQUENCY 1000 // Temperature::isr() is expected to be called at around 1kHz
// TODO: get rid of manual rate/prescale/ticks/cycles taken for procedures in stepper.cpp
#define STEPPER_TIMER_RATE 2000000 // 2 Mhz
#define STEPPER_TIMER_RATE 2'000'000 // 2 Mhz
extern uint32_t GetStepperTimerClkFreq();
#define STEPPER_TIMER_PRESCALE (GetStepperTimerClkFreq() / (STEPPER_TIMER_RATE))
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
// Pulse Timer (counter) calculations
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
extern void Step_Handler();
@ -116,5 +116,5 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const ha
}
}
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -187,7 +187,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask();
// Reset

View file

@ -29,8 +29,6 @@ uint8_t ServoCount = 0;
#include "Servo.h"
//#include "Servo.h"
#include <boards.h>
#include <io.h>
#include <pwm.h>

View file

@ -47,14 +47,14 @@ static uint8_t ram_eeprom[MARLIN_EEPROM_SIZE] __attribute__((aligned(4))) = {0};
static bool eeprom_dirty = false;
bool PersistentStore::access_start() {
const uint32_t *source = reinterpret_cast<const uint32_t*>(EEPROM_PAGE0_BASE);
uint32_t *destination = reinterpret_cast<uint32_t*>(ram_eeprom);
const uint32_t *src = reinterpret_cast<const uint32_t*>(EEPROM_PAGE0_BASE);
uint32_t *dst = reinterpret_cast<uint32_t*>(ram_eeprom);
static_assert(0 == (MARLIN_EEPROM_SIZE) % 4, "MARLIN_EEPROM_SIZE is corrupted. (Must be a multiple of 4.)"); // Ensure copying as uint32_t is safe
constexpr size_t eeprom_size_u32 = (MARLIN_EEPROM_SIZE) / 4;
for (size_t i = 0; i < eeprom_size_u32; ++i, ++destination, ++source)
*destination = *source;
for (size_t i = 0; i < eeprom_size_u32; ++i, ++dst, ++src)
*dst = *src;
eeprom_dirty = false;
return true;
@ -80,9 +80,9 @@ bool PersistentStore::access_finish() {
status = FLASH_ErasePage(EEPROM_PAGE1_BASE);
if (status != FLASH_COMPLETE) ACCESS_FINISHED(true);
const uint16_t *source = reinterpret_cast<const uint16_t*>(ram_eeprom);
for (size_t i = 0; i < long(MARLIN_EEPROM_SIZE); i += 2, ++source) {
if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + i, *source) != FLASH_COMPLETE)
const uint16_t *src = reinterpret_cast<const uint16_t*>(ram_eeprom);
for (size_t i = 0; i < long(MARLIN_EEPROM_SIZE); i += 2, ++src) {
if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + i, *src) != FLASH_COMPLETE)
ACCESS_FINISHED(false);
}

View file

@ -84,7 +84,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timer_set_prescaler(STEP_TIMER_DEV, (uint16_t)(STEPPER_TIMER_PRESCALE - 1));
timer_set_reload(STEP_TIMER_DEV, 0xFFFF);
timer_oc_set_mode(STEP_TIMER_DEV, STEP_TIMER_CHAN, TIMER_OC_MODE_FROZEN, TIMER_OC_NO_PRELOAD); // no output pin change
timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (STEPPER_TIMER_RATE) / frequency));
timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, _MIN(HAL_TIMER_TYPE_MAX, hal_timer_t((STEPPER_TIMER_RATE) / frequency)));
timer_no_ARR_preload_ARPE(STEP_TIMER_DEV); // Need to be sure no preload on ARR register
timer_attach_interrupt(STEP_TIMER_DEV, STEP_TIMER_CHAN, stepTC_Handler);
HAL_timer_set_interrupt_priority(MF_TIMER_STEP, STEP_TIMER_IRQ_PRIO);
@ -97,7 +97,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timer_set_count(TEMP_TIMER_DEV, 0);
timer_set_prescaler(TEMP_TIMER_DEV, (uint16_t)(TEMP_TIMER_PRESCALE - 1));
timer_set_reload(TEMP_TIMER_DEV, 0xFFFF);
timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (F_CPU) / (TEMP_TIMER_PRESCALE) / frequency));
timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, _MIN(HAL_TIMER_TYPE_MAX, hal_timer_t((F_CPU) / (TEMP_TIMER_PRESCALE) / frequency)));
timer_attach_interrupt(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, tempTC_Handler);
HAL_timer_set_interrupt_priority(MF_TIMER_TEMP, TEMP_TIMER_IRQ_PRIO);
timer_generate_update(TEMP_TIMER_DEV);

View file

@ -40,7 +40,7 @@
*/
typedef uint16_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFU
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT16_MAX)
#define HAL_TIMER_RATE uint32_t(F_CPU) // frequency of timers peripherals
@ -95,27 +95,26 @@ typedef uint16_t hal_timer_t;
#define TEMP_TIMER_IRQ_PRIO 3
#define SERVO0_TIMER_IRQ_PRIO 1
#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define TEMP_TIMER_PRESCALE 1000 // Prescaler for setting Temp Timer, 72Khz
#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency
#define STEPPER_TIMER_PRESCALE 18 // prescaler for setting stepper timer, 4Mhz
#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define STEPPER_TIMER_PRESCALE 18 // Prescaler for setting stepper timer, 4Mhz
#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // (Hz) Frequency of Stepper Timer ISR
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
timer_dev* HAL_get_timer_dev(int number);
#define TIMER_DEV(num) HAL_get_timer_dev(num)
#define STEP_TIMER_DEV TIMER_DEV(MF_TIMER_STEP)
#define TEMP_TIMER_DEV TIMER_DEV(MF_TIMER_TEMP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() timer_enable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN)
#define ENABLE_TEMPERATURE_INTERRUPT() timer_enable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN)
#define DISABLE_TEMPERATURE_INTERRUPT() timer_disable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN)
#define HAL_timer_get_count(timer_num) timer_get_count(TIMER_DEV(timer_num))
@ -188,7 +187,7 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
}
}
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}
// No command is available in framework to turn off ARPE bit, which is turned on by default in libmaple.
// Needed here to reset ARPE=0 for stepper timer

View file

@ -142,7 +142,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask() {}
// Reset

View file

@ -31,7 +31,5 @@ class libServo : public Servo {
void move(const int value);
private:
typedef Servo super;
uint16_t min_ticks;
uint16_t max_ticks;
uint8_t servoIndex; // index into the channel data for this servo
};

View file

@ -34,7 +34,7 @@
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFUL
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX)
#define FTM0_TIMER_PRESCALE 8
#define FTM1_TIMER_PRESCALE 4
@ -58,26 +58,25 @@ typedef uint32_t hal_timer_t;
#define TEMP_TIMER_FREQUENCY 1000
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000)
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler()
#define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr()
#endif
#ifndef HAL_TEMP_TIMER_ISR
#define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler()
#define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr()
#endif
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
@ -110,4 +109,4 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
void HAL_timer_isr_prologue(const uint8_t timer_num);
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -147,7 +147,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask() {}
// Reset

View file

@ -35,7 +35,5 @@ class libServo : public Servo {
void move(const int value);
private:
typedef Servo super;
uint16_t min_ticks;
uint16_t max_ticks;
uint8_t servoIndex; // Index into the channel data for this servo
};

View file

@ -34,7 +34,7 @@
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFUL
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX)
#define FTM0_TIMER_PRESCALE 8
#define FTM1_TIMER_PRESCALE 4
@ -58,19 +58,18 @@ typedef uint32_t hal_timer_t;
#define TEMP_TIMER_FREQUENCY 1000
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000)
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
@ -110,4 +109,4 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
void HAL_timer_isr_prologue(const uint8_t timer_num);
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -160,7 +160,7 @@ public:
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
// Tasks, called from marlin.idle()
static void idletask() {}
// Reset

View file

@ -37,7 +37,5 @@ class libServo : public PWMServo {
private:
typedef PWMServo super;
uint8_t servoPin;
uint16_t min_ticks;
uint16_t max_ticks;
uint8_t servoIndex; // Index into the channel data for this servo
};

View file

@ -30,41 +30,82 @@
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
switch (timer_num) {
//
// Step Timer GPT1 - Compare Interrupt OCR1 - Reset Mode
//
case MF_TIMER_STEP:
CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // turn off 24mhz mode
// 24MHz mode off Use peripheral clock (150MHz)
CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL;
// Enable GPT1 clock gating
CCM_CCGR1 |= CCM_CCGR1_GPT1_BUS(CCM_CCGR_ON);
GPT1_CR = 0; // disable timer
GPT1_SR = 0x3F; // clear all prior status
GPT1_PR = GPT1_TIMER_PRESCALE - 1;
GPT1_CR |= GPT_CR_CLKSRC(1); //clock selection #1 (peripheral clock = 150 MHz)
GPT1_CR |= GPT_CR_ENMOD; //reset count to zero before enabling
GPT1_CR |= GPT_CR_OM1(1); // toggle mode
GPT1_OCR1 = (GPT1_TIMER_RATE / frequency) -1; // Initial compare value
GPT1_IR = GPT_IR_OF1IE; // Compare3 value
GPT1_CR |= GPT_CR_EN; //enable GPT2 counting at 150 MHz
// Disable timer, clear all status bits
GPT1_CR = 0; // Disable timer
GPT1_SR = 0x3F; // Clear all prior status
OUT_WRITE(15, HIGH);
// Prescaler = 2 => 75MHz counting clock
GPT1_PR = GPT1_TIMER_PRESCALE - 1;
GPT1_CR = GPT_CR_CLKSRC(1) // Clock selection #1 (peripheral clock = 150 MHz)
| GPT_CR_ENMOD // Reset count to zero before enabling
| GPT_CR_OM2(TERN(MARLIN_DEV_MODE, 1, 0)); // 0 = edge compare, 1 = toggle
// Compare value the number of clocks between edges
GPT1_OCR1 = (GPT1_TIMER_RATE / frequency) - 1;
// Enable compareevent interrupt
GPT1_IR = GPT_IR_OF1IE; // OF1 interrupt enabled
// Pull Pin 15 HIGH (logichigh is the “idle” state)
TERN_(MARLIN_DEV_MODE, OUT_WRITE(15, HIGH));
// Attach and enable Stepper IRQ
// Note: UART priority is 16
attachInterruptVector(IRQ_GPT1, &stepTC_Handler);
NVIC_SET_PRIORITY(IRQ_GPT1, 16);
NVIC_SET_PRIORITY(IRQ_GPT1, 16); // Priority 16 (higher than Temp Timer)
// Start GPT1 counting at 150 MHz
GPT1_CR |= GPT_CR_EN;
break;
//
// Temperature Timer GPT2 - Compare Interrupt OCR1 - Reset Mode
//
case MF_TIMER_TEMP:
CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // turn off 24mhz mode
// 24MHz mode off Use peripheral clock (150MHz)
CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL;
// Enable GPT2 clock gating
CCM_CCGR0 |= CCM_CCGR0_GPT2_BUS(CCM_CCGR_ON);
GPT2_CR = 0; // disable timer
GPT2_SR = 0x3F; // clear all prior status
GPT2_PR = GPT2_TIMER_PRESCALE - 1;
GPT2_CR |= GPT_CR_CLKSRC(1); //clock selection #1 (peripheral clock = 150 MHz)
GPT2_CR |= GPT_CR_ENMOD; //reset count to zero before enabling
GPT2_CR |= GPT_CR_OM1(1); // toggle mode
GPT2_OCR1 = (GPT2_TIMER_RATE / frequency) -1; // Initial compare value
GPT2_IR = GPT_IR_OF1IE; // Compare3 value
GPT2_CR |= GPT_CR_EN; //enable GPT2 counting at 150 MHz
// Disable timer, clear all status bits
GPT2_CR = 0; // Disable timer
GPT2_SR = 0x3F; // Clear all prior status
OUT_WRITE(14, HIGH);
// Prescaler = 10 => 15MHz counting clock
GPT2_PR = GPT2_TIMER_PRESCALE - 1;
GPT2_CR = GPT_CR_CLKSRC(1) // Clock selection #1 (peripheral clock = 150 MHz)
| GPT_CR_ENMOD // and reset count to zero before enabling
| GPT_CR_OM2(TERN(MARLIN_DEV_MODE, 1, 0)); // 0 = edge compare, 1 = toggle
// Compare value the number of clocks between edges
GPT2_OCR1 = (GPT2_TIMER_RATE / frequency) - 1;
// Enable compareevent interrupt
GPT2_IR = GPT_IR_OF1IE; // OF1 interrupt enabled
// Pull Pin 14 HIGH (logichigh is the “idle” state)
TERN_(MARLIN_DEV_MODE, OUT_WRITE(14, HIGH));
// Attach Temperature ISR
attachInterruptVector(IRQ_GPT2, &tempTC_Handler);
NVIC_SET_PRIORITY(IRQ_GPT2, 32);
NVIC_SET_PRIORITY(IRQ_GPT2, 32); // Priority 32 (lower than Step Timer)
// Start GPT2 counting at 150 MHz
GPT2_CR |= GPT_CR_EN;
break;
}
}
@ -82,6 +123,7 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) {
case MF_TIMER_TEMP: NVIC_DISABLE_IRQ(IRQ_GPT2); break;
}
// Ensure the CPU actually stops servicing the IRQ
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
asm volatile("dsb");
@ -97,8 +139,8 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
void HAL_timer_isr_prologue(const uint8_t timer_num) {
switch (timer_num) {
case MF_TIMER_STEP: GPT1_SR = GPT_IR_OF1IE; break; // clear OF3 bit
case MF_TIMER_TEMP: GPT2_SR = GPT_IR_OF1IE; break; // clear OF3 bit
case MF_TIMER_STEP: GPT1_SR = GPT_IR_OF1IE; break; // clear OF1
case MF_TIMER_TEMP: GPT2_SR = GPT_IR_OF1IE; break;
}
asm volatile("dsb");
}

View file

@ -34,7 +34,7 @@
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFEUL
#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX-1UL)
#define GPT_TIMER_RATE (F_CPU / 4) // 150MHz (Can't use F_BUS_ACTUAL because it's extern volatile)
@ -57,20 +57,19 @@ typedef uint32_t hal_timer_t;
#define TEMP_TIMER_RATE 1000000
#define TEMP_TIMER_FREQUENCY 1000
#define HAL_TIMER_RATE GPT1_TIMER_RATE
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000)
#define STEPPER_TIMER_PRESCALE ((GPT_TIMER_RATE / 1000000) / STEPPER_TIMER_TICKS_PER_US)
#define HAL_TIMER_RATE GPT1_TIMER_RATE
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL)
#define STEPPER_TIMER_PRESCALE (GPT_TIMER_RATE / STEPPER_TIMER_RATE)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
@ -89,8 +88,16 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
switch (timer_num) {
case MF_TIMER_STEP: GPT1_OCR1 = compare - 1; break;
case MF_TIMER_TEMP: GPT2_OCR1 = compare - 1; break;
case MF_TIMER_STEP:
GPT1_CR |= GPT_CR_FRR; // Free Run Mode (setting OCRx preserves CNT)
GPT1_OCR1 = compare - 1;
GPT1_CR &= ~GPT_CR_FRR; // Reset Mode (CNT resets on trigger)
break;
case MF_TIMER_TEMP:
GPT2_CR |= GPT_CR_FRR; // Free Run Mode (setting OCRx preserves CNT)
GPT2_OCR1 = compare - 1;
GPT2_CR &= ~GPT_CR_FRR; // Reset Mode (CNT resets on trigger)
break;
}
}
@ -115,5 +122,4 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
void HAL_timer_isr_prologue(const uint8_t timer_num);
//void HAL_timer_isr_epilogue(const uint8_t timer_num) {}
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -74,11 +74,11 @@
#endif
#if HAS_DWIN_E3V2
#include "lcd/e3v2/common/encoder.h"
#include "lcd/dwin/common/encoder.h"
#if ENABLED(DWIN_CREALITY_LCD)
#include "lcd/e3v2/creality/dwin.h"
#include "lcd/dwin/creality/dwin.h"
#elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
#include "lcd/e3v2/jyersui/dwin.h"
#include "lcd/dwin/jyersui/dwin.h"
#elif ENABLED(SOVOL_SV06_RTS)
#include "lcd/sovol_rts/sovol_rts.h"
#endif
@ -160,15 +160,6 @@
#include "feature/spindle_laser.h"
#endif
#if HAS_MEDIA
CardReader card;
#endif
#if ENABLED(G38_PROBE_TARGET)
uint8_t G38_move; // = 0
bool G38_did_trigger; // = false
#endif
#if ENABLED(DELTA)
#include "module/delta.h"
#elif ENABLED(POLARGRAPH)
@ -269,33 +260,51 @@
#include "feature/rs485.h"
#endif
/**
* Spin in place here while keeping temperature processing alive
*/
void safe_delay(millis_t ms) {
while (ms > 50) {
ms -= 50;
delay(50);
thermalManager.task();
}
delay(ms);
thermalManager.task(); // This keeps us safe if too many small safe_delay() calls are made
}
// Singleton for Marlin global data and methods
Marlin marlin;
// Marlin static data
#if ENABLED(CONFIGURABLE_MACHINE_NAME)
MString<64> Marlin::machine_name;
#endif
// Global state of the firmware
MarlinState Marlin::state = MF_INITIALIZING;
// For M109 and M190, this flag may be cleared (by M108) to exit the wait loop
bool Marlin::wait_for_heatup = false;
#if !HAS_MEDIA
CardReader card; // Stub instance with "no media" methods
#endif
PGMSTR(M112_KILL_STR, "M112 Shutdown");
#if ENABLED(CONFIGURABLE_MACHINE_NAME)
MString<64> machine_name;
#endif
MarlinState marlin_state = MarlinState::MF_INITIALIZING;
// For M109 and M190, this flag may be cleared (by M108) to exit the wait loop
bool wait_for_heatup = false;
// For M0/M1, this flag may be cleared (by M108) to exit the wait-for-user loop
#if HAS_RESUME_CONTINUE
bool wait_for_user; // = false
bool Marlin::wait_for_user; // = false
void wait_for_user_response(millis_t ms/*=0*/, const bool no_sleep/*=false*/) {
void Marlin::wait_for_user_response(millis_t ms/*=0*/, const bool no_sleep/*=false*/) {
UNUSED(no_sleep);
KEEPALIVE_STATE(PAUSED_FOR_USER);
wait_for_user = true;
wait_start();
if (ms) ms += millis(); // expire time
while (wait_for_user && !(ms && ELAPSED(millis(), ms)))
idle(TERN_(ADVANCED_PAUSE_FEATURE, no_sleep));
wait_for_user = false;
user_resume();
while (ui.button_pressed()) safe_delay(50);
}
@ -325,7 +334,7 @@ bool wait_for_heatup = false;
#pragma GCC diagnostic ignored "-Wnarrowing"
#pragma GCC diagnostic ignored "-Wsign-compare"
bool pin_is_protected(const pin_t pin) {
bool Marlin::pin_is_protected(const pin_t pin) {
#define pgm_read_pin(P) (sizeof(pin_t) == 2 ? (pin_t)pgm_read_word(P) : (pin_t)pgm_read_byte(P))
for (uint8_t i = 0; i < COUNT(sensitive_dio); ++i)
if (pin == pgm_read_pin(&sensitive_dio[i])) return true;
@ -336,28 +345,28 @@ bool pin_is_protected(const pin_t pin) {
#pragma GCC diagnostic pop
bool printer_busy() {
bool Marlin::printer_busy() {
return planner.has_blocks_queued() || printingIsActive();
}
/**
* A Print Job exists when the timer is running or SD is printing
*/
bool printJobOngoing() { return print_job_timer.isRunning() || card.isStillPrinting(); }
bool Marlin::printJobOngoing() { return print_job_timer.isRunning() || card.isStillPrinting(); }
/**
* Printing is active when a job is underway but not paused
*/
bool printingIsActive() { return !did_pause_print && printJobOngoing(); }
bool Marlin::printingIsActive() { return !did_pause_print && printJobOngoing(); }
/**
* Printing is paused according to SD or host indicators
*/
bool printingIsPaused() {
bool Marlin::printingIsPaused() {
return did_pause_print || print_job_timer.isPaused() || card.isPaused();
}
void startOrResumeJob() {
void Marlin::startOrResumeJob() {
if (!printingIsPaused()) {
TERN_(GCODE_REPEAT_MARKERS, repeat.reset());
TERN_(CANCEL_OBJECTS, cancelable.reset());
@ -383,7 +392,7 @@ void startOrResumeJob() {
TERN(HAS_CUTTER, cutter.kill(), thermalManager.zero_fan_speeds()); // Full cutter shutdown including ISR control
wait_for_heatup = false;
marlin.heatup_done();
TERN_(POWER_LOSS_RECOVERY, recovery.purge());
@ -395,8 +404,8 @@ void startOrResumeJob() {
}
inline void finishSDPrinting() {
if (queue.enqueue_one(F("M1001"))) { // Keep trying until it gets queued
marlin_state = MarlinState::MF_RUNNING; // Signal to stop trying
if (queue.enqueue_one(F("M1001"))) { // Keep trying until it gets queued
marlin.setState(MF_RUNNING); // Signal to stop trying
TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine());
TERN_(DGUS_LCD_UI_MKS, screen.sdPrintingFinished());
}
@ -417,7 +426,7 @@ void startOrResumeJob() {
* - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT)
* - Pulse FET_SAFETY_PIN if it exists
*/
inline void manage_inactivity(const bool no_stepper_sleep=false) {
void Marlin::manage_inactivity(const bool no_stepper_sleep/*=false*/) {
queue.get_available_commands();
@ -531,11 +540,15 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
constexpr millis_t CUB_DEBOUNCE_DELAY_##N = 250UL; \
static millis_t next_cub_ms_##N; \
if (BUTTON##N##_HIT_STATE == READ(BUTTON##N##_PIN) \
&& (ENABLED(BUTTON##N##_WHEN_PRINTING) || printer_not_busy)) { \
&& (ENABLED(BUTTON##N##_WHEN_PRINTING) || printer_not_busy) \
) { \
if (ELAPSED(ms, next_cub_ms_##N)) { \
next_cub_ms_##N = ms + CUB_DEBOUNCE_DELAY_##N; \
CODE; \
queue.inject(F(BUTTON##N##_GCODE)); \
if (ENABLED(BUTTON##N##_IMMEDIATE)) \
gcode.process_subcommands_now(F(BUTTON##N##_GCODE)); \
else \
queue.inject(F(BUTTON##N##_GCODE)); \
TERN_(HAS_MARLINUI_MENU, ui.quick_feedback()); \
} \
} \
@ -709,9 +722,9 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
#if ENABLED(DUAL_X_CARRIAGE)
// handle delayed move timeout
if (delayed_move_time && ELAPSED(ms, delayed_move_time) && IsRunning()) {
if (delayed_move_time && ELAPSED(ms, delayed_move_time) && isRunning()) {
// travel moves have been received so enact them
delayed_move_time = 0xFFFFFFFFUL; // force moves to be done
delayed_move_time = UINT32_MAX; // force moves to be done
destination = current_position;
prepare_line_to_destination();
planner.synchronize();
@ -738,7 +751,8 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
WRITE(FET_SAFETY_PIN, FET_SAFETY_INVERTED);
}
#endif
} // manage_inactivity()
} // Marlin::manage_inactivity()
#if ALL(EP_BABYSTEPPING, EMERGENCY_PARSER)
#include "feature/babystep.h"
@ -766,14 +780,14 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
* - Update the Průša MMU2
* - Handle Joystick jogging
*/
void idle(const bool no_stepper_sleep/*=false*/) {
void Marlin::idle(const bool no_stepper_sleep/*=false*/) {
#ifdef MAX7219_DEBUG_PROFILE
CodeProfiler idle_profiler;
#endif
#if ENABLED(MARLIN_DEV_MODE)
static uint16_t idle_depth = 0;
if (++idle_depth > 5) SERIAL_ECHOLNPGM("idle() call depth: ", idle_depth);
if (++idle_depth > 5) SERIAL_ECHOLNPGM("Marlin::idle() call depth: ", idle_depth);
#endif
// Bed Distance Sensor task
@ -789,7 +803,7 @@ void idle(const bool no_stepper_sleep/*=false*/) {
TERN_(MAX7219_DEBUG, max7219.idle_tasks());
// Return if setup() isn't completed
if (marlin_state == MarlinState::MF_INITIALIZING) goto IDLE_DONE;
if (is(MF_INITIALIZING)) goto IDLE_DONE;
// TODO: Still causing errors
TERN_(TOOL_SENSOR, (void)check_tool_sensor_stats(active_extruder, true));
@ -889,13 +903,14 @@ void idle(const bool no_stepper_sleep/*=false*/) {
TERN_(MARLIN_DEV_MODE, idle_depth--);
return;
} // idle()
} // Marlin::idle()
/**
* Kill all activity and lock the machine.
* After this the machine will need to be reset.
*/
void kill(FSTR_P const lcd_error/*=nullptr*/, FSTR_P const lcd_component/*=nullptr*/, const bool steppers_off/*=false*/) {
void Marlin::kill(FSTR_P const lcd_error/*=nullptr*/, FSTR_P const lcd_component/*=nullptr*/, const bool steppers_off/*=false*/) {
thermalManager.disable_all_heaters();
TERN_(HAS_CUTTER, cutter.kill()); // Full cutter shutdown including ISR control
@ -921,7 +936,7 @@ void kill(FSTR_P const lcd_error/*=nullptr*/, FSTR_P const lcd_component/*=nullp
minkill(steppers_off);
}
void minkill(const bool steppers_off/*=false*/) {
void Marlin::minkill(const bool steppers_off/*=false*/) {
// Wait a short time (allows messages to get out before shutting down.
for (int i = 1000; i--;) DELAY_US(600);
@ -961,13 +976,14 @@ void minkill(const bool steppers_off/*=false*/) {
for (;;) hal.watchdog_refresh(); // Wait for RESET button or power-cycle
#endif
}
} // Marlin::minkill
/**
* Turn off heaters and stop the print in progress
* After a stop the machine may be resumed with M999
*/
void stop() {
void Marlin::stop() {
thermalManager.disable_all_heaters(); // 'unpause' taken care of in here
print_job_timer.stop();
@ -976,13 +992,13 @@ void stop() {
thermalManager.set_fans_paused(false); // Un-pause fans for safety
#endif
if (!IsStopped()) {
if (!isStopped()) {
SERIAL_ERROR_MSG(STR_ERR_STOPPED);
LCD_MESSAGE(MSG_STOPPED);
safe_delay(350); // allow enough time for messages to get out before stopping
marlin_state = MarlinState::MF_STOPPED;
safe_delay(350); // Allow enough time for messages to get out before stopping
setState(MF_STOPPED);
}
} // stop()
} // Marlin::stop()
inline void tmc_standby_setup() {
#if PIN_EXISTS(X_STDBY)
@ -1693,7 +1709,7 @@ void setup() {
SETUP_RUN(ftMotion.init());
#endif
marlin_state = MarlinState::MF_RUNNING;
marlin.setState(MF_RUNNING);
#ifdef STARTUP_TUNE
// Play a short startup tune before continuing.
@ -1709,7 +1725,7 @@ void setup() {
/**
* The main Marlin program loop
*
* - Call idle() to handle all tasks between G-code commands
* - Call marlin.idle() to handle all tasks between G-code commands
* Note that no G-codes from the queue can be executed during idle()
* but many G-codes can be called directly anytime like macros.
* - Check whether SD card auto-start is needed now.
@ -1721,11 +1737,11 @@ void setup() {
*/
void loop() {
do {
idle();
marlin.idle();
#if HAS_MEDIA
if (card.flag.abort_sd_printing) abortSDPrinting();
if (marlin_state == MarlinState::MF_SD_COMPLETE) finishSDPrinting();
if (marlin.is(MF_SD_COMPLETE)) finishSDPrinting();
#endif
queue.advance();

View file

@ -27,26 +27,8 @@
#include <stdio.h>
#include <stdlib.h>
void stop();
// Pass true to keep steppers from timing out
void idle(const bool no_stepper_sleep=false);
inline void idle_no_sleep() { idle(true); }
#if ENABLED(G38_PROBE_TARGET)
extern uint8_t G38_move; // Flag to tell the ISR that G38 is in progress, and the type
extern bool G38_did_trigger; // Flag from the ISR to indicate the endstop changed
#endif
void kill(FSTR_P const lcd_error=nullptr, FSTR_P const lcd_component=nullptr, const bool steppers_off=false);
void minkill(const bool steppers_off=false);
#if ENABLED(CONFIGURABLE_MACHINE_NAME)
extern MString<64> machine_name;
#endif
// Global State of the firmware
enum class MarlinState : uint8_t {
enum MarlinState : uint8_t {
MF_INITIALIZING = 0,
MF_STOPPED,
MF_KILLED,
@ -56,35 +38,81 @@ enum class MarlinState : uint8_t {
MF_WAITING,
};
extern MarlinState marlin_state;
inline bool IsRunning() { return marlin_state >= MarlinState::MF_RUNNING; }
inline bool IsStopped() { return marlin_state == MarlinState::MF_STOPPED; }
typedef bool (*testFunc_t)();
bool printingIsActive();
bool printJobOngoing();
bool printingIsPaused();
void startOrResumeJob();
// Delay ensuring that temperatures are updated and the watchdog is kept alive
void safe_delay(millis_t ms);
bool printer_busy();
// Singleton for Marlin global data and methods
extern bool wait_for_heatup;
#if HAS_RESUME_CONTINUE
extern bool wait_for_user;
void wait_for_user_response(millis_t ms=0, const bool no_sleep=false);
#endif
bool pin_is_protected(const pin_t pin);
#if HAS_SUICIDE
inline void suicide() { OUT_WRITE(SUICIDE_PIN, SUICIDE_PIN_STATE); }
#endif
#if HAS_KILL
#ifndef KILL_PIN_STATE
#define KILL_PIN_STATE LOW
class Marlin {
public:
#if ENABLED(CONFIGURABLE_MACHINE_NAME)
static MString<64> machine_name;
#endif
inline bool kill_state() { return READ(KILL_PIN) == KILL_PIN_STATE; }
#endif
static MarlinState state;
static void setState(const MarlinState s) { state = s; }
static bool is(const MarlinState s) { return state == s; }
static bool isStopped() { return is(MF_STOPPED); }
static bool isRunning() { return state >= MF_RUNNING; }
static bool printingIsActive();
static bool printJobOngoing();
static bool printingIsPaused();
static void startOrResumeJob();
static bool printer_busy();
static void stop();
// Maintain all important activities
static void manage_inactivity(const bool no_stepper_sleep=false);
// Pass true to keep steppers from timing out
static void idle(const bool no_stepper_sleep=false);
static void idle_no_sleep() { idle(true); }
static void kill(FSTR_P const lcd_error=nullptr, FSTR_P const lcd_component=nullptr, const bool steppers_off=false);
static void minkill(const bool steppers_off=false);
#if HAS_RESUME_CONTINUE
// Global waiting for user response
static bool wait_for_user;
static void wait_start() { wait_for_user = true; }
static void user_resume() { wait_for_user = false; }
static void wait_for_user_response(millis_t ms=0, const bool no_sleep=false);
#endif
// Global waiting for heatup state
static bool wait_for_heatup;
static bool is_heating() { return wait_for_heatup; }
static void heatup_start() { wait_for_heatup = true; }
static void heatup_done() { wait_for_heatup = false; }
static void end_waiting() { TERN_(HAS_RESUME_CONTINUE, wait_for_user =) wait_for_heatup = false; }
// Shared function for M42 / M43
static bool pin_is_protected(const pin_t pin);
#if HAS_SUICIDE
static void suicide() { OUT_WRITE(SUICIDE_PIN, SUICIDE_PIN_STATE); }
#endif
static bool kill_state() {
return (
#if HAS_KILL
#ifndef KILL_PIN_STATE
#define KILL_PIN_STATE LOW
#endif
READ(KILL_PIN) == KILL_PIN_STATE
#else
false
#endif
);
}
};
extern Marlin marlin;
extern const char M112_KILL_STR[];

View file

@ -55,11 +55,11 @@
#define BOARD_RAMPS_PLUS_EEF 1033 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_PLUS_SF 1034 // RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan)
#define BOARD_RAMPS_BTT_16_PLUS_EFB 1035 // RAMPS 1.6+ (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS_BTT_16_PLUS_EEB 1036 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS_BTT_16_PLUS_EFF 1037 // RAMPS 1.6+ (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_BTT_16_PLUS_EEF 1038 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_BTT_16_PLUS_SF 1039 // RAMPS 1.6+ (Power outputs: Spindle, Controller Fan)
#define BOARD_RAMPS_BTT_16_PLUS_EFB 1040 // RAMPS 1.6+ (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS_BTT_16_PLUS_EEB 1041 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS_BTT_16_PLUS_EFF 1042 // RAMPS 1.6+ (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_BTT_16_PLUS_EEF 1043 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_BTT_16_PLUS_SF 1044 // RAMPS 1.6+ (Power outputs: Spindle, Controller Fan)
//
// RAMPS Derivatives - ATmega1280, ATmega2560
@ -431,67 +431,68 @@
// STM32 ARM Cortex-M4F
//
#define BOARD_ARMED 5200 // Arm'ed STM32F4-based controller
#define BOARD_RUMBA32_V1_0 5201 // RUMBA32 STM32F446VE based controller from Aus3D
#define BOARD_RUMBA32_V1_1 5202 // RUMBA32 STM32F446VE based controller from Aus3D
#define BOARD_RUMBA32_MKS 5203 // RUMBA32 STM32F446VE based controller from Makerbase
#define BOARD_RUMBA32_BTT 5204 // RUMBA32 STM32F446VE based controller from BIGTREETECH
#define BOARD_BLACK_STM32F407VE 5205 // Black STM32F407VE development board
#define BOARD_BLACK_STM32F407ZE 5206 // Black STM32F407ZE development board
#define BOARD_BTT_SKR_MINI_E3_V3_0_1 5207 // BigTreeTech SKR Mini E3 V3.0.1 (STM32F401RC)
#define BOARD_BTT_SKR_PRO_V1_1 5208 // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
#define BOARD_BTT_SKR_PRO_V1_2 5209 // BigTreeTech SKR Pro v1.2 (STM32F407ZG)
#define BOARD_BTT_BTT002_V1_0 5210 // BigTreeTech BTT002 v1.0 (STM32F407VG)
#define BOARD_BTT_E3_RRF 5211 // BigTreeTech E3 RRF (STM32F407VG)
#define BOARD_BTT_SKR_V2_0_REV_A 5212 // BigTreeTech SKR v2.0 Rev A (STM32F407VG)
#define BOARD_BTT_SKR_V2_0_REV_B 5213 // BigTreeTech SKR v2.0 Rev B (STM32F407VG/STM32F429VG)
#define BOARD_BTT_GTR_V1_0 5214 // BigTreeTech GTR v1.0 (STM32F407IGT)
#define BOARD_BTT_OCTOPUS_V1_0 5215 // BigTreeTech Octopus v1.0 (STM32F446ZE)
#define BOARD_BTT_OCTOPUS_V1_1 5216 // BigTreeTech Octopus v1.1 (STM32F446ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_0 5217 // BigTreeTech Octopus Pro v1.0 (STM32F446ZE / STM32F429ZG)
#define BOARD_LERDGE_K 5218 // Lerdge K (STM32F407ZG)
#define BOARD_LERDGE_S 5219 // Lerdge S (STM32F407VE)
#define BOARD_LERDGE_X 5220 // Lerdge X (STM32F407VE)
#define BOARD_FYSETC_S6 5221 // FYSETC S6 (STM32F446VE)
#define BOARD_FYSETC_S6_V2_0 5222 // FYSETC S6 v2.0 (STM32F446VE)
#define BOARD_FYSETC_SPIDER 5223 // FYSETC Spider (STM32F446VE)
#define BOARD_FYSETC_SPIDER_V2_2 5224 // FYSETC Spider V2.2 (STM32F446VE)
#define BOARD_FLYF407ZG 5225 // FLYmaker FLYF407ZG (STM32F407ZG)
#define BOARD_MKS_ROBIN2 5226 // MKS Robin2 V1.0 (STM32F407ZE)
#define BOARD_MKS_ROBIN_PRO_V2 5227 // MKS Robin Pro V2 (STM32F407VE)
#define BOARD_MKS_ROBIN_NANO_V3 5228 // MKS Robin Nano V3 (STM32F407VG)
#define BOARD_MKS_ROBIN_NANO_V3_1 5229 // MKS Robin Nano V3.1 (STM32F407VE)
#define BOARD_MKS_MONSTER8_V1 5230 // MKS Monster8 V1 (STM32F407VE)
#define BOARD_MKS_MONSTER8_V2 5231 // MKS Monster8 V2 (STM32F407VE)
#define BOARD_ANET_ET4 5232 // ANET ET4 V1.x (STM32F407VG)
#define BOARD_ANET_ET4P 5233 // ANET ET4P V1.x (STM32F407VG)
#define BOARD_FYSETC_CHEETAH_V20 5234 // FYSETC Cheetah V2.0 (STM32F401RC)
#define BOARD_FYSETC_CHEETAH_V30 5235 // FYSETC Cheetah V3.0 (STM32F446RC)
#define BOARD_TH3D_EZBOARD_V2 5236 // TH3D EZBoard v2.0 (STM32F405RG)
#define BOARD_OPULO_LUMEN_REV3 5237 // Opulo Lumen PnP Controller REV3 (STM32F407VE / STM32F407VG)
#define BOARD_OPULO_LUMEN_REV4 5238 // Opulo Lumen PnP Controller REV4 (STM32F407VE / STM32F407VG)
#define BOARD_MKS_ROBIN_NANO_V1_3_F4 5239 // MKS Robin Nano V1.3 and MKS Robin Nano-S V1.3 (STM32F407VE)
#define BOARD_MKS_EAGLE 5240 // MKS Eagle (STM32F407VE)
#define BOARD_ARTILLERY_RUBY 5241 // Artillery Ruby (STM32F401RC)
#define BOARD_CREALITY_V24S1_301F4 5242 // Creality v2.4.S1_301F4 (STM32F401RC) as found in the Ender-3 S1 F4
#define BOARD_CREALITY_CR4NTXXC10 5243 // Creality E3 Free-runs Silent Motherboard (STM32F401RET6)
#define BOARD_FYSETC_SPIDER_KING407 5244 // FYSETC Spider King407 (STM32F407ZG)
#define BOARD_MKS_SKIPR_V1 5245 // MKS SKIPR v1.0 all-in-one board (STM32F407VE)
#define BOARD_TRONXY_CXY_446_V10 5246 // TRONXY CXY-446-V10-220413/CXY-V6-191121 (STM32F446ZE)
#define BOARD_CREALITY_F401RE 5247 // Creality CR4NS200141C13 (STM32F401RE) as found in the Ender-5 S1
#define BOARD_BLACKPILL_CUSTOM 5248 // Custom board based on STM32F401CDU6.
#define BOARD_I3DBEEZ9_V1 5249 // I3DBEEZ9 V1 (STM32F407ZG)
#define BOARD_MELLOW_FLY_E3_V2 5250 // Mellow Fly E3 V2 (STM32F407VG)
#define BOARD_BLACKBEEZMINI_V1 5251 // BlackBeezMini V1 (STM32F401CCU6)
#define BOARD_XTLW_CLIMBER_8TH 5252 // XTLW Climber-8th (STM32F407VGT6)
#define BOARD_FLY_RRF_E3_V1 5253 // Fly RRF E3 V1.0 (STM32F407VG)
#define BOARD_FLY_SUPER8 5254 // Fly SUPER8 (STM32F407ZGT6)
#define BOARD_FLY_D8 5255 // FLY D8 (STM32F407VG)
#define BOARD_FLY_CDY_V3 5256 // FLY CDY V3 (STM32F407VGT6)
#define BOARD_ZNP_ROBIN_NANO 5257 // Elegoo Neptune 2 v1.2 board
#define BOARD_ZNP_ROBIN_NANO_V1_3 5258 // Elegoo Neptune 2 v1.3 board
#define BOARD_MKS_NEPTUNE_X 5259 // Elegoo Neptune X
#define BOARD_MKS_NEPTUNE_3 5260 // Elegoo Neptune 3
#define BOARD_ARMED 5200 // Arm'ed STM32F4-based controller
#define BOARD_RUMBA32_V1_0 5201 // RUMBA32 STM32F446VE based controller from Aus3D
#define BOARD_RUMBA32_V1_1 5202 // RUMBA32 STM32F446VE based controller from Aus3D
#define BOARD_RUMBA32_MKS 5203 // RUMBA32 STM32F446VE based controller from Makerbase
#define BOARD_RUMBA32_BTT 5204 // RUMBA32 STM32F446VE based controller from BIGTREETECH
#define BOARD_BLACK_STM32F407VE 5205 // Black STM32F407VE development board
#define BOARD_BLACK_STM32F407ZE 5206 // Black STM32F407ZE development board
#define BOARD_BTT_SKR_MINI_E3_V3_0_1 5207 // BigTreeTech SKR Mini E3 V3.0.1 (STM32F401RC)
#define BOARD_BTT_SKR_PRO_V1_1 5208 // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
#define BOARD_BTT_SKR_PRO_V1_2 5209 // BigTreeTech SKR Pro v1.2 (STM32F407ZG)
#define BOARD_BTT_BTT002_V1_0 5210 // BigTreeTech BTT002 v1.0 (STM32F407VG)
#define BOARD_BTT_E3_RRF 5211 // BigTreeTech E3 RRF (STM32F407VG)
#define BOARD_BTT_SKR_V2_0_REV_A 5212 // BigTreeTech SKR v2.0 Rev A (STM32F407VG)
#define BOARD_BTT_SKR_V2_0_REV_B 5213 // BigTreeTech SKR v2.0 Rev B (STM32F407VG/STM32F429VG)
#define BOARD_BTT_GTR_V1_0 5214 // BigTreeTech GTR v1.0 (STM32F407IGT)
#define BOARD_BTT_OCTOPUS_V1_0 5215 // BigTreeTech Octopus v1.0 (STM32F446ZE)
#define BOARD_BTT_OCTOPUS_V1_1 5216 // BigTreeTech Octopus v1.1 (STM32F446ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_0 5217 // BigTreeTech Octopus Pro v1.0 (STM32F446ZE / STM32F429ZG)
#define BOARD_LERDGE_K 5218 // Lerdge K (STM32F407ZG)
#define BOARD_LERDGE_S 5219 // Lerdge S (STM32F407VE)
#define BOARD_LERDGE_X 5220 // Lerdge X (STM32F407VE)
#define BOARD_FYSETC_S6 5221 // FYSETC S6 (STM32F446VE)
#define BOARD_FYSETC_S6_V2_0 5222 // FYSETC S6 v2.0 (STM32F446VE)
#define BOARD_FYSETC_SPIDER 5223 // FYSETC Spider (STM32F446VE)
#define BOARD_FYSETC_SPIDER_V2_2 5224 // FYSETC Spider V2.2 (STM32F446VE)
#define BOARD_FLYF407ZG 5225 // FLYmaker FLYF407ZG (STM32F407ZG)
#define BOARD_MKS_ROBIN2 5226 // MKS Robin2 V1.0 (STM32F407ZE)
#define BOARD_MKS_ROBIN_PRO_V2 5227 // MKS Robin Pro V2 (STM32F407VE)
#define BOARD_MKS_ROBIN_NANO_V3 5228 // MKS Robin Nano V3 (STM32F407VG)
#define BOARD_MKS_ROBIN_NANO_V3_1 5229 // MKS Robin Nano V3.1 (STM32F407VE)
#define BOARD_MKS_MONSTER8_V1 5230 // MKS Monster8 V1 (STM32F407VE)
#define BOARD_MKS_MONSTER8_V2 5231 // MKS Monster8 V2 (STM32F407VE)
#define BOARD_ANET_ET4 5232 // ANET ET4 V1.x (STM32F407VG)
#define BOARD_ANET_ET4P 5233 // ANET ET4P V1.x (STM32F407VG)
#define BOARD_FYSETC_CHEETAH_V20 5234 // FYSETC Cheetah V2.0 (STM32F401RC)
#define BOARD_FYSETC_CHEETAH_V30 5235 // FYSETC Cheetah V3.0 (STM32F446RC)
#define BOARD_TH3D_EZBOARD_V2 5236 // TH3D EZBoard v2.0 (STM32F405RG)
#define BOARD_OPULO_LUMEN_REV3 5237 // Opulo Lumen PnP Controller REV3 (STM32F407VE / STM32F407VG)
#define BOARD_OPULO_LUMEN_REV4 5238 // Opulo Lumen PnP Controller REV4 (STM32F407VE / STM32F407VG)
#define BOARD_MKS_ROBIN_NANO_V1_3_F4 5239 // MKS Robin Nano V1.3 and MKS Robin Nano-S V1.3 (STM32F407VE)
#define BOARD_MKS_EAGLE 5240 // MKS Eagle (STM32F407VE)
#define BOARD_ARTILLERY_RUBY 5241 // Artillery Ruby (STM32F401RC)
#define BOARD_CREALITY_V24S1_301F4 5242 // Creality v2.4.S1_301F4 (STM32F401RC) as found in the Ender-3 S1 F4
#define BOARD_CREALITY_CR4NTXXC10 5243 // Creality E3 Free-runs Silent Motherboard (STM32F401RET6)
#define BOARD_FYSETC_SPIDER_KING_V1_F407 5244 // FYSETC Spider King v1 (STM32F407ZG)
#define BOARD_FYSETC_SPIDER_KING_V1_1_F407 5245 // FYSETC Spider King v1.1 (STM32F407ZG)
#define BOARD_MKS_SKIPR_V1 5246 // MKS SKIPR v1.0 all-in-one board (STM32F407VE)
#define BOARD_TRONXY_CXY_446_V10 5247 // TRONXY CXY-446-V10-220413/CXY-V6-191121 (STM32F446ZE)
#define BOARD_CREALITY_F401RE 5248 // Creality CR4NS200141C13 (STM32F401RE) as found in the Ender-5 S1
#define BOARD_BLACKPILL_CUSTOM 5249 // Custom board based on STM32F401CDU6.
#define BOARD_I3DBEEZ9_V1 5250 // I3DBEEZ9 V1 (STM32F407ZG)
#define BOARD_MELLOW_FLY_E3_V2 5251 // Mellow Fly E3 V2 (STM32F407VG)
#define BOARD_BLACKBEEZMINI_V1 5252 // BlackBeezMini V1 (STM32F401CCU6)
#define BOARD_XTLW_CLIMBER_8TH 5253 // XTLW Climber-8th (STM32F407VGT6)
#define BOARD_FLY_RRF_E3_V1 5254 // Fly RRF E3 V1.0 (STM32F407VG)
#define BOARD_FLY_SUPER8 5255 // Fly SUPER8 (STM32F407ZGT6)
#define BOARD_FLY_D8 5256 // FLY D8 (STM32F407VG)
#define BOARD_FLY_CDY_V3 5257 // FLY CDY V3 (STM32F407VGT6)
#define BOARD_ZNP_ROBIN_NANO 5258 // Elegoo Neptune 2 v1.2 board
#define BOARD_ZNP_ROBIN_NANO_V1_3 5259 // Elegoo Neptune 2 v1.3 board
#define BOARD_MKS_NEPTUNE_X 5260 // Elegoo Neptune X
#define BOARD_MKS_NEPTUNE_3 5261 // Elegoo Neptune 3
//
// Other ARM Cortex-M4
@ -502,22 +503,24 @@
// ARM Cortex-M7
//
#define BOARD_REMRAM_V1 6000 // RemRam v1
#define BOARD_NUCLEO_F767ZI 6001 // ST NUCLEO-F767ZI Dev Board
#define BOARD_BTT_SKR_SE_BX_V2 6002 // BigTreeTech SKR SE BX V2.0 (STM32H743II)
#define BOARD_BTT_SKR_SE_BX_V3 6003 // BigTreeTech SKR SE BX V3.0 (STM32H743II)
#define BOARD_BTT_SKR_V3_0 6004 // BigTreeTech SKR V3.0 (STM32H743VI / STM32H723VG)
#define BOARD_BTT_SKR_V3_0_EZ 6005 // BigTreeTech SKR V3.0 EZ (STM32H743VI / STM32H723VG)
#define BOARD_BTT_OCTOPUS_MAX_EZ_V1_0 6006 // BigTreeTech Octopus Max EZ V1.0 (STM32H723ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_0_1 6007 // BigTreeTech Octopus Pro v1.0.1 (STM32H723ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_1 6008 // BigTreeTech Octopus Pro v1.1 (STM32H723ZE)
#define BOARD_BTT_MANTA_M8P_V2_0 6009 // BigTreeTech Manta M8P V2.0 (STM32H723ZE)
#define BOARD_BTT_KRAKEN_V1_0 6010 // BigTreeTech Kraken v1.0 (STM32H723ZG)
#define BOARD_TEENSY40 6011 // Teensy 4.0
#define BOARD_TEENSY41 6012 // Teensy 4.1
#define BOARD_T41U5XBB 6013 // T41U5XBB Teensy 4.1 breakout board
#define BOARD_FLY_D8_PRO 6014 // FLY_D8_PRO (STM32H723VG)
#define BOARD_FLY_SUPER8_PRO 6015 // FLY SUPER8 PRO (STM32H723ZG)
#define BOARD_REMRAM_V1 6000 // RemRam v1
#define BOARD_NUCLEO_F767ZI 6001 // ST NUCLEO-F767ZI Dev Board
#define BOARD_BTT_SKR_SE_BX_V2 6002 // BigTreeTech SKR SE BX V2.0 (STM32H743II)
#define BOARD_BTT_SKR_SE_BX_V3 6003 // BigTreeTech SKR SE BX V3.0 (STM32H743II)
#define BOARD_BTT_SKR_V3_0 6004 // BigTreeTech SKR V3.0 (STM32H743VI / STM32H723VG)
#define BOARD_BTT_SKR_V3_0_EZ 6005 // BigTreeTech SKR V3.0 EZ (STM32H743VI / STM32H723VG)
#define BOARD_BTT_OCTOPUS_MAX_EZ_V1_0 6006 // BigTreeTech Octopus Max EZ V1.0 (STM32H723ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_0_1 6007 // BigTreeTech Octopus Pro v1.0.1 (STM32H723ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_1 6008 // BigTreeTech Octopus Pro v1.1 (STM32H723ZE)
#define BOARD_BTT_MANTA_M8P_V2_0 6009 // BigTreeTech Manta M8P V2.0 (STM32H723ZE)
#define BOARD_BTT_KRAKEN_V1_0 6010 // BigTreeTech Kraken v1.0 (STM32H723ZG)
#define BOARD_TEENSY40 6011 // Teensy 4.0
#define BOARD_TEENSY41 6012 // Teensy 4.1
#define BOARD_T41U5XBB 6013 // T41U5XBB Teensy 4.1 breakout board
#define BOARD_FLY_D8_PRO 6014 // FLY_D8_PRO (STM32H723VG)
#define BOARD_FLY_SUPER8_PRO 6015 // FLY SUPER8 PRO (STM32H723ZG)
#define BOARD_FYSETC_SPIDER_KING_V1_H723 6016 // FYSETC Spider King v1 (STM32H723ZG)
#define BOARD_FYSETC_SPIDER_KING_V1_1_H723 6017 // FYSETC Spider King v1.1 (STM32H723ZG)
//
// Espressif ESP32 WiFi
@ -575,7 +578,8 @@
//
#define BOARD_RP2040 6200 // Generic RP2040 Test board
#define BOARD_BTT_SKR_PICO 6201 // BigTreeTech SKR Pico 1.x
#define BOARD_RASPBERRY_PI_PICO 6201 // Raspberry Pi Pico
#define BOARD_BTT_SKR_PICO 6202 // BigTreeTech SKR Pico 1.x
//
// Custom board

View file

@ -210,6 +210,8 @@
#define STR_KILL_BUTTON "KILL button/pin"
// temperature.cpp strings
#define STR_WAIT_FOR_HOTEND "Wait for hotend heating..."
#define STR_WAIT_FOR_BED "Wait for bed heating..."
#define STR_PID_AUTOTUNE "PID Autotune"
#define STR_PID_AUTOTUNE_START " start"
#define STR_PID_BAD_HEATER_ID " failed! Bad heater id"
@ -230,6 +232,8 @@
#define STR_PID_DEBUG_INPUT ": Input "
#define STR_PID_DEBUG_OUTPUT " Output "
#define STR_INVALID_EXTRUDER_NUM " - Invalid extruder number !"
// MPCTEMP strings
#define STR_MPC_AUTOTUNE_START "MPC Autotune start for " STR_E
#define STR_MPC_AUTOTUNE_INTERRUPTED "MPC Autotune interrupted!"
#define STR_MPC_AUTOTUNE_FINISHED "MPC Autotune finished! Put the constants below into Configuration.h"
@ -238,6 +242,7 @@
#define STR_MPC_MEASURING_AMBIENT "Measuring ambient heatloss at "
#define STR_MPC_TEMPERATURE_ERROR "Temperature error"
// Temperature Sensors
#define STR_HEATER_BED "bed"
#define STR_HEATER_CHAMBER "chamber"
#define STR_COOLER "cooler"
@ -247,6 +252,7 @@
#define STR_REDUNDANT "redundant "
#define STR_LASER_TEMP "laser temperature"
// Misc. Errors, Thermal Runaway
#define STR_STOPPED_HEATER ", system stopped! Heater_ID: "
#define STR_DETECTED_TEMP_B " (temp: "
#define STR_DETECTED_TEMP_E ")"
@ -269,6 +275,7 @@
#define STR_DEBUG_COMMUNICATION "COMMUNICATION"
#define STR_DEBUG_DETAIL "DETAIL"
// Password Security
#define STR_PRINTER_LOCKED "Printer locked! (Unlock with M511 or LCD)"
#define STR_WRONG_PASSWORD "Incorrect Password"
#define STR_PASSWORD_TOO_LONG "Password too long"
@ -296,6 +303,7 @@
#define STR_TOOL_CHANGING "Tool-changing"
#define STR_HOTEND_OFFSETS "Hotend offsets"
#define STR_SERVO_ANGLES "Servo Angles"
#define STR_AUTOTEMP "Auto Temp Control"
#define STR_HOTEND_PID "Hotend PID"
#define STR_BED_PID "Bed PID"
#define STR_CHAMBER_PID "Chamber PID"

View file

@ -25,12 +25,6 @@
#define __has_include(...) 1
#endif
#define ABCE 4
#define XYZE 4
#define ABC 3
#define XYZ 3
#define XY 2
#define _AXIS(A) (A##_AXIS)
#define _FORCE_INLINE_ __attribute__((__always_inline__)) __inline__
@ -215,7 +209,10 @@
// "Ternary" that emits or omits the given content
#define EMIT(V...) V
#define OMIT(...)
#define TERN_(O,A) _TERN(_ENA_1(O),OMIT,EMIT)(A) // OPTION ? 'A' : '<nul>'
#define TERN_(O,A) TERF(O,EMIT)(A) // OPTION ? 'A' : '<nul>' ; Usage: TERN_(OPTION, EMITTHIS)
// Call G(...) or swallow with OMIT(...)
#define TERF(O,G) _TERN(_ENA_1(O),OMIT,G) // OPTION ? 'G' : 'OMIT' ; Usage: TERF(OPTION, CALLTHIS)(ARGS...)
// Macros to conditionally emit array items and function arguments
#define _OPTITEM(A...) A,

View file

@ -280,12 +280,11 @@ public:
// Quick hash to detect change (e.g., to avoid expensive drawing)
typedef IF<ENABLED(DJB2_HASH), uint32_t, uint16_t>::type hash_t;
hash_t hash() const {
const int sz = length();
#if ENABLED(DJB2_HASH)
hash_t hval = 5381;
char c;
while ((c = *str++)) hval += (hval << 5) + c; // = hval * 33 + c
for (int i = 0; i < sz; i++) hval += (hval << 5) + str[i]; // = hval * 33 + c
#else
const int sz = length();
hash_t hval = hash_t(sz);
for (int i = 0; i < sz; i++) hval = ((hval << 1) | (hval >> 15)) ^ str[i]; // ROL, XOR
#endif

View file

@ -50,6 +50,7 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
#define NUM_AXIS_DECL_LC(T,V) NUM_AXIS_LIST(T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V)
#define MAIN_AXIS_NAMES NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W)
#define MAIN_AXIS_NAMES_LC NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)
#define NUM_AXIS_CALL(G) do { NUM_AXIS_CODE(G(X_AXIS), G(Y_AXIS), G(Z_AXIS), G(I_AXIS), G(J_AXIS), G(K_AXIS), G(U_AXIS), G(V_AXIS), G(W_AXIS)); } while(0)
#define STR_AXES_MAIN NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
#define LOGICAL_AXIS_GANG(N,V...) NUM_AXIS_GANG(V) GANG_ITEM_E(N)
@ -68,6 +69,7 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
#define LOGICAL_AXIS_NAMES_LC LOGICAL_AXIS_LIST(e, x, y, z, i, j, k, u, v, w)
#define LOGICAL_AXIS_MAP(F) MAP(F, LOGICAL_AXIS_NAMES)
#define LOGICAL_AXIS_MAP_LC(F) MAP(F, LOGICAL_AXIS_NAMES_LC)
#define LOGICAL_AXIS_CALL(G) do { LOGICAL_AXIS_CODE(G(E_AXIS), G(X_AXIS), G(Y_AXIS), G(Z_AXIS), G(I_AXIS), G(J_AXIS), G(K_AXIS), G(U_AXIS), G(V_AXIS), G(W_AXIS)); } while(0)
#define STR_AXES_LOGICAL LOGICAL_AXIS_GANG("E", "X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
#define NUM_AXIS_PAIRED_LIST(V...) LIST_N(DOUBLE(NUM_AXES), V)
@ -175,6 +177,7 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
#define CARTES_CODE(x,y,z,e) XYZ_CODE(x,y,z) CODE_ITEM_E(e)
#define CARTES_GANG(x,y,z,e) XYZ_GANG(x,y,z) GANG_ITEM_E(e)
#define CARTES_AXIS_NAMES CARTES_LIST(X,Y,Z,E)
#define CARTES_AXIS_NAMES_LC CARTES_LIST(x,y,z,e)
#define CARTES_MAP(F) MAP(F, CARTES_AXIS_NAMES)
#if CARTES_COUNT
#define CARTES_COMMA ,
@ -238,6 +241,24 @@ struct Flags<N, false> {
FI bool operator[](const int n) const { return test(n); }
FI int size() const { return sizeof(b); }
FI operator bool() const { return b != 0; }
FI Flags<N>& operator|=(Flags<N> &p) const { b |= p.b; return *this; }
FI Flags<N>& operator&=(Flags<N> &p) const { b &= p.b; return *this; }
FI Flags<N>& operator^=(Flags<N> &p) const { b ^= p.b; return *this; }
FI Flags<N>& operator|=(const flagbits_t &p) { b |= flagbits_t(p); return *this; }
FI Flags<N>& operator&=(const flagbits_t &p) { b &= flagbits_t(p); return *this; }
FI Flags<N>& operator^=(const flagbits_t &p) { b ^= flagbits_t(p); return *this; }
FI Flags<N> operator|(Flags<N> &p) const { return Flags<N>(b | p.b); }
FI Flags<N> operator&(Flags<N> &p) const { return Flags<N>(b & p.b); }
FI Flags<N> operator^(Flags<N> &p) const { return Flags<N>(b ^ p.b); }
FI Flags<N> operator~() const { return Flags<N>(~b); }
FI flagbits_t operator|(const flagbits_t &p) const { return b | flagbits_t(p); }
FI flagbits_t operator&(const flagbits_t &p) const { return b & flagbits_t(p); }
FI flagbits_t operator^(const flagbits_t &p) const { return b ^ flagbits_t(p); }
};
// Flag bits for more than 64 states
@ -492,7 +513,7 @@ typedef ab_float_t ab_pos_t;
typedef abc_float_t abc_pos_t;
typedef abce_float_t abce_pos_t;
// External conversion methods
// External conversion methods (motion.h)
void toLogical(xy_pos_t &raw);
void toLogical(xyz_pos_t &raw);
void toLogical(xyze_pos_t &raw);
@ -523,9 +544,9 @@ struct XYval {
#endif
#if HAS_Y_AXIS
FI void set(const T px, const T py) { x = px; y = py; }
FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; }
FI void set(const T (&arr)[2]) { x = arr[0]; y = arr[1]; }
#endif
#if NUM_AXES > XY
#if NUM_AXES > 2
FI void set(const T (&arr)[NUM_AXES]) { x = arr[0]; y = arr[1]; }
#endif
#if LOGICAL_AXES > NUM_AXES
@ -635,6 +656,21 @@ struct XYval {
FI bool operator==(const T &p) const { return x == p && y == p; }
FI bool operator!=(const T &p) const { return !operator==(p); }
FI bool operator< (const XYval<T> &rs) const { return x < rs.x && y < rs.y; }
FI bool operator<=(const XYval<T> &rs) const { return x <= rs.x && y <= rs.y; }
FI bool operator> (const XYval<T> &rs) const { return x > rs.x && y > rs.y; }
FI bool operator>=(const XYval<T> &rs) const { return x >= rs.x && y >= rs.y; }
FI bool operator< (const XYZval<T> &rs) const { return true XY_GANG(&& x < rs.x, && y < rs.y); }
FI bool operator<=(const XYZval<T> &rs) const { return true XY_GANG(&& x <= rs.x, && y <= rs.y); }
FI bool operator> (const XYZval<T> &rs) const { return true XY_GANG(&& x > rs.x, && y > rs.y); }
FI bool operator>=(const XYZval<T> &rs) const { return true XY_GANG(&& x >= rs.x, && y >= rs.y); }
FI bool operator< (const XYZEval<T> &rs) const { return true XY_GANG(&& x < rs.x, && y < rs.y); }
FI bool operator<=(const XYZEval<T> &rs) const { return true XY_GANG(&& x <= rs.x, && y <= rs.y); }
FI bool operator> (const XYZEval<T> &rs) const { return true XY_GANG(&& x > rs.x, && y > rs.y); }
FI bool operator>=(const XYZEval<T> &rs) const { return true XY_GANG(&& x >= rs.x, && y >= rs.y); }
};
//
@ -783,6 +819,7 @@ 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 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 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(_RSE(x), _RSE(y), _RSE(z), _RSE(i), _RSE(j), _RSE(k), _RSE(u), _RSE(v), _RSE(w)); return *this; }
FI XYZval<T>& operator<<=(const int &p) { NUM_AXIS_CODE(_LSE(x), _LSE(y), _LSE(z), _LSE(i), _LSE(j), _LSE(k), _LSE(u), _LSE(v), _LSE(w)); return *this; }
@ -794,6 +831,16 @@ struct XYZval {
FI bool operator==(const T &p) const { return ENABLED(HAS_X_AXIS) NUM_AXIS_GANG(&& x == p, && y == p, && z == p, && i == p, && j == p, && k == p, && u == p, && v == p, && w == p); }
FI bool operator!=(const T &p) const { return !operator==(p); }
FI bool operator< (const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x < rs.x, && y < rs.y, && z < rs.z, && i < rs.i, && j < rs.j, && k < rs.k, && u < rs.u, && v < rs.v, && w < rs.w); }
FI bool operator<=(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x <= rs.x, && y <= rs.y, && z <= rs.z, && i <= rs.i, && j <= rs.j, && k <= rs.k, && u <= rs.u, && v <= rs.v, && w <= rs.w); }
FI bool operator> (const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x > rs.x, && y > rs.y, && z > rs.z, && i > rs.i, && j > rs.j, && k > rs.k, && u > rs.u, && v > rs.v, && w > rs.w); }
FI bool operator>=(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x >= rs.x, && y >= rs.y, && z >= rs.z, && i >= rs.i, && j >= rs.j, && k >= rs.k, && u >= rs.u, && v >= rs.v, && w >= rs.w); }
FI bool operator< (const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x < rs.x, && y < rs.y, && z < rs.z, && i < rs.i, && j < rs.j, && k < rs.k, && u < rs.u, && v < rs.v, && w < rs.w); }
FI bool operator<=(const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x <= rs.x, && y <= rs.y, && z <= rs.z, && i <= rs.i, && j <= rs.j, && k <= rs.k, && u <= rs.u, && v <= rs.v, && w <= rs.w); }
FI bool operator> (const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x > rs.x, && y > rs.y, && z > rs.z, && i > rs.i, && j > rs.j, && k > rs.k, && u > rs.u, && v > rs.v, && w > rs.w); }
FI bool operator>=(const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x >= rs.x, && y >= rs.y, && z >= rs.z, && i >= rs.i, && j >= rs.j, && k >= rs.k, && u >= rs.u, && v >= rs.v, && w >= rs.w); }
};
//
@ -824,7 +871,7 @@ struct XYZEval {
FI void set(const XYZval<T> &pxyz, const T pe) { set(pxyz); e = pe; }
FI void set(LOGICAL_AXIS_ARGS_LC(const T)) { LOGICAL_AXIS_CODE(_e = e, a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w); }
#if DISTINCT_AXES > LOGICAL_AXES
FI void set(const T (&arr)[DISTINCT_AXES]) { LOGICAL_AXIS_CODE(e = arr[LOGICAL_AXES-1], x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); }
FI void set(const T (&arr)[DISTINCT_AXES], const uint8_t eindex) { LOGICAL_AXIS_CODE(e = arr[LOGICAL_AXES-1 + eindex], x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); }
#endif
#endif
@ -943,7 +990,10 @@ struct XYZEval {
FI XYZEval<T>& operator-=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e -= rs.e, x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k, u -= rs.u, v -= rs.v, w -= rs.w); return *this; }
FI XYZEval<T>& operator*=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e *= rs.e, x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k, u *= rs.u, v *= rs.v, w *= rs.w); return *this; }
FI XYZEval<T>& operator/=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e /= rs.e, x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k, u /= rs.u, v /= rs.v, w /= rs.w); return *this; }
FI XYZEval<T>& operator+=(const 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 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 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 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(_RSE(e), _RSE(x), _RSE(y), _RSE(z), _RSE(i), _RSE(j), _RSE(k), _RSE(u), _RSE(v), _RSE(w)); return *this; }
FI XYZEval<T>& operator<<=(const int &p) { LOGICAL_AXIS_CODE(_LSE(e), _LSE(x), _LSE(y), _LSE(z), _LSE(i), _LSE(j), _LSE(k), _LSE(u), _LSE(v), _LSE(w)); return *this; }
@ -957,6 +1007,16 @@ struct XYZEval {
FI bool operator==(const T &p) const { return ENABLED(HAS_X_AXIS) LOGICAL_AXIS_GANG(&& e == p, && x == p, && y == p, && z == p, && i == p, && j == p, && k == p, && u == p, && v == p, && w == p); }
FI bool operator!=(const T &p) const { return !operator==(p); }
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 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 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 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 true NUM_AXIS_GANG(&& x < rs.x, && y < rs.y, && z < rs.z, && i < rs.i, && j < rs.j, && k < rs.k, && u < rs.u, && v < rs.v, && w < rs.w); }
FI bool operator<=(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x <= rs.x, && y <= rs.y, && z <= rs.z, && i <= rs.i, && j <= rs.j, && k <= rs.k, && u <= rs.u, && v <= rs.v, && w <= rs.w); }
FI bool operator> (const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x > rs.x, && y > rs.y, && z > rs.z, && i > rs.i, && j > rs.j, && k > rs.k, && u > rs.u, && v > rs.v, && w > rs.w); }
FI bool operator>=(const XYZval<T> &rs) 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); }
};
#include <string.h> // for memset
@ -1263,6 +1323,7 @@ public:
FI AxisBits operator|(const AxisBits &p) const { return AxisBits(bits | p.bits); }
FI AxisBits operator&(const AxisBits &p) const { return AxisBits(bits & p.bits); }
FI AxisBits operator^(const AxisBits &p) const { return AxisBits(bits ^ p.bits); }
FI AxisBits operator~() const { return AxisBits(~bits); }
FI operator bool() const { return !!bits; }
FI operator uint16_t() const { return uint16_t(bits & 0xFFFF); }
@ -1280,7 +1341,7 @@ public:
// Axis names for G-code parsing, reports, etc.
constexpr xyze_char_t axis_codes LOGICAL_AXIS_ARRAY('E', 'X', 'Y', 'Z', AXIS4_NAME, AXIS5_NAME, AXIS6_NAME, AXIS7_NAME, AXIS8_NAME, AXIS9_NAME);
#if NUM_AXES <= XYZ && !HAS_EXTRUDERS
#if NUM_AXES <= 3 && !HAS_EXTRUDERS
#define AXIS_CHAR(A) ((char)('X' + A))
#define IAXIS_CHAR AXIS_CHAR
#else

View file

@ -22,26 +22,16 @@
#include "utility.h"
#include "../MarlinCore.h"
#include "../module/temperature.h"
#if ENABLED(MARLIN_DEV_MODE)
MarlinError marlin_error_number; // Error Number - Marlin can beep X times periodically, display, and emit...
#endif
void safe_delay(millis_t ms) {
while (ms > 50) {
ms -= 50;
delay(50);
thermalManager.task();
}
delay(ms);
thermalManager.task(); // This keeps us safe if too many small safe_delay() calls are made
}
// A delay to provide brittle hosts time to receive bytes
#if ENABLED(SERIAL_OVERRUN_PROTECTION)
#include "../MarlinCore.h" // for safe_delay
#include "../gcode/gcode.h" // for set_autoreport_paused
void serial_delay(const millis_t ms) {
@ -143,7 +133,7 @@ void safe_delay(millis_t ms) {
SERIAL_ECHOPGM("ABL Adjustment");
LOOP_NUM_AXES(a) {
SERIAL_ECHOPGM_P((PGM_P)pgm_read_ptr(&SP_AXIS_STR[a]));
serial_offset(planner.get_axis_position_mm(AxisEnum(a)) - current_position[a]);
serial_offset(planner.get_axis_position_mm((AxisEnum)a) - current_position[a]);
}
#else
#if ENABLED(AUTO_BED_LEVELING_UBL)

View file

@ -25,8 +25,6 @@
#include "../core/types.h"
#include "../core/millis_t.h"
void safe_delay(millis_t ms); // Delay ensuring that temperatures are updated and the watchdog is kept alive.
#if ENABLED(SERIAL_OVERRUN_PROTECTION)
void serial_delay(const millis_t ms);
#else

View file

@ -25,8 +25,7 @@
#if ENABLED(BABYSTEPPING)
#include "babystep.h"
#include "../MarlinCore.h"
#include "../module/motion.h" // for axes_should_home(), BABYSTEP_ALLOWED
#include "../module/motion.h" // for axis_should_home(), BABYSTEP_ALLOWED
#include "../module/planner.h" // for axis_steps_per_mm[]
#include "../module/stepper.h"
@ -49,7 +48,7 @@ int16_t Babystep::accum;
void Babystep::step_axis(const AxisEnum axis) {
const int16_t curTodo = steps[BS_AXIS_IND(axis)]; // get rid of volatile for performance
if (curTodo) {
stepper.do_babystep((AxisEnum)axis, curTodo > 0);
stepper.do_babystep(axis, curTodo > 0);
if (curTodo > 0) steps[BS_AXIS_IND(axis)]--; else steps[BS_AXIS_IND(axis)]++;
}
}

View file

@ -24,7 +24,6 @@
#if ENABLED(BD_SENSOR)
#include "../../../MarlinCore.h"
#include "../../../gcode/gcode.h"
#include "../../../module/settings.h"
#include "../../../module/motion.h"
@ -110,7 +109,7 @@ float BDS_Leveling::read() {
}
void BDS_Leveling::process() {
if (config_state == BDS_IDLE && printingIsActive()) return;
if (config_state == BDS_IDLE && marlin.printingIsActive()) return;
static millis_t next_check_ms = 0; // starting at T=0
static float zpos = 0.0f;
const millis_t ms = millis();
@ -156,7 +155,7 @@ void BDS_Leveling::process() {
}
else if (config_state == BDS_HOMING_Z) {
SERIAL_ECHOLNPGM("Read:", tmp);
kill(F("BDsensor connect Err!"));
marlin.kill(F("BDsensor connect Err!"));
}
DEBUG_ECHOLNPGM("BD:", tmp & 0x3FF, " Z:", cur_z, "|", current_position.z);

View file

@ -28,7 +28,6 @@
unified_bed_leveling bedlevel;
#include "../../../MarlinCore.h"
#include "../../../gcode/gcode.h"
#include "../../../module/settings.h"
@ -221,7 +220,7 @@ void unified_bed_leveling::display_map(const uint8_t map_type) {
if (human) SERIAL_CHAR(is_current ? ']' : ' ');
SERIAL_FLUSHTX();
idle_no_sleep();
marlin.idle_no_sleep();
}
if (!lcd) SERIAL_EOL();

View file

@ -26,7 +26,6 @@
#include "../bedlevel.h"
#include "../../../MarlinCore.h"
#include "../../../HAL/shared/eeprom_api.h"
#include "../../../libs/hex_print.h"
#include "../../../module/settings.h"
@ -314,7 +313,7 @@ void unified_bed_leveling::G29() {
const bool may_move = p_val == 1 || p_val == 2 || p_val == 4 || parser.seen_test('J');
// Potentially disable Fixed-Time Motion for probing
TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler);
TERN_(FT_MOTION, FTM_DISABLE_IN_SCOPE());
// Check for commands that require the printer to be homed
if (may_move) {
@ -375,7 +374,7 @@ void unified_bed_leveling::G29() {
bool invalidate_all = count >= GRID_MAX_POINTS;
if (!invalidate_all) {
while (count--) {
if ((count & 0x0F) == 0x0F) idle();
if ((count & 0x0F) == 0x0F) marlin.idle();
const mesh_index_pair closest = find_closest_mesh_point_of_type(REAL, param.XY_pos);
// No more REAL mesh points to invalidate? Assume the user meant
// to invalidate the ENTIRE mesh, which can't be done with
@ -397,7 +396,7 @@ void unified_bed_leveling::G29() {
if (parser.seen('Q')) {
const int16_t test_pattern = parser.has_value() ? parser.value_int() : -99;
if (!WITHIN(test_pattern, TERN0(UBL_DEVEL_DEBUGGING, -1), 2)) {
SERIAL_ECHOLNPGM("?Invalid (Q) test pattern. (" TERN(UBL_DEVEL_DEBUGGING, "-1", "0") " to 2)\n");
SERIAL_ECHOLN(F("?Invalid "), F("(Q) test pattern. (" TERN(UBL_DEVEL_DEBUGGING, "-1", "0") " to 2)\n"));
return;
}
SERIAL_ECHOLNPGM("Applying test pattern.\n");
@ -648,7 +647,7 @@ void unified_bed_leveling::G29() {
}
if (!WITHIN(param.KLS_storage_slot, 0, a - 1)) {
SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1);
SERIAL_ECHOLN(F("?Invalid "), F("storage slot.\n?Use 0 to "), a - 1);
return;
}
@ -676,7 +675,7 @@ void unified_bed_leveling::G29() {
}
if (!WITHIN(param.KLS_storage_slot, 0, a - 1)) {
SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1);
SERIAL_ECHOLN(F("?Invalid "), F("storage slot.\n?Use 0 to "), a - 1);
goto LEAVE;
}
@ -856,7 +855,7 @@ void set_message_with_feedback(FSTR_P const fstr) {
ui.quick_feedback(false); // Preserve button state for click-and-hold
const millis_t nxt = millis() + 1500UL;
while (ui.button_pressed()) { // Loop while the encoder is pressed. Uses hardware flag!
idle(); // idle, of course
marlin.idle(); // idle, of course
if (ELAPSED(millis(), nxt)) { // After 1.5 seconds
ui.quick_feedback();
if (func) (*func)();
@ -872,7 +871,7 @@ void set_message_with_feedback(FSTR_P const fstr) {
void unified_bed_leveling::move_z_with_encoder(const float multiplier) {
ui.wait_for_release();
while (!ui.button_pressed()) {
idle();
marlin.idle();
gcode.reset_stepper_timeout(); // Keep steppers powered
if (encoder_diff) {
do_blocking_move_to_z(current_position.z + float(encoder_diff) * multiplier);
@ -1088,7 +1087,7 @@ void set_message_with_feedback(FSTR_P const fstr) {
SET_SOFT_ENDSTOP_LOOSE(true);
do {
idle_no_sleep();
marlin.idle_no_sleep();
new_z = ui.ubl_mesh_value();
TERN_(UBL_MESH_EDIT_MOVES_Z, do_blocking_move_to_z(h_offset + new_z)); // Move the nozzle as the point is edited
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
@ -1161,16 +1160,16 @@ bool unified_bed_leveling::G29_parse_parameters() {
}
if (parser.seen('P')) {
const uint8_t pv = parser.value_byte();
const uint8_t pval = parser.value_byte();
#if !HAS_BED_PROBE
if (pv == 1) {
if (pval == 1) {
SERIAL_ECHOLNPGM("G29 P1 requires a probe.\n");
err_flag = true;
}
else
#endif
{
param.P_phase = pv;
param.P_phase = pval;
if (!WITHIN(param.P_phase, 0, 6)) {
SERIAL_ECHOLNPGM("?(P)hase value invalid (0-6).\n");
err_flag = true;
@ -1182,7 +1181,7 @@ bool unified_bed_leveling::G29_parse_parameters() {
#if HAS_BED_PROBE
param.J_grid_size = parser.value_byte();
if (param.J_grid_size && !WITHIN(param.J_grid_size, 2, 9)) {
SERIAL_ECHOLNPGM("?Invalid grid size (J) specified (2-9).\n");
SERIAL_ECHOLN(F("?Invalid "), F("grid size (J) specified (2-9).\n"));
err_flag = true;
}
#else
@ -1728,7 +1727,7 @@ void unified_bed_leveling::smart_fill_mesh() {
const float ez = -lsf_results.D - lsf_results.A * ppos.x - lsf_results.B * ppos.y;
z_values[ix][iy] = ez;
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ix, iy, z_values[ix][iy]));
idle(); // housekeeping
marlin.idle(); // housekeeping
}
}
}
@ -1785,7 +1784,7 @@ void unified_bed_leveling::smart_fill_mesh() {
SERIAL_EOL();
#if HAS_KILL
SERIAL_ECHOLNPGM("Kill pin on :", KILL_PIN, " state:", kill_state());
SERIAL_ECHOLNPGM("Kill pin on :", KILL_PIN, " state:", marlin.kill_state());
#endif
SERIAL_EOL();
@ -1823,7 +1822,7 @@ void unified_bed_leveling::smart_fill_mesh() {
SERIAL_ECHO_MSG("EEPROM Dump:");
persistentStore.access_start();
for (uint16_t i = 0; i < persistentStore.capacity(); i += 16) {
if (!(i & 0x3)) idle();
if (!(i & 0x3)) marlin.idle();
print_hex_word(i);
SERIAL_ECHOPGM(": ");
for (uint16_t j = 0; j < 16; j++) {
@ -1851,7 +1850,7 @@ void unified_bed_leveling::smart_fill_mesh() {
}
if (!parser.has_value() || !WITHIN(parser.value_int(), 0, a - 1)) {
SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1);
SERIAL_ECHOLN(F("?Invalid "), F("storage slot.\n?Use 0 to "), a - 1);
return;
}

View file

@ -32,7 +32,6 @@
#include "../../../module/delta.h"
#endif
#include "../../../MarlinCore.h"
#include <math.h>
//#define DEBUG_UBL_MOTION

View file

@ -71,11 +71,9 @@ void BLTouch::init(const bool set_voltage/*=false*/) {
#else
#ifdef DEBUG_OUT
if (DEBUGGING(LEVELING))
DEBUG_ECHOLN( F("BLTouch Mode: "), bltouch.od_5v_mode ? F("5V") : F("OD"),
F(" (Default " TERN(BLTOUCH_SET_5V_MODE, "5V", "OD") ")"));
#endif
if (DEBUGGING(LEVELING))
DEBUG_ECHOLN( F("BLTouch Mode: "), bltouch.od_5v_mode ? F("5V") : F("OD"),
F(" (Default " TERN(BLTOUCH_SET_5V_MODE, "5V", "OD") ")"));
const bool should_set = od_5v_mode != ENABLED(BLTOUCH_SET_5V_MODE);

View file

@ -134,7 +134,7 @@ void ControllerFan::update() {
} while (0)
#if ENABLED(FAN_SOFT_PWM)
soft_pwm_speed = speed;
soft_pwm_speed = speed >> 1; // Controller Fan Soft PWM uses 0-127 as 0-100% so cut the 0-255 range in half.
#else
SET_CONTROLLER_FAN();
#if PIN_EXISTS(CONTROLLER_FAN2)

View file

@ -10,7 +10,6 @@
#include "dac_dac084s085.h"
#include "../../MarlinCore.h"
#include "../../HAL/shared/Delay.h"
dac084s085::dac084s085() { }

View file

@ -87,7 +87,7 @@ void StepperDAC::print_values() {
LOOP_LOGICAL_AXES(a) {
SERIAL_CHAR(' ', IAXIS_CHAR(a), ':');
SERIAL_ECHO(dac_perc(a));
SERIAL_ECHOPGM_P(PSTR(" ("), dac_amps(AxisEnum(a)), PSTR(")"));
SERIAL_ECHOPGM_P(PSTR(" ("), dac_amps((AxisEnum)a), PSTR(")"));
}
#if HAS_EXTRUDERS
SERIAL_ECHOLNPGM_P(SP_E_LBL, dac_perc(E_AXIS), PSTR(" ("), dac_amps(E_AXIS), PSTR(")"));

View file

@ -175,7 +175,7 @@ namespace DirectStepping {
template <typename Cfg>
void SerialPageManager<Cfg>::write_responses() {
if (fatal_error) {
kill(GET_TEXT_F(MSG_BAD_PAGE));
marlin.kill(GET_TEXT_F(MSG_BAD_PAGE));
return;
}

View file

@ -33,6 +33,9 @@
// Static data members
bool EmergencyParser::killed_by_M112, // = false
EmergencyParser::quickstop_by_M410,
#if ENABLED(FTM_RESONANCE_TEST)
EmergencyParser::rt_stop_by_M496, // = false
#endif
#if HAS_MEDIA
EmergencyParser::sd_abort_by_M524,
#endif
@ -46,9 +49,6 @@ bool EmergencyParser::killed_by_M112, // = false
// Global instance
EmergencyParser emergency_parser;
// External references
extern bool wait_for_user, wait_for_heatup;
#if ENABLED(EP_BABYSTEPPING)
#include "babystep.h"
#endif
@ -147,9 +147,22 @@ void EmergencyParser::update(EmergencyParser::State &state, const uint8_t c) {
case EP_M10: state = (c == '8') ? EP_M108 : EP_IGNORE; break;
case EP_M11: state = (c == '2') ? EP_M112 : EP_IGNORE; break;
case EP_M4: state = (c == '1') ? EP_M41 : EP_IGNORE; break;
case EP_M4:
switch (c) {
case '1' :state = EP_M41; break;
#if ENABLED(FT_MOTION_RESONANCE_TEST)
case '9': state = EP_M49; break;
#endif
default: state = EP_IGNORE;
}
break;
case EP_M41: state = (c == '0') ? EP_M410 : EP_IGNORE; break;
#if ENABLED(FTM_RESONANCE_TEST)
case EP_M49: state = (c == '6') ? EP_M496 : EP_IGNORE; break;
#endif
#if HAS_MEDIA
case EP_M5: state = (c == '2') ? EP_M52 : EP_IGNORE; break;
case EP_M52: state = (c == '4') ? EP_M524 : EP_IGNORE; break;
@ -192,9 +205,12 @@ void EmergencyParser::update(EmergencyParser::State &state, const uint8_t c) {
default:
if (ISEOL(c)) {
if (enabled) switch (state) {
case EP_M108: wait_for_user = wait_for_heatup = false; break;
case EP_M108: marlin.end_waiting(); break;
case EP_M112: killed_by_M112 = true; break;
case EP_M410: quickstop_by_M410 = true; break;
#if ENABLED(FTM_RESONANCE_TEST)
case EP_M496: rt_stop_by_M496 = true; break;
#endif
#if ENABLED(EP_BABYSTEPPING)
case EP_M293: babystep.ep_babysteps++; break;
case EP_M294: babystep.ep_babysteps--; break;

View file

@ -43,6 +43,9 @@ public:
#if HAS_MEDIA
EP_M5, EP_M52, EP_M524,
#endif
#if ENABLED(FTM_RESONANCE_TEST)
EP_M49, EP_M496,
#endif
#if ENABLED(EP_BABYSTEPPING)
EP_M2, EP_M29, EP_M293, EP_M294,
#endif
@ -64,6 +67,10 @@ public:
static bool killed_by_M112;
static bool quickstop_by_M410;
#if ENABLED(FTM_RESONANCE_TEST)
static bool rt_stop_by_M496;
#endif
#if HAS_MEDIA
static bool sd_abort_by_M524;
#endif
@ -79,6 +86,8 @@ public:
static void update(State &state, const uint8_t c);
static bool isEnabled() { return enabled; }
private:
static bool enabled;
};

View file

@ -91,7 +91,7 @@ void EasythreedUI::blinkLED() {
// Load/Unload buttons are a 3 position switch with a common center ground.
//
void EasythreedUI::loadButton() {
if (printingIsActive()) return;
if (marlin.printingIsActive()) return;
enum FilamentStatus : uint8_t { FS_IDLE, FS_PRESS, FS_CHECK, FS_PROCEED };
static uint8_t filament_status = FS_IDLE;
@ -185,7 +185,7 @@ void EasythreedUI::printButton() {
if (PENDING(ms, key_time, 1200 - BTN_DEBOUNCE_MS)) { // Register a press < 1.2 seconds
switch (print_key_flag) {
case PF_START: { // The "Print" button starts an SD card print
if (printingIsActive()) break; // Already printing? (find another line that checks for 'is planner doing anything else right now?')
if (marlin.printingIsActive()) break; // Already printing? (find another line that checks for 'is planner doing anything else right now?')
blink_interval_ms = LED_BLINK_2; // Blink the indicator LED at 1 second intervals
print_key_flag = PF_PAUSE; // The "Print" button now pauses the print
card.mount(); // Force SD card to mount - now!
@ -201,13 +201,13 @@ void EasythreedUI::printButton() {
card.openAndPrintFile(card.filename); // Start printing it
} break;
case PF_PAUSE: { // Pause printing (not currently firing)
if (!printingIsActive()) break;
if (!marlin.printingIsActive()) break;
blink_interval_ms = LED_ON; // Set indicator to steady ON
queue.inject(F("M25")); // Queue Pause
print_key_flag = PF_RESUME; // The "Print" button now resumes the print
} break;
case PF_RESUME: { // Resume printing
if (printingIsActive()) break;
if (marlin.printingIsActive()) break;
blink_interval_ms = LED_BLINK_2; // Blink the indicator LED at 1 second intervals
queue.inject(F("M24")); // Queue resume
print_key_flag = PF_PAUSE; // The "Print" button now pauses the print
@ -215,7 +215,7 @@ void EasythreedUI::printButton() {
}
}
else { // Register a longer press
if (print_key_flag == PF_START && !printingIsActive()) { // While not printing, this moves Z up 10mm
if (print_key_flag == PF_START && !marlin.printingIsActive()) { // While not printing, this moves Z up 10mm
blink_interval_ms = LED_ON;
queue.inject(F("G91\nG0 Z10 F600\nG90")); // Raise Z soon after returning to main loop
}

View file

@ -149,7 +149,7 @@ void I2CPositionEncoder::update() {
#ifdef I2CPE_ERR_THRESH_ABORT
if (ABS(error) > I2CPE_ERR_THRESH_ABORT * planner.settings.axis_steps_per_mm[encoderAxis]) {
//kill(F("Significant Error"));
//marlin.kill(F("Significant Error"));
SERIAL_ECHOLNPGM("Axis error over threshold, aborting!", error);
safe_delay(5000);
}
@ -801,7 +801,7 @@ void I2CPositionEncodersMgr::M860() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen_test(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) report_position(idx, hasU, hasO);
}
}
@ -828,7 +828,7 @@ void I2CPositionEncodersMgr::M861() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) report_status(idx);
}
}
@ -856,7 +856,7 @@ void I2CPositionEncodersMgr::M862() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) test_axis(idx);
}
}
@ -887,7 +887,7 @@ void I2CPositionEncodersMgr::M863() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) calibrate_steps_mm(idx, iterations);
}
}
@ -963,7 +963,7 @@ void I2CPositionEncodersMgr::M865() {
if (!I2CPE_addr) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) report_module_firmware(encoders[idx].get_address());
}
}
@ -994,12 +994,12 @@ void I2CPositionEncodersMgr::M866() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) {
if (hasR)
reset_error_count(idx, AxisEnum(i));
reset_error_count(idx, (AxisEnum)i);
else
report_error_count(idx, AxisEnum(i));
report_error_count(idx, (AxisEnum)i);
}
}
}
@ -1032,10 +1032,10 @@ void I2CPositionEncodersMgr::M867() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) {
const bool ena = onoff == -1 ? !encoders[I2CPE_idx].get_ec_enabled() : !!onoff;
enable_ec(idx, ena, AxisEnum(i));
enable_ec(idx, ena, (AxisEnum)i);
}
}
}
@ -1068,7 +1068,7 @@ void I2CPositionEncodersMgr::M868() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) {
if (newThreshold != -9999)
set_ec_threshold(idx, newThreshold, encoders[idx].get_axis());
@ -1102,7 +1102,7 @@ void I2CPositionEncodersMgr::M869() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) report_error(idx);
}
}

View file

@ -42,62 +42,18 @@ bool FanCheck::enabled;
void FanCheck::init() {
#define _TACHINIT(N) TERN(E##N##_FAN_TACHO_PULLUP, SET_INPUT_PULLUP, TERN(E##N##_FAN_TACHO_PULLDOWN, SET_INPUT_PULLDOWN, SET_INPUT))(E##N##_FAN_TACHO_PIN)
#if HAS_E0_FAN_TACHO
_TACHINIT(0);
#endif
#if HAS_E1_FAN_TACHO
_TACHINIT(1);
#endif
#if HAS_E2_FAN_TACHO
_TACHINIT(2);
#endif
#if HAS_E3_FAN_TACHO
_TACHINIT(3);
#endif
#if HAS_E4_FAN_TACHO
_TACHINIT(4);
#endif
#if HAS_E5_FAN_TACHO
_TACHINIT(5);
#endif
#if HAS_E6_FAN_TACHO
_TACHINIT(6);
#endif
#if HAS_E7_FAN_TACHO
_TACHINIT(7);
#endif
#define _EN_TACHINIT(N) TERF(HAS_E##N##_FAN_TACHO, _TACHINIT)(N);
REPEAT(8, _EN_TACHINIT);
}
void FanCheck::update_tachometers() {
bool status;
#define _TACHO_CASE(N) case N: status = READ(E##N##_FAN_TACHO_PIN); break;
#define __TACHO_GET_STATUS(N) case N: status = READ(E##N##_FAN_TACHO_PIN); break;
#define _TACHO_GET_STATUS(N) TERF(HAS_E##N##_FAN_TACHO, __TACHO_GET_STATUS)(N)
for (uint8_t f = 0; f < TACHO_COUNT; ++f) {
switch (f) {
#if HAS_E0_FAN_TACHO
_TACHO_CASE(0)
#endif
#if HAS_E1_FAN_TACHO
_TACHO_CASE(1)
#endif
#if HAS_E2_FAN_TACHO
_TACHO_CASE(2)
#endif
#if HAS_E3_FAN_TACHO
_TACHO_CASE(3)
#endif
#if HAS_E4_FAN_TACHO
_TACHO_CASE(4)
#endif
#if HAS_E5_FAN_TACHO
_TACHO_CASE(5)
#endif
#if HAS_E6_FAN_TACHO
_TACHO_CASE(6)
#endif
#if HAS_E7_FAN_TACHO
_TACHO_CASE(7)
#endif
REPEAT(8, _TACHO_GET_STATUS)
default: continue;
}
@ -115,14 +71,8 @@ void FanCheck::compute_speed(uint16_t elapsedTime) {
uint8_t fan_error_msk = 0;
for (uint8_t f = 0; f < TACHO_COUNT; ++f) {
switch (f) {
TERN_(HAS_E0_FAN_TACHO, case 0:)
TERN_(HAS_E1_FAN_TACHO, case 1:)
TERN_(HAS_E2_FAN_TACHO, case 2:)
TERN_(HAS_E3_FAN_TACHO, case 3:)
TERN_(HAS_E4_FAN_TACHO, case 4:)
TERN_(HAS_E5_FAN_TACHO, case 5:)
TERN_(HAS_E6_FAN_TACHO, case 6:)
TERN_(HAS_E7_FAN_TACHO, case 7:)
#define _EN_COMPUTE_FAN_CASE(N) TERN_(HAS_E##N##_FAN_TACHO, case N:)
REPEAT(8, _EN_COMPUTE_FAN_CASE)
// Compute fan speed
rps[f] = edge_counter[f] * float(250) / elapsedTime;
edge_counter[f] = 0;
@ -143,7 +93,7 @@ void FanCheck::compute_speed(uint16_t elapsedTime) {
// Drop the error when all fans are ok
if (!fan_error_msk && error == TachoError::REPORTED) error = TachoError::FIXED;
if (error == TachoError::FIXED && !printJobOngoing() && !printingIsPaused()) {
if (error == TachoError::FIXED && !marlin.printJobOngoing() && !marlin.printingIsPaused()) {
error = TachoError::NONE; // if the issue has been fixed while the printer is idle, reenable immediately
ui.reset_alert_level();
}
@ -156,17 +106,17 @@ void FanCheck::compute_speed(uint16_t elapsedTime) {
}
void FanCheck::report_speed_error(uint8_t fan) {
if (printJobOngoing()) {
if (marlin.printJobOngoing()) {
if (error == TachoError::NONE) {
if (thermalManager.degTargetHotend(fan) != 0) {
kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT));
marlin.kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT));
error = TachoError::REPORTED;
}
else
error = TachoError::DETECTED; // Plans error for next processed command
}
}
else if (!printingIsPaused()) {
else if (!marlin.printingIsPaused()) {
thermalManager.setTargetHotend(0, fan); // Always disable heating
if (error == TachoError::NONE) error = TachoError::REPORTED;
}
@ -179,14 +129,8 @@ void FanCheck::print_fan_states() {
for (uint8_t s = 0; s < 2; ++s) {
for (uint8_t f = 0; f < TACHO_COUNT; ++f) {
switch (f) {
TERN_(HAS_E0_FAN_TACHO, case 0:)
TERN_(HAS_E1_FAN_TACHO, case 1:)
TERN_(HAS_E2_FAN_TACHO, case 2:)
TERN_(HAS_E3_FAN_TACHO, case 3:)
TERN_(HAS_E4_FAN_TACHO, case 4:)
TERN_(HAS_E5_FAN_TACHO, case 5:)
TERN_(HAS_E6_FAN_TACHO, case 6:)
TERN_(HAS_E7_FAN_TACHO, case 7:)
#define _EN_PRINT_FAN_CASE(N) TERN_(HAS_E##N##_FAN_TACHO, case N:)
REPEAT(8, _EN_PRINT_FAN_CASE)
SERIAL_ECHOPGM("E", f);
if (s == 0)
SERIAL_ECHOPGM(":", 60 * rps[f], " RPM ");

View file

@ -25,7 +25,6 @@
#if HAS_FANCHECK
#include "../MarlinCore.h"
#include "../lcd/marlinui.h"
#if ENABLED(AUTO_REPORT_FANS)
@ -74,7 +73,11 @@ class FanCheck {
static void check_deferred_error() {
if (error == TachoError::DETECTED) {
error = TachoError::REPORTED;
TERN(PARK_HEAD_ON_PAUSE, queue.inject(F("M125")), kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT)));
#if ENABLED(PARK_HEAD_ON_PAUSE)
queue.inject(F("M125"));
#else
marlin.kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT));
#endif
}
}

View file

@ -164,9 +164,8 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/))
current_retract[active_extruder] = 0;
// Recover E, set_current_to_destination
prepare_internal_move_to_destination(
MUL_TERN(RETRACT_SYNC_MIXING, swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s, MIXING_STEPPERS)
);
const feedRate_t fr_mm_s = swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s;
prepare_internal_move_to_destination(MUL_TERN(RETRACT_SYNC_MIXING, fr_mm_s, MIXING_STEPPERS));
}
TERN_(RETRACT_SYNC_MIXING, mixer.T(old_mixing_tool)); // Restore original mixing tool

View file

@ -87,10 +87,6 @@ void HostUI::action(FSTR_P const fstr, const bool eol) {
PGMSTR(CONTINUE_STR, "Continue");
PGMSTR(DISMISS_STR, "Dismiss");
#if HAS_RESUME_CONTINUE
extern bool wait_for_user;
#endif
void HostUI::notify(const char * const cstr) {
PORT_REDIRECT(SerialMask::All);
action(F("notification "), false);
@ -205,7 +201,7 @@ void HostUI::action(FSTR_P const fstr, const bool eol) {
}
break;
case PROMPT_USER_CONTINUE:
TERN_(HAS_RESUME_CONTINUE, wait_for_user = false);
TERN_(HAS_RESUME_CONTINUE, marlin.user_resume());
break;
case PROMPT_PAUSE_RESUME:
#if ALL(ADVANCED_PAUSE_FEATURE, HAS_MEDIA)

View file

@ -43,7 +43,7 @@ millis_t HotendIdleProtection::next_protect_ms = 0;
hotend_idle_settings_t HotendIdleProtection::cfg; // Initialized by settings.load
void HotendIdleProtection::check_hotends(const millis_t &ms) {
const bool busy = (TERN0(HAS_RESUME_CONTINUE, wait_for_user) || planner.has_blocks_queued());
const bool busy = (TERN0(HAS_RESUME_CONTINUE, marlin.wait_for_user) || planner.has_blocks_queued());
bool do_prot = false;
if (!busy && cfg.timeout != 0) {
HOTEND_LOOP() {

View file

@ -67,18 +67,10 @@ Joystick joystick;
#if ENABLED(JOYSTICK_DEBUG)
void Joystick::report() {
SERIAL_ECHOPGM("Joystick");
#if HAS_JOY_ADC_X
SERIAL_ECHOPGM_P(SP_X_STR, JOY_X(x.getraw()));
#endif
#if HAS_JOY_ADC_Y
SERIAL_ECHOPGM_P(SP_Y_STR, JOY_Y(y.getraw()));
#endif
#if HAS_JOY_ADC_Z
SERIAL_ECHOPGM_P(SP_Z_STR, JOY_Z(z.getraw()));
#endif
#if HAS_JOY_ADC_EN
SERIAL_ECHO_TERNARY(READ(JOY_EN_PIN), " EN=", "HIGH (dis", "LOW (en", "abled)");
#endif
TERF(HAS_JOY_ADC_X, SERIAL_ECHOPGM_P)(SP_X_STR, JOY_X(x.getraw()));
TERF(HAS_JOY_ADC_Y, SERIAL_ECHOPGM_P)(SP_Y_STR, JOY_Y(y.getraw()));
TERF(HAS_JOY_ADC_Z, SERIAL_ECHOPGM_P)(SP_Z_STR, JOY_Z(z.getraw()));
TERF(HAS_JOY_ADC_EN, SERIAL_ECHO_TERNARY)(READ(JOY_EN_PIN), " EN=", "HIGH (dis", "LOW (en", "abled)");
SERIAL_EOL();
}
#endif

View file

@ -74,14 +74,13 @@
#ifdef MAX7219_DEBUG_PROFILE
// This class sums up the amount of time for which its instances exist.
// By default there is one instantiated for the duration of the idle()
// function. But an instance can be created in any code block to measure
// the time spent from the point of instantiation until the CPU leaves
// block. Be careful about having multiple instances of CodeProfiler as
// it does not guard against double counting. In general mixing ISR and
// non-ISR use will require critical sections but note that mode setting
// is atomic so the total or average times can safely be read if you set
// mode to FREEZE first.
// By default there is one instantiated for the duration of marlin.idle()
// but an instance can be created in any code block to measure time spent
// from instantiation until the CPU leaves the block.
// Be careful about having multiple instances of CodeProfiler as it does
// not guard against double counting. In general mixing ISR and non-ISR
// use will require critical sections but note that mode setting is atomic
// so the total or average times can safely be read if you set mode to FREEZE first.
class CodeProfiler {
public:
enum Mode : uint8_t { ACCUMULATE_AVERAGE, ACCUMULATE_TOTAL, FREEZE };

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