bump to head
This commit is contained in:
File diff suppressed because it is too large
Load Diff
+18
-11
@@ -1,21 +1,22 @@
|
||||
#define PetsfangMicroswiss
|
||||
//#define PetsfangMicroswiss
|
||||
//#define BondtechBMG
|
||||
#define CR10SPro_GearedExtruder
|
||||
//#define CR10SPro_GearedExtruder
|
||||
//#define E3DV6
|
||||
|
||||
//#define FilamentSensorStd
|
||||
//#define FilamentSensorLerdge
|
||||
#define FilamentEncoder
|
||||
|
||||
#define STOCK_2208 // V2 Stock Board with TMC2208 Drivers
|
||||
//#define STOCK_2208 // V2 Stock Board with TMC2208 Drivers
|
||||
//#define SKR13 // 32 bit board - assumes 2208 drivers
|
||||
//#define SKR13_2209
|
||||
//#define E_8825
|
||||
//#define SKR13_UART // Configure SKR board with drivers in UART mode
|
||||
|
||||
#define SX2 // Small formfactor 200mm machine
|
||||
//#define SX2 // Small formfactor 200mm machine
|
||||
|
||||
#define DUAL_Z
|
||||
//#define GRAPHICSLCD
|
||||
#define GRAPHICSLCD
|
||||
#define UBL
|
||||
|
||||
/**
|
||||
@@ -123,6 +124,7 @@
|
||||
/**
|
||||
* Select the serial port on the board to use for communication with the host.
|
||||
* This allows the connection of wireless adapters (for instance) to non-default port pins.
|
||||
* Serial port -1 is the USB emulated serial port, if available.
|
||||
* Note: The first serial port (-1 or 0) will always be used by the Arduino bootloader.
|
||||
*
|
||||
* :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
|
||||
@@ -131,9 +133,6 @@
|
||||
|
||||
/**
|
||||
* Select a secondary serial port on the board to use for communication with the host.
|
||||
* This allows the connection of wireless adapters (for instance) to non-default port pins.
|
||||
* Serial port -1 is the USB emulated serial port, if available.
|
||||
*
|
||||
* :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
|
||||
*/
|
||||
#if ENABLED(SKR13)
|
||||
@@ -397,6 +396,7 @@
|
||||
* 331 : (3.3V scaled thermistor 1 table for MEGA)
|
||||
* 332 : (3.3V scaled thermistor 1 table for DUE)
|
||||
* 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup)
|
||||
* 202 : 200k thermistor - Copymaster 3D
|
||||
* 3 : Mendel-parts thermistor (4.7k pullup)
|
||||
* 4 : 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !!
|
||||
* 5 : 100K thermistor - ATC Semitec 104GT-2/104NT-4-R025H42G (Used in ParCan & J-Head) (4.7k pullup)
|
||||
@@ -1270,7 +1270,7 @@
|
||||
* For other boards you may need to define FIL_RUNOUT_PIN, FIL_RUNOUT2_PIN, etc.
|
||||
* By default the firmware assumes HIGH=FILAMENT PRESENT.
|
||||
*/
|
||||
#if ENABLED(FilamentSensorStd) || ENABLED(FilamentSensorLerdge)
|
||||
#if ANY(FilamentSensorStd, FilamentSensorLerdge, FilamentEncoder)
|
||||
#define FILAMENT_RUNOUT_SENSOR
|
||||
#endif
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|
||||
@@ -1294,13 +1294,19 @@
|
||||
// After a runout is detected, continue printing this length of filament
|
||||
// before executing the runout script. Useful for a sensor at the end of
|
||||
// a feed tube. Requires 4 bytes SRAM per sensor, plus 4 bytes overhead.
|
||||
#define FILAMENT_RUNOUT_DISTANCE_MM 5
|
||||
#if ENABLED(FilamentEncoder)
|
||||
#define FILAMENT_RUNOUT_DISTANCE_MM 15
|
||||
#else
|
||||
#define FILAMENT_RUNOUT_DISTANCE_MM 5
|
||||
#endif
|
||||
|
||||
#ifdef FILAMENT_RUNOUT_DISTANCE_MM
|
||||
// Enable this option to use an encoder disc that toggles the runout pin
|
||||
// as the filament moves. (Be sure to set FILAMENT_RUNOUT_DISTANCE_MM
|
||||
// large enough to avoid false positives.)
|
||||
//#define FILAMENT_MOTION_SENSOR
|
||||
#if ENABLED(FilamentEncoder)
|
||||
#define FILAMENT_MOTION_SENSOR
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1592,6 +1598,7 @@
|
||||
#define EEPROM_SETTINGS // Persistent storage with M500 and M501
|
||||
//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release!
|
||||
#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM.
|
||||
#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors.
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+136
-36
@@ -338,15 +338,22 @@
|
||||
* Controller Fan
|
||||
* To cool down the stepper drivers and MOSFETs.
|
||||
*
|
||||
* The fan will turn on automatically whenever any stepper is enabled
|
||||
* and turn off after a set period after all steppers are turned off.
|
||||
* The fan turns on automatically whenever any driver is enabled and turns
|
||||
* off (or reduces to idle speed) shortly after drivers are turned off.
|
||||
*
|
||||
*/
|
||||
//#define USE_CONTROLLER_FAN
|
||||
#if ENABLED(USE_CONTROLLER_FAN)
|
||||
//#define CONTROLLER_FAN_PIN -1 // Set a custom pin for the controller fan
|
||||
#define CONTROLLERFAN_SECS 60 // Duration in seconds for the fan to run after all motors are disabled
|
||||
#define CONTROLLERFAN_SPEED 255 // 255 == full speed
|
||||
//#define CONTROLLERFAN_SPEED_Z_ONLY 127 // Reduce noise on machines that keep Z enabled
|
||||
//#define CONTROLLER_FAN_PIN -1 // Set a custom pin for the controller fan
|
||||
//#define CONTROLLER_FAN_USE_Z_ONLY // With this option only the Z axis is considered
|
||||
#define CONTROLLERFAN_SPEED_MIN 0 // (0-255) Minimum speed. (If set below this value the fan is turned off.)
|
||||
#define CONTROLLERFAN_SPEED_ACTIVE 255 // (0-255) Active speed, used when any motor is enabled
|
||||
#define CONTROLLERFAN_SPEED_IDLE 0 // (0-255) Idle speed, used when motors are disabled
|
||||
#define CONTROLLERFAN_IDLE_TIME 60 // (seconds) Extra time to keep the fan running after disabling motors
|
||||
//#define CONTROLLER_FAN_EDITABLE // Enable M710 configurable settings
|
||||
#if ENABLED(CONTROLLER_FAN_EDITABLE)
|
||||
#define CONTROLLER_FAN_MENU // Enable the Controller Fan submenu
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// When first starting the main fan, run it at full speed for the
|
||||
@@ -758,8 +765,12 @@
|
||||
// Minimum time that a segment needs to take if the buffer is emptied
|
||||
#define DEFAULT_MINSEGMENTTIME 20000 // (ms)
|
||||
|
||||
// If defined the movements slow down when the look ahead buffer is only half full
|
||||
// Slow down the machine if the look ahead buffer is (by default) half full.
|
||||
// Increase the slowdown divisor for larger buffer sizes.
|
||||
#define SLOWDOWN
|
||||
#if ENABLED(SLOWDOWN)
|
||||
#define SLOWDOWN_DIVISOR 2
|
||||
#endif
|
||||
|
||||
// Frequency limit
|
||||
// See nophead's blog for more info
|
||||
@@ -1007,7 +1018,7 @@
|
||||
#define BOOTSCREEN_TIMEOUT 2000 // (ms) Total Duration to display the boot screen(s)
|
||||
#endif
|
||||
|
||||
#if HAS_GRAPHICAL_LCD && HAS_PRINT_PROGRESS
|
||||
#if HAS_GRAPHICAL_LCD && EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
|
||||
//#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits
|
||||
//#define SHOW_REMAINING_TIME // Display estimated time to completion
|
||||
#if ENABLED(SHOW_REMAINING_TIME)
|
||||
@@ -1046,6 +1057,10 @@
|
||||
|
||||
#define EVENT_GCODE_SD_STOP "G28XY" // G-code to run on Stop Print (e.g., "G28XY" or "G27")
|
||||
|
||||
#if ENABLED(PRINTER_EVENT_LEDS)
|
||||
#define PE_LEDS_COMPLETED_TIME (30*60) // (seconds) Time to keep the LED "done" color before restoring normal illumination
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Continue after Power-Loss (Creality3D)
|
||||
*
|
||||
@@ -1602,18 +1617,11 @@
|
||||
// Add additional compensation depending on hotend temperature
|
||||
// Note: this values cannot be calibrated and have to be set manually
|
||||
#if ENABLED(PROBE_TEMP_COMPENSATION)
|
||||
// Max temperature that can be reached by heated bed.
|
||||
// This is required only for the calibration process.
|
||||
#define PTC_MAX_BED_TEMP BED_MAXTEMP
|
||||
|
||||
// Park position to wait for probe cooldown
|
||||
#define PTC_PARK_POS_X 0.0F
|
||||
#define PTC_PARK_POS_Y 0.0F
|
||||
#define PTC_PARK_POS_Z 100.0F
|
||||
#define PTC_PARK_POS { 0, 0, 100 }
|
||||
|
||||
// Probe position to probe and wait for probe to reach target temperature
|
||||
#define PTC_PROBE_POS_X 90.0F
|
||||
#define PTC_PROBE_POS_Y 100.0F
|
||||
#define PTC_PROBE_POS { 90, 100 }
|
||||
|
||||
// Enable additional compensation using hotend temperature
|
||||
// Note: this values cannot be calibrated automatically but have to be set manually
|
||||
@@ -1911,7 +1919,7 @@
|
||||
#define FILAMENT_UNLOAD_PURGE_FEEDRATE 25 // (mm/s) feedrate to purge before unload
|
||||
|
||||
#define PAUSE_PARK_NOZZLE_TIMEOUT 45 // (seconds) Time limit before the nozzle is turned off for safety.
|
||||
#define FILAMENT_CHANGE_ALERT_BEEPS 10 // Number of alert beeps to play when a response is needed.
|
||||
#define FILAMENT_CHANGE_ALERT_BEEPS 2 // Number of alert beeps to play when a response is needed.
|
||||
#define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable for XYZ steppers to stay powered on during filament change.
|
||||
|
||||
#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change.
|
||||
@@ -2670,31 +2678,123 @@
|
||||
#define SPINDLE_LASER_ACTIVE_HIGH false // Set to "true" if the on/off function is active HIGH
|
||||
#define SPINDLE_LASER_PWM true // Set to "true" if your controller supports setting the speed/power
|
||||
#define SPINDLE_LASER_PWM_INVERT true // Set to "true" if the speed/power goes up when you want it to go slower
|
||||
#define SPINDLE_LASER_POWERUP_DELAY 5000 // (ms) Delay to allow the spindle/laser to come up to speed/power
|
||||
#define SPINDLE_LASER_POWERDOWN_DELAY 5000 // (ms) Delay to allow the spindle to stop
|
||||
|
||||
#define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR and LPC)
|
||||
|
||||
/**
|
||||
* Speed / Power can be set ('M3 S') and displayed in terms of:
|
||||
* - PWM (S0 - S255)
|
||||
* - PERCENT (S0 - S100)
|
||||
* - RPM (S0 - S50000) Best for use with a spindle
|
||||
*/
|
||||
#define CUTTER_POWER_DISPLAY PWM
|
||||
|
||||
/**
|
||||
* Relative mode uses relative range (SPEED_POWER_MIN to SPEED_POWER_MAX) instead of normal range (0 to SPEED_POWER_MAX)
|
||||
* Best use with SuperPID router controller where for example S0 = 5,000 RPM and S255 = 30,000 RPM
|
||||
*/
|
||||
//#define CUTTER_POWER_RELATIVE // Set speed proportional to [SPEED_POWER_MIN...SPEED_POWER_MAX] instead of directly
|
||||
|
||||
#if ENABLED(SPINDLE_FEATURE)
|
||||
//#define SPINDLE_CHANGE_DIR // Enable if your spindle controller can change spindle direction
|
||||
#define SPINDLE_CHANGE_DIR_STOP // Enable if the spindle should stop before changing spin direction
|
||||
#define SPINDLE_INVERT_DIR false // Set to "true" if the spin direction is reversed
|
||||
|
||||
#define SPINDLE_LASER_POWERUP_DELAY 5000 // (ms) Delay to allow the spindle/laser to come up to speed/power
|
||||
#define SPINDLE_LASER_POWERDOWN_DELAY 5000 // (ms) Delay to allow the spindle to stop
|
||||
|
||||
/**
|
||||
* The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
|
||||
* M3/M4 uses the following equation to convert speed/power to PWM duty cycle
|
||||
* Power = ((DC / 255 * 100) - SPEED_POWER_INTERCEPT)) * (1 / SPEED_POWER_SLOPE)
|
||||
* where PWM DC varies from 0 to 255
|
||||
*
|
||||
* SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
|
||||
* where PWM duty cycle varies from 0 to 255
|
||||
*
|
||||
* set the following for your controller (ALL MUST BE SET)
|
||||
* Set these required parameters for your controller
|
||||
*/
|
||||
#define SPEED_POWER_SLOPE 118.4
|
||||
#define SPEED_POWER_INTERCEPT 0
|
||||
#define SPEED_POWER_MIN 5000
|
||||
#define SPEED_POWER_MAX 30000 // SuperPID router controller 0 - 30,000 RPM
|
||||
#define SPEED_POWER_SLOPE 118.4 // SPEED_POWER_SLOPE = SPEED_POWER_MAX / 255
|
||||
#define SPEED_POWER_INTERCEPT 0
|
||||
#define SPEED_POWER_MIN 5000
|
||||
#define SPEED_POWER_MAX 30000 // SuperPID router controller 0 - 30,000 RPM
|
||||
#define SPEED_POWER_STARTUP 25000 // The default value for speed power when M3 is called without arguments
|
||||
|
||||
#else
|
||||
#define SPEED_POWER_SLOPE 0.3922
|
||||
#define SPEED_POWER_INTERCEPT 0
|
||||
#define SPEED_POWER_MIN 10
|
||||
#define SPEED_POWER_MAX 100 // 0-100%
|
||||
|
||||
#define SPEED_POWER_SLOPE 0.3922 // SPEED_POWER_SLOPE = SPEED_POWER_MAX / 255
|
||||
#define SPEED_POWER_INTERCEPT 0
|
||||
#define SPEED_POWER_MIN 0
|
||||
#define SPEED_POWER_MAX 100 // 0-100%
|
||||
#define SPEED_POWER_STARTUP 80 // The default value for speed power when M3 is called without arguments
|
||||
|
||||
/**
|
||||
* Enable inline laser power to be handled in the planner / stepper routines.
|
||||
* Inline power is specified by the I (inline) flag in an M3 command (e.g., M3 S20 I)
|
||||
* or by the 'S' parameter in G0/G1/G2/G3 moves (see LASER_MOVE_POWER).
|
||||
*
|
||||
* This allows the laser to keep in perfect sync with the planner and removes
|
||||
* the powerup/down delay since lasers require negligible time.
|
||||
*/
|
||||
#define LASER_POWER_INLINE
|
||||
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
/**
|
||||
* Scale the laser's power in proportion to the movement rate.
|
||||
*
|
||||
* - Sets the entry power proportional to the entry speed over the nominal speed.
|
||||
* - Ramps the power up every N steps to approximate the speed trapezoid.
|
||||
* - Due to the limited power resolution this is only approximate.
|
||||
*/
|
||||
#define LASER_POWER_INLINE_TRAPEZOID
|
||||
|
||||
/**
|
||||
* Continuously calculate the current power (nominal_power * current_rate / nominal_rate).
|
||||
* Required for accurate power with non-trapezoidal acceleration (e.g., S_CURVE_ACCELERATION).
|
||||
* This is a costly calculation so this option is discouraged on 8-bit AVR boards.
|
||||
*
|
||||
* LASER_POWER_INLINE_TRAPEZOID_CONT_PER defines how many step cycles there are between power updates. If your
|
||||
* board isn't able to generate steps fast enough (and you are using LASER_POWER_INLINE_TRAPEZOID_CONT), increase this.
|
||||
* Note that when this is zero it means it occurs every cycle; 1 means a delay wait one cycle then run, etc.
|
||||
*/
|
||||
//#define LASER_POWER_INLINE_TRAPEZOID_CONT
|
||||
|
||||
/**
|
||||
* Stepper iterations between power updates. Increase this value if the board
|
||||
* can't keep up with the processing demands of LASER_POWER_INLINE_TRAPEZOID_CONT.
|
||||
* Disable (or set to 0) to recalculate power on every stepper iteration.
|
||||
*/
|
||||
//#define LASER_POWER_INLINE_TRAPEZOID_CONT_PER 10
|
||||
|
||||
/**
|
||||
* Include laser power in G0/G1/G2/G3/G5 commands with the 'S' parameter
|
||||
*/
|
||||
//#define LASER_MOVE_POWER
|
||||
|
||||
#if ENABLED(LASER_MOVE_POWER)
|
||||
// Turn off the laser on G0 moves with no power parameter.
|
||||
// If a power parameter is provided, use that instead.
|
||||
//#define LASER_MOVE_G0_OFF
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Inline flag inverted
|
||||
*
|
||||
* WARNING: M5 will NOT turn off the laser unless another move
|
||||
* is done (so G-code files must end with 'M5 I').
|
||||
*/
|
||||
//#define LASER_POWER_INLINE_INVERT
|
||||
|
||||
/**
|
||||
* Continuously apply inline power. ('M3 S3' == 'G1 S3' == 'M3 S3 I')
|
||||
*
|
||||
* The laser might do some weird things, so only enable this
|
||||
* feature if you understand the implications.
|
||||
*/
|
||||
//#define LASER_POWER_INLINE_CONTINUOUS
|
||||
|
||||
#else
|
||||
|
||||
#define SPINDLE_LASER_POWERUP_DELAY 50 // (ms) Delay to allow the spindle/laser to come up to speed/power
|
||||
#define SPINDLE_LASER_POWERDOWN_DELAY 50 // (ms) Delay to allow the spindle to stop
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -2862,7 +2962,7 @@
|
||||
|
||||
#define CommBedTmp "65"
|
||||
#if ENABLED(DUAL_Z)
|
||||
#define ALIGN_CMD "G34I20\n"
|
||||
#define ALIGN_CMD "G34RI20\n"
|
||||
#else
|
||||
#define ALIGN_CMD ""
|
||||
#endif
|
||||
@@ -2874,10 +2974,10 @@
|
||||
#endif
|
||||
|
||||
#define USER_DESC_2 "PID Tune"
|
||||
#define USER_GCODE_2 "M106 S128 \n M303 C8 S225 E0 U \n M500 \n M117 PID Tune Done"
|
||||
#define USER_GCODE_2 "M106 S128\nM303C8S225E0\nM500\nM117 PID Tune Done"
|
||||
|
||||
#define USER_DESC_3 "Prep for Z Adjust"
|
||||
#define USER_GCODE_3 "M190 S" CommBedTmp" \n M104 S235 \n G28 \n G29 L1 \n G1 X100 Y 100 \n G1 Z0"
|
||||
#define USER_GCODE_3 "M190S" CommBedTmp"\nM104S235\nG28\nG29L1\nG1X100Y100\nG1Z0"
|
||||
|
||||
#define USER_DESC_4 "Store Settings"
|
||||
#define USER_GCODE_4 "M500\nM117 Settings Stored"
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@
|
||||
/**
|
||||
* Marlin release version identifier
|
||||
*/
|
||||
#define SHORT_BUILD_VERSION "2.0.5_SX4L"
|
||||
#define SHORT_BUILD_VERSION "2.0.5_SX4M"
|
||||
|
||||
/**
|
||||
* Verbose version identifier which should contain a reference to the location
|
||||
@@ -41,7 +41,7 @@
|
||||
* here we define this default string as the date where the latest release
|
||||
* version was tagged.
|
||||
*/
|
||||
#define STRING_DISTRIBUTION_DATE "2020-03-19"
|
||||
#define STRING_DISTRIBUTION_DATE "2020-04-07"
|
||||
|
||||
/**
|
||||
* Defines a generic printer name to be output to the LCD after booting Marlin.
|
||||
|
||||
@@ -395,6 +395,8 @@ inline void HAL_adc_init() {
|
||||
// AVR compatibility
|
||||
#define strtof strtod
|
||||
|
||||
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
|
||||
|
||||
/**
|
||||
* set_pwm_frequency
|
||||
* Sets the frequency of the timer corresponding to the provided pin
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE)
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
bool PersistentStore::access_start() { return true; }
|
||||
bool PersistentStore::access_finish() { return true; }
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM
|
||||
#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
|
||||
|
||||
#include "HAL.h"
|
||||
|
||||
@@ -278,5 +278,5 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
|
||||
}
|
||||
}
|
||||
|
||||
#endif // FAST_PWM_FAN || SPINDLE_LASER_PWM
|
||||
#endif // NEEDS_HARDWARE_PWM
|
||||
#endif // __AVR__
|
||||
|
||||
@@ -98,9 +98,9 @@
|
||||
|
||||
#define SET_INPUT(IO) _SET_INPUT(IO)
|
||||
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0)
|
||||
#define SET_INPUT_PULLDOWN SET_INPUT
|
||||
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
||||
|
||||
#define SET_PWM(IO) SET_OUTPUT(IO)
|
||||
#define SET_PWM SET_OUTPUT
|
||||
|
||||
#define IS_INPUT(IO) _IS_INPUT(IO)
|
||||
#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
||||
|
||||
#include "../shared/Marduino.h"
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
#define EEPROMSize 4096
|
||||
#define PagesPerGroup 128
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
// Define MYSERIAL0/1 before MarlinSerial includes!
|
||||
#if SERIAL_PORT == -1
|
||||
#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER)
|
||||
#define MYSERIAL0 customizedSerial1
|
||||
#elif SERIAL_PORT == 0
|
||||
#define MYSERIAL0 Serial
|
||||
@@ -56,7 +56,7 @@
|
||||
#ifdef SERIAL_PORT_2
|
||||
#if SERIAL_PORT_2 == SERIAL_PORT
|
||||
#error "SERIAL_PORT_2 must be different from SERIAL_PORT. Please update your configuration."
|
||||
#elif SERIAL_PORT_2 == -1
|
||||
#elif SERIAL_PORT_2 == -1 || ENABLED(EMERGENCY_PARSER)
|
||||
#define MYSERIAL1 customizedSerial2
|
||||
#elif SERIAL_PORT_2 == 0
|
||||
#define MYSERIAL1 Serial
|
||||
@@ -94,7 +94,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include "MarlinSerial.h"
|
||||
#include "MarlinSerialUSB.h"
|
||||
|
||||
|
||||
@@ -629,23 +629,13 @@ void MarlinSerial<Cfg>::printFloat(double number, uint8_t digits) {
|
||||
|
||||
// If not using the USB port as serial port
|
||||
#if SERIAL_PORT >= 0
|
||||
|
||||
// Preinstantiate
|
||||
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>;
|
||||
|
||||
// Instantiate
|
||||
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
|
||||
|
||||
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>; // Define
|
||||
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1; // Instantiate
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_PORT_2
|
||||
|
||||
// Preinstantiate
|
||||
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>;
|
||||
|
||||
// Instantiate
|
||||
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
|
||||
|
||||
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
|
||||
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>; // Define
|
||||
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2; // Instantiate
|
||||
#endif
|
||||
|
||||
#endif // ARDUINO_ARCH_SAM
|
||||
|
||||
@@ -172,13 +172,9 @@ struct MarlinSerialCfg {
|
||||
};
|
||||
|
||||
#if SERIAL_PORT >= 0
|
||||
|
||||
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
|
||||
|
||||
#endif // SERIAL_PORT >= 0
|
||||
|
||||
#ifdef SERIAL_PORT_2
|
||||
|
||||
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
|
||||
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if SERIAL_PORT == -1
|
||||
#if HAS_USB_SERIAL
|
||||
|
||||
#include "MarlinSerialUSB.h"
|
||||
|
||||
@@ -283,8 +283,12 @@ void MarlinSerialUSB::printFloat(double number, uint8_t digits) {
|
||||
}
|
||||
|
||||
// Preinstantiate
|
||||
MarlinSerialUSB customizedSerial1;
|
||||
|
||||
#endif // SERIAL_PORT == -1
|
||||
#if SERIAL_PORT == -1
|
||||
MarlinSerialUSB customizedSerial1;
|
||||
#endif
|
||||
#if SERIAL_PORT_2 == -1
|
||||
MarlinSerialUSB customizedSerial2;
|
||||
#endif
|
||||
|
||||
#endif // HAS_USB_SERIAL
|
||||
#endif // ARDUINO_ARCH_SAM
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if SERIAL_PORT == -1
|
||||
#if HAS_USB_SERIAL
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
@@ -88,6 +88,12 @@ private:
|
||||
static void printFloat(double, uint8_t);
|
||||
};
|
||||
|
||||
extern MarlinSerialUSB customizedSerial1;
|
||||
#if SERIAL_PORT == -1
|
||||
extern MarlinSerialUSB customizedSerial1;
|
||||
#endif
|
||||
|
||||
#endif // SERIAL_PORT == -1
|
||||
#if SERIAL_PORT_2 == -1
|
||||
extern MarlinSerialUSB customizedSerial2;
|
||||
#endif
|
||||
|
||||
#endif // HAS_USB_SERIAL
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
#if !defined(E2END) && ENABLED(FLASH_EEPROM_EMULATION)
|
||||
#define E2END 0xFFF // Default to Flash emulated EEPROM size (EepromEmulation_Due.cpp)
|
||||
@@ -166,7 +166,7 @@
|
||||
// Set pin as output (wrapper) - reads the pin and sets the output to that value
|
||||
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
||||
// Set pin as PWM
|
||||
#define SET_PWM(IO) SET_OUTPUT(IO)
|
||||
#define SET_PWM SET_OUTPUT
|
||||
|
||||
// Check if pin is an input
|
||||
#define IS_INPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) == 0)
|
||||
|
||||
@@ -46,6 +46,31 @@
|
||||
|
||||
#include "G2_PWM.h"
|
||||
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_X)
|
||||
#define G2_PWM_X 1
|
||||
#else
|
||||
#define G2_PWM_X 0
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Y)
|
||||
#define G2_PWM_Y 1
|
||||
#else
|
||||
#define G2_PWM_Y 0
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
|
||||
#define G2_PWM_Z 1
|
||||
#else
|
||||
#define G2_PWM_Z 0
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#define G2_PWM_E 1
|
||||
#else
|
||||
#define G2_PWM_E 0
|
||||
#endif
|
||||
#define G2_MASK_X(V) (G2_PWM_X * (V))
|
||||
#define G2_MASK_Y(V) (G2_PWM_Y * (V))
|
||||
#define G2_MASK_Z(V) (G2_PWM_Z * (V))
|
||||
#define G2_MASK_E(V) (G2_PWM_E * (V))
|
||||
|
||||
volatile uint32_t *SODR_A = &PIOA->PIO_SODR,
|
||||
*SODR_B = &PIOB->PIO_SODR,
|
||||
*CODR_A = &PIOA->PIO_CODR,
|
||||
@@ -55,10 +80,18 @@ PWM_map ISR_table[NUM_PWMS] = PWM_MAP_INIT;
|
||||
|
||||
void Stepper::digipot_init() {
|
||||
|
||||
OUT_WRITE(MOTOR_CURRENT_PWM_X_PIN, 0); // init pins
|
||||
OUT_WRITE(MOTOR_CURRENT_PWM_Y_PIN, 0);
|
||||
OUT_WRITE(MOTOR_CURRENT_PWM_Z_PIN, 0);
|
||||
OUT_WRITE(MOTOR_CURRENT_PWM_E_PIN, 0);
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_X)
|
||||
OUT_WRITE(MOTOR_CURRENT_PWM_X_PIN, 0); // init pins
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Y)
|
||||
OUT_WRITE(MOTOR_CURRENT_PWM_Y_PIN, 0);
|
||||
#endif
|
||||
#if G2_PWM_Z
|
||||
OUT_WRITE(MOTOR_CURRENT_PWM_Z_PIN, 0);
|
||||
#endif
|
||||
#if G2_PWM_E
|
||||
OUT_WRITE(MOTOR_CURRENT_PWM_E_PIN, 0);
|
||||
#endif
|
||||
|
||||
#define WPKEY (0x50574D << 8) // “PWM” in ASCII
|
||||
#define WPCMD_DIS_SW 0 // command to disable Write Protect SW
|
||||
@@ -71,30 +104,51 @@ void Stepper::digipot_init() {
|
||||
PWM->PWM_WPCR = WPKEY | WPRG_ALL | WPCMD_DIS_SW; // enable setting of all PWM registers
|
||||
PWM->PWM_CLK = PWM_CLOCK_F; // enable CLK_A and set it to 1MHz, leave CLK_B disabled
|
||||
PWM->PWM_CH_NUM[0].PWM_CMR = 0b1011; // set channel 0 to Clock A input & to left aligned
|
||||
PWM->PWM_CH_NUM[1].PWM_CMR = 0b1011; // set channel 1 to Clock A input & to left aligned
|
||||
PWM->PWM_CH_NUM[2].PWM_CMR = 0b1011; // set channel 2 to Clock A input & to left aligned
|
||||
PWM->PWM_CH_NUM[3].PWM_CMR = 0b1011; // set channel 3 to Clock A input & to left aligned
|
||||
PWM->PWM_CH_NUM[4].PWM_CMR = 0b1011; // set channel 4 to Clock A input & to left aligned
|
||||
if (G2_PWM_X) PWM->PWM_CH_NUM[1].PWM_CMR = 0b1011; // set channel 1 to Clock A input & to left aligned
|
||||
if (G2_PWM_Y) PWM->PWM_CH_NUM[2].PWM_CMR = 0b1011; // set channel 2 to Clock A input & to left aligned
|
||||
if (G2_PWM_Z) PWM->PWM_CH_NUM[3].PWM_CMR = 0b1011; // set channel 3 to Clock A input & to left aligned
|
||||
if (G2_PWM_E) PWM->PWM_CH_NUM[4].PWM_CMR = 0b1011; // set channel 4 to Clock A input & to left aligned
|
||||
|
||||
PWM->PWM_CH_NUM[0].PWM_CPRD = PWM_PERIOD_US; // set channel 0 Period
|
||||
|
||||
PWM->PWM_IER2 = PWM_IER1_CHID0; // generate interrupt when counter0 overflows
|
||||
PWM->PWM_IER2 = PWM_IER2_CMPM0 | PWM_IER2_CMPM1 | PWM_IER2_CMPM2 | PWM_IER2_CMPM3 | PWM_IER2_CMPM4; // generate interrupt on compare event
|
||||
PWM->PWM_IER2 = PWM_IER2_CMPM0
|
||||
| G2_MASK_X(PWM_IER2_CMPM1)
|
||||
| G2_MASK_Y(PWM_IER2_CMPM2)
|
||||
| G2_MASK_Z(PWM_IER2_CMPM3)
|
||||
| G2_MASK_E(PWM_IER2_CMPM4)
|
||||
; // generate interrupt on compare event
|
||||
|
||||
PWM->PWM_CMP[1].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 1 PWM inactive
|
||||
PWM->PWM_CMP[2].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 2 PWM inactive
|
||||
PWM->PWM_CMP[3].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[1])); // interrupt when counter0 == CMPV - used to set Motor 3 PWM inactive
|
||||
PWM->PWM_CMP[4].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[2])); // interrupt when counter0 == CMPV - used to set Motor 4 PWM inactive
|
||||
if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 1 PWM inactive
|
||||
if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 2 PWM inactive
|
||||
if (G2_PWM_Z) PWM->PWM_CMP[3].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[1])); // interrupt when counter0 == CMPV - used to set Motor 3 PWM inactive
|
||||
if (G2_PWM_E) PWM->PWM_CMP[4].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[2])); // interrupt when counter0 == CMPV - used to set Motor 4 PWM inactive
|
||||
|
||||
PWM->PWM_CMP[1].PWM_CMPM = 0x0001; // enable compare event
|
||||
PWM->PWM_CMP[2].PWM_CMPM = 0x0001; // enable compare event
|
||||
PWM->PWM_CMP[3].PWM_CMPM = 0x0001; // enable compare event
|
||||
PWM->PWM_CMP[4].PWM_CMPM = 0x0001; // enable compare event
|
||||
if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPM = 0x0001; // enable compare event
|
||||
if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPM = 0x0001; // enable compare event
|
||||
if (G2_PWM_Z) PWM->PWM_CMP[3].PWM_CMPM = 0x0001; // enable compare event
|
||||
if (G2_PWM_E) PWM->PWM_CMP[4].PWM_CMPM = 0x0001; // enable compare event
|
||||
|
||||
PWM->PWM_SCM = PWM_SCM_UPDM_MODE0 | PWM_SCM_SYNC0 | PWM_SCM_SYNC1 | PWM_SCM_SYNC2 | PWM_SCM_SYNC3 | PWM_SCM_SYNC4; // sync 1-4 with 0, use mode 0 for updates
|
||||
PWM->PWM_SCM = PWM_SCM_UPDM_MODE0 | PWM_SCM_SYNC0
|
||||
| G2_MASK_X(PWM_SCM_SYNC1)
|
||||
| G2_MASK_Y(PWM_SCM_SYNC2)
|
||||
| G2_MASK_Z(PWM_SCM_SYNC3)
|
||||
| G2_MASK_E(PWM_SCM_SYNC4)
|
||||
; // sync 1-4 with 0, use mode 0 for updates
|
||||
|
||||
PWM->PWM_ENA = PWM_ENA_CHID0 | PWM_ENA_CHID1 | PWM_ENA_CHID2 | PWM_ENA_CHID3 | PWM_ENA_CHID4; // enable the channels used by G2
|
||||
PWM->PWM_IER1 = PWM_IER1_CHID0 | PWM_IER1_CHID1 | PWM_IER1_CHID2 | PWM_IER1_CHID3 | PWM_IER1_CHID4; // enable interrupts for the channels used by G2
|
||||
PWM->PWM_ENA = PWM_ENA_CHID0
|
||||
| G2_MASK_X(PWM_ENA_CHID1)
|
||||
| G2_MASK_Y(PWM_ENA_CHID2)
|
||||
| G2_MASK_Z(PWM_ENA_CHID3)
|
||||
| G2_MASK_E(PWM_ENA_CHID4)
|
||||
; // enable channels used by G2
|
||||
|
||||
PWM->PWM_IER1 = PWM_IER1_CHID0
|
||||
| G2_MASK_X(PWM_IER1_CHID1)
|
||||
| G2_MASK_Y(PWM_IER1_CHID2)
|
||||
| G2_MASK_Z(PWM_IER1_CHID3)
|
||||
| G2_MASK_E(PWM_IER1_CHID4)
|
||||
; // enable interrupts for channels used by G2
|
||||
|
||||
NVIC_EnableIRQ(PWM_IRQn); // Enable interrupt handler
|
||||
NVIC_SetPriority(PWM_IRQn, NVIC_EncodePriority(0, 10, 0)); // normal priority for PWM module (can stand some jitter on the Vref signals)
|
||||
@@ -105,20 +159,27 @@ void Stepper::digipot_current(const uint8_t driver, const int16_t current) {
|
||||
if (!(PWM->PWM_CH_NUM[0].PWM_CPRD == PWM_PERIOD_US)) digipot_init(); // Init PWM system if needed
|
||||
|
||||
switch (driver) {
|
||||
case 0: PWM->PWM_CMP[1].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update X & Y
|
||||
PWM->PWM_CMP[2].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current));
|
||||
PWM->PWM_CMP[1].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||
PWM->PWM_CMP[2].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
||||
break;
|
||||
case 1: PWM->PWM_CMP[3].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update Z
|
||||
PWM->PWM_CMP[3].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
||||
break;
|
||||
default:PWM->PWM_CMP[4].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update E
|
||||
PWM->PWM_CMP[4].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
||||
break;
|
||||
case 0:
|
||||
if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update X & Y
|
||||
if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current));
|
||||
if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||
if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||
if (G2_PWM_X || G2_PWM_Y) PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
||||
break;
|
||||
case 1:
|
||||
if (G2_PWM_Z) {
|
||||
PWM->PWM_CMP[3].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update Z
|
||||
PWM->PWM_CMP[3].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (G2_PWM_E) {
|
||||
PWM->PWM_CMP[4].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update E
|
||||
PWM->PWM_CMP[4].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,17 +188,17 @@ volatile uint32_t PWM_ISR1_STATUS, PWM_ISR2_STATUS;
|
||||
void PWM_Handler() {
|
||||
PWM_ISR1_STATUS = PWM->PWM_ISR1;
|
||||
PWM_ISR2_STATUS = PWM->PWM_ISR2;
|
||||
if (PWM_ISR1_STATUS & PWM_IER1_CHID0) { // CHAN_0 interrupt
|
||||
*ISR_table[0].set_register = ISR_table[0].write_mask; // set X to active
|
||||
*ISR_table[1].set_register = ISR_table[1].write_mask; // set Y to active
|
||||
*ISR_table[2].set_register = ISR_table[2].write_mask; // set Z to active
|
||||
*ISR_table[3].set_register = ISR_table[3].write_mask; // set E to active
|
||||
if (PWM_ISR1_STATUS & PWM_IER1_CHID0) { // CHAN_0 interrupt
|
||||
if (G2_PWM_X) *ISR_table[0].set_register = ISR_table[0].write_mask; // set X to active
|
||||
if (G2_PWM_Y) *ISR_table[1].set_register = ISR_table[1].write_mask; // set Y to active
|
||||
if (G2_PWM_Z) *ISR_table[2].set_register = ISR_table[2].write_mask; // set Z to active
|
||||
if (G2_PWM_E) *ISR_table[3].set_register = ISR_table[3].write_mask; // set E to active
|
||||
}
|
||||
else {
|
||||
if (PWM_ISR2_STATUS & PWM_IER2_CMPM1) *ISR_table[0].clr_register = ISR_table[0].write_mask; // set X to inactive
|
||||
if (PWM_ISR2_STATUS & PWM_IER2_CMPM2) *ISR_table[1].clr_register = ISR_table[1].write_mask; // set Y to inactive
|
||||
if (PWM_ISR2_STATUS & PWM_IER2_CMPM3) *ISR_table[2].clr_register = ISR_table[2].write_mask; // set Z to inactive
|
||||
if (PWM_ISR2_STATUS & PWM_IER2_CMPM4) *ISR_table[3].clr_register = ISR_table[3].write_mask; // set E to inactive
|
||||
if (G2_PWM_X && (PWM_ISR2_STATUS & PWM_IER2_CMPM1)) *ISR_table[0].clr_register = ISR_table[0].write_mask; // set X to inactive
|
||||
if (G2_PWM_Y && (PWM_ISR2_STATUS & PWM_IER2_CMPM2)) *ISR_table[1].clr_register = ISR_table[1].write_mask; // set Y to inactive
|
||||
if (G2_PWM_Z && (PWM_ISR2_STATUS & PWM_IER2_CMPM3)) *ISR_table[2].clr_register = ISR_table[2].write_mask; // set Z to inactive
|
||||
if (G2_PWM_E && (PWM_ISR2_STATUS & PWM_IER2_CMPM4)) *ISR_table[3].clr_register = ISR_table[3].write_mask; // set E to inactive
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if USE_EMULATED_EEPROM
|
||||
#if USE_FALLBACK_EEPROM
|
||||
#undef SRAM_EEPROM_EMULATION
|
||||
#undef SDCARD_EEPROM_EMULATION
|
||||
#define FLASH_EEPROM_EMULATION
|
||||
|
||||
+4
-4
@@ -24,10 +24,10 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS) && DISABLED(FLASH_EEPROM_EMULATION)
|
||||
#if USE_WIRED_EEPROM
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "EEPROM.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
#include <EEPROM.h>
|
||||
|
||||
#define EEPROM_SIZE 4096
|
||||
|
||||
@@ -59,5 +59,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t
|
||||
|
||||
size_t PersistentStore::capacity() { return EEPROM_SIZE; }
|
||||
|
||||
#endif // EEPROM_SETTINGS
|
||||
#endif // USE_WIRED_EEPROM
|
||||
#endif // ARDUINO_ARCH_ESP32
|
||||
@@ -56,7 +56,7 @@
|
||||
#define SET_OUTPUT(IO) do{ _SET_OUTPUT(IO); }while(0)
|
||||
|
||||
// Set pin as PWM
|
||||
#define SET_PWM(IO) SET_OUTPUT(IO)
|
||||
#define SET_PWM SET_OUTPUT
|
||||
|
||||
// Set pin as output and init
|
||||
#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// If no real EEPROM, Flash emulation, or SRAM emulation is available fall back to SD emulation
|
||||
#if ENABLED(EEPROM_SETTINGS) && NONE(USE_REAL_EEPROM, FLASH_EEPROM_EMULATION, SRAM_EEPROM_EMULATION)
|
||||
#define SDCARD_EEPROM_EMULATION
|
||||
#undef USE_WIRED_EEPROM
|
||||
#if ENABLED(EEPROM_SETTINGS) && DISABLED(FLASH_EEPROM_EMULATION)
|
||||
#define USE_WIRED_EEPROM 1
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define LINUX_EEPROM_SIZE (E2END + 1)
|
||||
@@ -67,9 +67,7 @@ int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
|
||||
return ind > -1 ? ind : dval;
|
||||
}
|
||||
|
||||
void flashFirmware(int16_t value) {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
void flashFirmware(const int16_t) { NVIC_SystemReset(); }
|
||||
|
||||
void HAL_clear_reset_source(void) {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
@@ -195,7 +195,9 @@ int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
|
||||
void HAL_idletask();
|
||||
|
||||
#define PLATFORM_M997_SUPPORT
|
||||
void flashFirmware(int16_t value);
|
||||
void flashFirmware(const int16_t);
|
||||
|
||||
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
|
||||
|
||||
/**
|
||||
* set_pwm_frequency
|
||||
|
||||
@@ -21,6 +21,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
#define FLASH_EEPROM_EMULATION
|
||||
+1
-1
@@ -40,7 +40,7 @@
|
||||
|
||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
||||
|
||||
#include "persistent_store_api.h"
|
||||
#include "eeprom_api.h"
|
||||
|
||||
extern "C" {
|
||||
#include <lpc17xx_iap.h>
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
|
||||
#if ENABLED(SDCARD_EEPROM_EMULATION)
|
||||
|
||||
#include "persistent_store_api.h"
|
||||
#include "eeprom_api.h"
|
||||
|
||||
#include <chanfs/diskio.h>
|
||||
#include <chanfs/ff.h>
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM
|
||||
#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
|
||||
|
||||
#include <pwm.h>
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
/// set pin as output wrapper - reads the pin and sets the output to that value
|
||||
#define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0)
|
||||
// set pin as PWM
|
||||
#define SET_PWM(IO) SET_OUTPUT(IO)
|
||||
#define SET_PWM SET_OUTPUT
|
||||
|
||||
/// check if pin is an input wrapper
|
||||
#define IS_INPUT(IO) _IS_INPUT(IO)
|
||||
|
||||
@@ -21,6 +21,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if USE_EMULATED_EEPROM && NONE(SDCARD_EEPROM_EMULATION, SRAM_EEPROM_EMULATION)
|
||||
#if USE_FALLBACK_EEPROM && NONE(SDCARD_EEPROM_EMULATION, SRAM_EEPROM_EMULATION)
|
||||
#define FLASH_EEPROM_EMULATION
|
||||
#endif
|
||||
|
||||
@@ -90,7 +90,7 @@ void HAL_init() {
|
||||
|
||||
//debug_frmwrk_init();
|
||||
//_DBG("\n\nDebug running\n");
|
||||
// Initialise the SD card chip select pins as soon as possible
|
||||
// Initialize the SD card chip select pins as soon as possible
|
||||
#if PIN_EXISTS(SS)
|
||||
OUT_WRITE(SS_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(QSPI_EEPROM)
|
||||
|
||||
#include "QSPIFlash.h"
|
||||
|
||||
#define INVALID_ADDR 0xffffffff
|
||||
#define SECTOR_OF(a) (a & ~(SFLASH_SECTOR_SIZE - 1))
|
||||
#define OFFSET_OF(a) (a & (SFLASH_SECTOR_SIZE - 1))
|
||||
|
||||
Adafruit_SPIFlashBase * QSPIFlash::_flashBase = nullptr;
|
||||
uint8_t QSPIFlash::_buf[SFLASH_SECTOR_SIZE];
|
||||
uint32_t QSPIFlash::_addr = INVALID_ADDR;
|
||||
|
||||
void QSPIFlash::begin() {
|
||||
if (_flashBase != nullptr) return;
|
||||
|
||||
_flashBase = new Adafruit_SPIFlashBase(new Adafruit_FlashTransport_QSPI());
|
||||
_flashBase->begin(NULL);
|
||||
}
|
||||
|
||||
size_t QSPIFlash::size() {
|
||||
return _flashBase->size();
|
||||
}
|
||||
|
||||
uint8_t QSPIFlash::readByte(const uint32_t address) {
|
||||
if (SECTOR_OF(address) == _addr) return _buf[OFFSET_OF(address)];
|
||||
|
||||
return _flashBase->read8(address);
|
||||
}
|
||||
|
||||
void QSPIFlash::writeByte(const uint32_t address, const uint8_t value) {
|
||||
uint32_t const sector_addr = SECTOR_OF(address);
|
||||
|
||||
// Page changes, flush old and update new cache
|
||||
if (sector_addr != _addr) {
|
||||
flush();
|
||||
_addr = sector_addr;
|
||||
|
||||
// read a whole page from flash
|
||||
_flashBase->readBuffer(sector_addr, _buf, SFLASH_SECTOR_SIZE);
|
||||
}
|
||||
|
||||
_buf[OFFSET_OF(address)] = value;
|
||||
}
|
||||
|
||||
void QSPIFlash::flush() {
|
||||
if (_addr == INVALID_ADDR) return;
|
||||
|
||||
_flashBase->eraseSector(_addr / SFLASH_SECTOR_SIZE);
|
||||
_flashBase->writeBuffer(_addr, _buf, SFLASH_SECTOR_SIZE);
|
||||
|
||||
_addr = INVALID_ADDR;
|
||||
}
|
||||
|
||||
#endif // QSPI_EEPROM
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @file QSPIFlash.h
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach and Dean Miller for Adafruit Industries LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Derived from Adafruit_SPIFlash class with no SdFat references
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Adafruit_SPIFlashBase.h>
|
||||
|
||||
// This class extends Adafruit_SPIFlashBase by adding caching support.
|
||||
//
|
||||
// This class will use 4096 Bytes of RAM as a block cache.
|
||||
class QSPIFlash {
|
||||
public:
|
||||
static void begin();
|
||||
static size_t size();
|
||||
static uint8_t readByte(const uint32_t address);
|
||||
static void writeByte(const uint32_t address, const uint8_t v);
|
||||
static void flush();
|
||||
|
||||
private:
|
||||
static Adafruit_SPIFlashBase * _flashBase;
|
||||
static uint8_t _buf[SFLASH_SECTOR_SIZE];
|
||||
static uint32_t _addr;
|
||||
};
|
||||
|
||||
extern QSPIFlash qspi;
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __SAMD51__
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS) && NONE(QSPI_EEPROM, FLASH_EEPROM_EMULATION)
|
||||
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
size_t PersistentStore::capacity() { return E2END + 1; }
|
||||
|
||||
bool PersistentStore::access_start() { return true; }
|
||||
bool PersistentStore::access_finish() { return true; }
|
||||
|
||||
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
|
||||
while (size--) {
|
||||
const uint8_t v = *value;
|
||||
uint8_t * const p = (uint8_t * const)pos;
|
||||
if (v != eeprom_read_byte(p)) {
|
||||
eeprom_write_byte(p, v);
|
||||
delay(2);
|
||||
if (eeprom_read_byte(p) != v) {
|
||||
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
crc16(crc, &v, 1);
|
||||
pos++;
|
||||
value++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
|
||||
while (size--) {
|
||||
uint8_t c = eeprom_read_byte((uint8_t*)pos);
|
||||
if (writing) *value = c;
|
||||
crc16(crc, &c, 1);
|
||||
pos++;
|
||||
value++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // EEPROM_SETTINGS && !(QSPI_EEPROM || FLASH_EEPROM_EMULATION)
|
||||
#endif // __SAMD51__
|
||||
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __SAMD51__
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
||||
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
#define NVMCTRL_CMD(c) do{ \
|
||||
SYNC(!NVMCTRL->STATUS.bit.READY); \
|
||||
NVMCTRL->INTFLAG.bit.DONE = true; \
|
||||
NVMCTRL->CTRLB.reg = c | NVMCTRL_CTRLB_CMDEX_KEY; \
|
||||
SYNC(NVMCTRL->INTFLAG.bit.DONE); \
|
||||
}while(0)
|
||||
#define NVMCTRL_FLUSH() do{ \
|
||||
if (NVMCTRL->SEESTAT.bit.LOAD) \
|
||||
NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_SEEFLUSH); \
|
||||
}while(0)
|
||||
|
||||
size_t PersistentStore::capacity() {
|
||||
const uint8_t psz = NVMCTRL->SEESTAT.bit.PSZ,
|
||||
sblk = NVMCTRL->SEESTAT.bit.SBLK;
|
||||
|
||||
return (!psz && !sblk) ? 0
|
||||
: (psz <= 2) ? (0x200 << psz)
|
||||
: (sblk == 1 || psz == 3) ? 4096
|
||||
: (sblk == 2 || psz == 4) ? 8192
|
||||
: (sblk <= 4 || psz == 5) ? 16384
|
||||
: (sblk >= 9 && psz == 7) ? 65536
|
||||
: 32768;
|
||||
}
|
||||
|
||||
bool PersistentStore::access_start() {
|
||||
NVMCTRL->SEECFG.reg = NVMCTRL_SEECFG_WMODE_BUFFERED; // Buffered mode and segment reallocation active
|
||||
if (NVMCTRL->SEESTAT.bit.RLOCK)
|
||||
NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_USEE); // Unlock E2P data write access
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistentStore::access_finish() {
|
||||
NVMCTRL_FLUSH();
|
||||
if (!NVMCTRL->SEESTAT.bit.LOCK)
|
||||
NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_LSEE); // Lock E2P data write access
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
|
||||
while (size--) {
|
||||
const uint8_t v = *value;
|
||||
SYNC(NVMCTRL->SEESTAT.bit.BUSY);
|
||||
if (NVMCTRL->INTFLAG.bit.SEESFULL)
|
||||
NVMCTRL_FLUSH(); // Next write will trigger a sector reallocation. I need to flush 'pagebuffer'
|
||||
((volatile uint8_t *)SEEPROM_ADDR)[pos] = v;
|
||||
SYNC(!NVMCTRL->INTFLAG.bit.SEEWRC);
|
||||
crc16(crc, &v, 1);
|
||||
pos++;
|
||||
value++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
|
||||
while (size--) {
|
||||
SYNC(NVMCTRL->SEESTAT.bit.BUSY);
|
||||
uint8_t c = ((volatile uint8_t *)SEEPROM_ADDR)[pos];
|
||||
if (writing) *value = c;
|
||||
crc16(crc, &c, 1);
|
||||
pos++;
|
||||
value++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // FLASH_EEPROM_EMULATION
|
||||
#endif // __SAMD51__
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef __SAMD51__
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(QSPI_EEPROM)
|
||||
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
#include "QSPIFlash.h"
|
||||
|
||||
static bool initialized;
|
||||
|
||||
size_t PersistentStore::capacity() { return qspi.size(); }
|
||||
|
||||
bool PersistentStore::access_start() {
|
||||
if (!initialized) {
|
||||
qspi.begin();
|
||||
initialized = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistentStore::access_finish() {
|
||||
qspi.flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
|
||||
while (size--) {
|
||||
const uint8_t v = *value;
|
||||
qspi.writeByte(pos, v);
|
||||
crc16(crc, &v, 1);
|
||||
pos++;
|
||||
value++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
|
||||
while (size--) {
|
||||
uint8_t c = qspi.readByte(pos);
|
||||
if (writing) *value = c;
|
||||
crc16(crc, &c, 1);
|
||||
pos++;
|
||||
value++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // QSPI_EEPROM
|
||||
#endif // __SAMD51__
|
||||
@@ -100,9 +100,9 @@
|
||||
PORT->Group[port].DIRCLR.reg = MASK(pin); \
|
||||
}while(0)
|
||||
// Set pin as PWM (push pull)
|
||||
#define SET_PWM(IO) SET_OUTPUT(IO)
|
||||
#define SET_PWM SET_OUTPUT
|
||||
// Set pin as PWM (open drain)
|
||||
#define SET_PWM_OD(IO) SET_OUTPUT_OD(IO)
|
||||
#define SET_PWM_OD SET_OUTPUT_OD
|
||||
|
||||
// check if pin is an output
|
||||
#define IS_OUTPUT(IO) ((PORT->Group[(EPortType)GET_SAMD_PORT(IO)].DIR.reg & MASK(GET_SAMD_PIN(IO))) \
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if USE_EMULATED_EEPROM
|
||||
#undef SRAM_EEPROM_EMULATION
|
||||
#undef SDCARD_EEPROM_EMULATION
|
||||
#if USE_FALLBACK_EEPROM && NONE(SDCARD_EEPROM_EMULATION, SRAM_EEPROM_EMULATION)
|
||||
#define FLASH_EEPROM_EMULATION
|
||||
#endif
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __SAMD51__
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
|
||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
||||
#define NVMCTRL_CMD(c) do{ \
|
||||
SYNC(!NVMCTRL->STATUS.bit.READY); \
|
||||
NVMCTRL->INTFLAG.bit.DONE = true; \
|
||||
NVMCTRL->CTRLB.reg = c | NVMCTRL_CTRLB_CMDEX_KEY; \
|
||||
SYNC(NVMCTRL->INTFLAG.bit.DONE); \
|
||||
}while(0)
|
||||
#define NVMCTRL_FLUSH() do{ \
|
||||
if (NVMCTRL->SEESTAT.bit.LOAD) \
|
||||
NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_SEEFLUSH); \
|
||||
}while(0)
|
||||
#endif
|
||||
|
||||
bool PersistentStore::access_start() {
|
||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
||||
NVMCTRL->SEECFG.reg = NVMCTRL_SEECFG_WMODE_BUFFERED; // Buffered mode and segment reallocation active
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistentStore::access_finish() {
|
||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
||||
NVMCTRL_FLUSH();
|
||||
if (!NVMCTRL->SEESTAT.bit.LOCK)
|
||||
NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_LSEE); // Lock E2P data write access
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
|
||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
||||
if (NVMCTRL->SEESTAT.bit.RLOCK)
|
||||
NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_USEE); // Unlock E2P data write access
|
||||
#endif
|
||||
|
||||
while (size--) {
|
||||
const uint8_t v = *value;
|
||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
||||
SYNC(NVMCTRL->SEESTAT.bit.BUSY);
|
||||
if (NVMCTRL->INTFLAG.bit.SEESFULL)
|
||||
NVMCTRL_FLUSH(); // Next write will trigger a sector reallocation. I need to flush 'pagebuffer'
|
||||
((volatile uint8_t *)SEEPROM_ADDR)[pos] = v;
|
||||
SYNC(!NVMCTRL->INTFLAG.bit.SEEWRC);
|
||||
#else
|
||||
uint8_t * const p = (uint8_t * const)pos;
|
||||
if (v != eeprom_read_byte(p)) {
|
||||
eeprom_write_byte(p, v);
|
||||
delay(2);
|
||||
if (eeprom_read_byte(p) != v) {
|
||||
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
crc16(crc, &v, 1);
|
||||
pos++;
|
||||
value++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
|
||||
while (size--) {
|
||||
uint8_t c;
|
||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
||||
SYNC(NVMCTRL->SEESTAT.bit.BUSY);
|
||||
c = ((volatile uint8_t *)SEEPROM_ADDR)[pos];
|
||||
#else
|
||||
c = eeprom_read_byte((uint8_t*)pos);
|
||||
#endif
|
||||
if (writing) *value = c;
|
||||
crc16(crc, &c, 1);
|
||||
pos++;
|
||||
value++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t PersistentStore::capacity() {
|
||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
||||
const uint8_t psz = NVMCTRL->SEESTAT.bit.PSZ,
|
||||
sblk = NVMCTRL->SEESTAT.bit.SBLK;
|
||||
|
||||
if (!psz && !sblk) return 0;
|
||||
else if (psz <= 2) return (0x200 << psz);
|
||||
else if (sblk == 1 || psz == 3) return 4096;
|
||||
else if (sblk == 2 || psz == 4) return 8192;
|
||||
else if (sblk <= 4 || psz == 5) return 16384;
|
||||
else if (sblk >= 9 && psz == 7) return 65536;
|
||||
else return 32768;
|
||||
#else
|
||||
return E2END + 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // EEPROM_SETTINGS
|
||||
|
||||
#endif // __SAMD51__
|
||||
@@ -133,6 +133,6 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRe
|
||||
|
||||
uint16_t HAL_adc_get_result() { return HAL_adc_result; }
|
||||
|
||||
void flashFirmware(int16_t) { NVIC_SystemReset(); }
|
||||
void flashFirmware(const int16_t) { NVIC_SystemReset(); }
|
||||
|
||||
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
|
||||
|
||||
@@ -223,4 +223,4 @@ uint16_t HAL_adc_get_result();
|
||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
|
||||
|
||||
#define PLATFORM_M997_SUPPORT
|
||||
void flashFirmware(int16_t value);
|
||||
void flashFirmware(const int16_t);
|
||||
|
||||
@@ -29,9 +29,7 @@
|
||||
* The latest version of this library can always be found at
|
||||
* http://arduiniana.org.
|
||||
*/
|
||||
|
||||
#ifndef SOFTWARESERIAL_H
|
||||
#define SOFTWARESERIAL_H
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
@@ -64,7 +62,6 @@ class SoftwareSerial : public Stream {
|
||||
uint32_t delta_start = 0;
|
||||
|
||||
// static data
|
||||
static bool initialised;
|
||||
static HardwareTimer timer;
|
||||
static const IRQn_Type timer_interrupt_number;
|
||||
static uint32_t timer_interrupt_priority;
|
||||
@@ -91,7 +88,7 @@ class SoftwareSerial : public Stream {
|
||||
public:
|
||||
// public methods
|
||||
|
||||
SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic = false);
|
||||
SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic=false);
|
||||
virtual ~SoftwareSerial();
|
||||
void begin(long speed);
|
||||
bool listen();
|
||||
@@ -115,5 +112,3 @@ class SoftwareSerial : public Stream {
|
||||
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
#endif // SOFTWARESERIAL_H
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
|
||||
#if BOTH(EEPROM_SETTINGS, FLASH_EEPROM_EMULATION)
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
|
||||
// Only STM32F4 can support wear leveling at this time
|
||||
+6
-6
@@ -24,9 +24,9 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if EITHER(USE_REAL_EEPROM, SRAM_EEPROM_EMULATION)
|
||||
#if EITHER(USE_WIRED_EEPROM, SRAM_EEPROM_EMULATION)
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
bool PersistentStore::access_start() {
|
||||
return true;
|
||||
@@ -41,7 +41,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
|
||||
uint8_t v = *value;
|
||||
|
||||
// Save to either external EEPROM, program flash or Backup SRAM
|
||||
#if USE_REAL_EEPROM
|
||||
#if USE_WIRED_EEPROM
|
||||
// EEPROM has only ~100,000 write cycles,
|
||||
// so only write bytes that have changed!
|
||||
uint8_t * const p = (uint8_t * const)pos;
|
||||
@@ -68,7 +68,7 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t
|
||||
do {
|
||||
// Read from either external EEPROM, program flash or Backup SRAM
|
||||
const uint8_t c = (
|
||||
#if USE_REAL_EEPROM
|
||||
#if USE_WIRED_EEPROM
|
||||
eeprom_read_byte((uint8_t*)pos)
|
||||
#else
|
||||
(*(__IO uint8_t *)(BKPSRAM_BASE + ((uint8_t*)pos)))
|
||||
@@ -85,7 +85,7 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t
|
||||
|
||||
size_t PersistentStore::capacity() {
|
||||
return (
|
||||
#if USE_REAL_EEPROM
|
||||
#if USE_WIRED_EEPROM
|
||||
E2END + 1
|
||||
#else
|
||||
4096 // 4kB
|
||||
@@ -93,5 +93,5 @@ size_t PersistentStore::capacity() {
|
||||
);
|
||||
}
|
||||
|
||||
#endif // USE_REAL_EEPROM || SRAM_EEPROM_EMULATION
|
||||
#endif // USE_WIRED_EEPROM || SRAM_EEPROM_EMULATION
|
||||
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
|
||||
+1
-1
@@ -30,7 +30,7 @@
|
||||
|
||||
#if ENABLED(SDCARD_EEPROM_EMULATION)
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
#ifndef E2END
|
||||
#define E2END 0xFFF // 4KB
|
||||
@@ -22,6 +22,6 @@
|
||||
#pragma once
|
||||
|
||||
// If no real EEPROM, Flash emulation, or SRAM emulation is available fall back to SD emulation
|
||||
#if ENABLED(EEPROM_SETTINGS) && NONE(USE_REAL_EEPROM, FLASH_EEPROM_EMULATION, SRAM_EEPROM_EMULATION)
|
||||
#if ENABLED(EEPROM_SETTINGS) && NONE(USE_WIRED_EEPROM, FLASH_EEPROM_EMULATION, SRAM_EEPROM_EMULATION)
|
||||
#define SDCARD_EEPROM_EMULATION
|
||||
#endif
|
||||
|
||||
@@ -388,6 +388,6 @@ void analogWrite(pin_t pin, int pwm_val8) {
|
||||
analogWrite(uint8_t(pin), pwm_val8);
|
||||
}
|
||||
|
||||
void flashFirmware(int16_t value) { nvic_sys_reset(); }
|
||||
void flashFirmware(const int16_t) { nvic_sys_reset(); }
|
||||
|
||||
#endif // __STM32F1__
|
||||
|
||||
@@ -160,6 +160,7 @@ void HAL_idletask();
|
||||
|
||||
#ifndef digitalPinHasPWM
|
||||
#define digitalPinHasPWM(P) (PIN_MAP[P].timer_device != nullptr)
|
||||
#define NO_COMPILE_TIME_PWM
|
||||
#endif
|
||||
|
||||
#define CRITICAL_SECTION_START() uint32_t primask = __get_primask(); (void)__iCliRetVal()
|
||||
@@ -287,4 +288,4 @@ void analogWrite(pin_t pin, int pwm_val8); // PWM only! mul by 257 in maple!?
|
||||
#define JTAGSWD_DISABLE() afio_cfg_debug_ports(AFIO_DEBUG_NONE)
|
||||
|
||||
#define PLATFORM_M997_SUPPORT
|
||||
void flashFirmware(int16_t value);
|
||||
void flashFirmware(const int16_t);
|
||||
|
||||
+3
-3
@@ -22,9 +22,9 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if USE_REAL_EEPROM
|
||||
#if USE_WIRED_EEPROM
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
bool PersistentStore::access_start() {
|
||||
#if ENABLED(SPI_EEPROM)
|
||||
@@ -73,5 +73,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t
|
||||
|
||||
size_t PersistentStore::capacity() { return E2END + 1; }
|
||||
|
||||
#endif // USE_REAL_EEPROM
|
||||
#endif // USE_WIRED_EEPROM
|
||||
#endif // __STM32F1__
|
||||
+3
-4
@@ -31,10 +31,9 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
// This is for EEPROM emulation in flash
|
||||
#if BOTH(EEPROM_SETTINGS, FLASH_EEPROM_EMULATION)
|
||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
#include <flash_stm32.h>
|
||||
#include <EEPROM.h>
|
||||
@@ -108,5 +107,5 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uin
|
||||
|
||||
size_t PersistentStore::capacity() { return EEPROM_SIZE; }
|
||||
|
||||
#endif // EEPROM_SETTINGS && EEPROM FLASH
|
||||
#endif // FLASH_EEPROM_EMULATION
|
||||
#endif // __STM32F1__
|
||||
+1
-2
@@ -31,7 +31,7 @@
|
||||
|
||||
#if ENABLED(SDCARD_EEPROM_EMULATION)
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
#ifndef E2END
|
||||
#define E2END 0xFFF // 4KB
|
||||
@@ -101,5 +101,4 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uin
|
||||
size_t PersistentStore::capacity() { return HAL_EEPROM_SIZE; }
|
||||
|
||||
#endif // SDCARD_EEPROM_EMULATION
|
||||
|
||||
#endif // __STM32F1__
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
bool PersistentStore::access_start() { return true; }
|
||||
bool PersistentStore::access_finish() { return true; }
|
||||
@@ -22,7 +22,7 @@
|
||||
#pragma once
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS) && defined(STM32F7)
|
||||
#undef USE_REAL_EEPROM
|
||||
#undef USE_WIRED_EEPROM
|
||||
#undef SRAM_EEPROM_EMULATION
|
||||
#undef SDCARD_EEPROM_EMULATION
|
||||
#define FLASH_EEPROM_EMULATION
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
bool PersistentStore::access_start() { return true; }
|
||||
bool PersistentStore::access_finish() { return true; }
|
||||
@@ -76,8 +76,9 @@
|
||||
|
||||
#define SET_INPUT(IO) _SET_INPUT(IO)
|
||||
#define SET_INPUT_PULLUP(IO) _SET_INPUT_PULLUP(IO)
|
||||
#define SET_INPUT_PULLDOWN SET_INPUT
|
||||
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
||||
#define SET_PWM(IO) SET_OUTPUT(IO)
|
||||
#define SET_PWM SET_OUTPUT
|
||||
|
||||
#define IS_INPUT(IO) _IS_INPUT(IO)
|
||||
#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
|
||||
|
||||
@@ -22,6 +22,6 @@
|
||||
#pragma once
|
||||
|
||||
// If no real EEPROM, Flash emulation, or SRAM emulation is available fall back to SD emulation
|
||||
#if ENABLED(EEPROM_SETTINGS) && NONE(USE_REAL_EEPROM, FLASH_EEPROM_EMULATION, SRAM_EEPROM_EMULATION)
|
||||
#if ENABLED(EEPROM_SETTINGS) && NONE(USE_WIRED_EEPROM, FLASH_EEPROM_EMULATION, SRAM_EEPROM_EMULATION)
|
||||
#define SDCARD_EEPROM_EMULATION
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
|
||||
#include "../shared/persistent_store_api.h"
|
||||
#include "../shared/eeprom_api.h"
|
||||
#include <avr/eeprom.h>
|
||||
|
||||
bool PersistentStore::access_start() { return true; }
|
||||
@@ -76,8 +76,9 @@
|
||||
|
||||
#define SET_INPUT(IO) _SET_INPUT(IO)
|
||||
#define SET_INPUT_PULLUP(IO) _SET_INPUT_PULLUP(IO)
|
||||
#define SET_INPUT_PULLDOWN SET_INPUT
|
||||
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
||||
#define SET_PWM(IO) SET_OUTPUT(IO)
|
||||
#define SET_PWM SET_OUTPUT
|
||||
|
||||
#define IS_INPUT(IO) _IS_INPUT(IO)
|
||||
#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
|
||||
#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE)
|
||||
|
||||
#include "persistent_store_api.h"
|
||||
#include "eeprom_api.h"
|
||||
PersistentStore persistentStore;
|
||||
|
||||
#endif
|
||||
+109
-102
@@ -210,11 +210,24 @@ bool wait_for_heatup = true;
|
||||
// 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;
|
||||
|
||||
void wait_for_user_response(millis_t ms/*=0*/, const bool no_sleep/*=false*/) {
|
||||
#if DISABLED(ADVANCED_PAUSE_FEATURE)
|
||||
UNUSED(no_sleep);
|
||||
#endif
|
||||
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
||||
wait_for_user = true;
|
||||
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;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Inactivity shutdown
|
||||
millis_t max_inactive_time, // = 0
|
||||
stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL;
|
||||
stepper_inactive_time = SEC_TO_MS(DEFAULT_STEPPER_DEACTIVE_TIME);
|
||||
|
||||
#if PIN_EXISTS(CHDK)
|
||||
extern millis_t chdk_timeout;
|
||||
@@ -407,7 +420,11 @@ void startOrResumeJob() {
|
||||
#if DISABLED(SD_ABORT_NO_COOLDOWN)
|
||||
thermalManager.disable_all_heaters();
|
||||
#endif
|
||||
thermalManager.zero_fan_speeds();
|
||||
#if !HAS_CUTTER
|
||||
thermalManager.zero_fan_speeds();
|
||||
#else
|
||||
cutter.kill(); // Full cutter shutdown including ISR control
|
||||
#endif
|
||||
wait_for_heatup = false;
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
recovery.purge();
|
||||
@@ -418,59 +435,14 @@ void startOrResumeJob() {
|
||||
}
|
||||
|
||||
inline void finishSDPrinting() {
|
||||
|
||||
bool did_state = true;
|
||||
switch (card.sdprinting_done_state) {
|
||||
|
||||
case 1:
|
||||
did_state = print_job_timer.duration() < 60 || queue.enqueue_one_P(PSTR("M31"));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
did_state = queue.enqueue_one_P(PSTR("M77"));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
#if ENABLED(LCD_SET_PROGRESS_MANUALLY)
|
||||
ui.set_progress_done();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 4: // Display "Click to Continue..."
|
||||
#if HAS_RESUME_CONTINUE // 30 min timeout with LCD, 1 min without
|
||||
did_state = queue.enqueue_one_P(
|
||||
print_job_timer.duration() < 60 ? PSTR("M0Q1P1") : PSTR("M0Q1S" TERN(HAS_LCD_MENU, "1800", "60"))
|
||||
);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 5:
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
recovery.purge();
|
||||
#endif
|
||||
|
||||
#if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND)
|
||||
planner.finish_and_disable();
|
||||
#endif
|
||||
|
||||
#if ENABLED(SD_REPRINT_LAST_SELECTED_FILE)
|
||||
ui.reselect_last_file();
|
||||
#endif
|
||||
|
||||
SERIAL_ECHOLNPGM(STR_FILE_PRINTED);
|
||||
|
||||
default:
|
||||
did_state = false;
|
||||
card.sdprinting_done_state = 0;
|
||||
}
|
||||
if (did_state) ++card.sdprinting_done_state;
|
||||
if (queue.enqueue_one_P(PSTR("M1001")))
|
||||
marlin_state = MF_RUNNING;
|
||||
}
|
||||
|
||||
#endif // SDSUPPORT
|
||||
|
||||
/**
|
||||
* Minimal management of Marlin's core activities:
|
||||
* - Check for Filament Runout
|
||||
* - Keep the command buffer full
|
||||
* - Check for maximum inactive time between commands
|
||||
* - Check for maximum inactive time between stepper commands
|
||||
@@ -481,13 +453,8 @@ 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 ignore_stepper_queue=false) {
|
||||
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
runout.run();
|
||||
#endif
|
||||
|
||||
if (queue.length < BUFSIZE) queue.get_available_commands();
|
||||
|
||||
const millis_t ms = millis();
|
||||
@@ -576,7 +543,7 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
|
||||
|
||||
#if ENABLED(EXTRUDER_RUNOUT_PREVENT)
|
||||
if (thermalManager.degHotend(active_extruder) > EXTRUDER_RUNOUT_MINTEMP
|
||||
&& ELAPSED(ms, gcode.previous_move_ms + (EXTRUDER_RUNOUT_SECONDS) * 1000UL)
|
||||
&& ELAPSED(ms, gcode.previous_move_ms + SEC_TO_MS(EXTRUDER_RUNOUT_SECONDS))
|
||||
&& !planner.has_blocks_queued()
|
||||
) {
|
||||
#if ENABLED(SWITCHING_EXTRUDER)
|
||||
@@ -671,54 +638,95 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard idle routine keeps the machine alive
|
||||
* Standard idle routine keeps the machine alive:
|
||||
* - Core Marlin activities
|
||||
* - Manage heaters (and Watchdog)
|
||||
* - Max7219 heartbeat, animation, etc.
|
||||
*
|
||||
* Only after setup() is complete:
|
||||
* - Handle filament runout sensors
|
||||
* - Run HAL idle tasks
|
||||
* - Handle Power-Loss Recovery
|
||||
* - Run StallGuard endstop checks
|
||||
* - Handle SD Card insert / remove
|
||||
* - Handle USB Flash Drive insert / remove
|
||||
* - Announce Host Keepalive state (if any)
|
||||
* - Update the Print Job Timer state
|
||||
* - Update the Beeper queue
|
||||
* - Read Buttons and Update the LCD
|
||||
* - Run i2c Position Encoders
|
||||
* - Auto-report Temperatures / SD Status
|
||||
* - Update the Prusa MMU2
|
||||
* - Handle Joystick jogging
|
||||
*/
|
||||
void idle(
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
bool no_stepper_sleep/*=false*/
|
||||
#endif
|
||||
) {
|
||||
#if ENABLED(POWER_LOSS_RECOVERY) && PIN_EXISTS(POWER_LOSS)
|
||||
recovery.outage();
|
||||
#endif
|
||||
void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
|
||||
|
||||
#if ENABLED(SPI_ENDSTOPS)
|
||||
if (endstops.tmc_spi_homing.any
|
||||
#if ENABLED(IMPROVE_HOMING_RELIABILITY)
|
||||
&& ELAPSED(millis(), sg_guard_period)
|
||||
#endif
|
||||
) {
|
||||
for (uint8_t i = 4; i--;) // Read SGT 4 times per idle loop
|
||||
if (endstops.tmc_spi_homing_check()) break;
|
||||
}
|
||||
#endif
|
||||
// Core Marlin activities
|
||||
manage_inactivity(TERN_(ADVANCED_PAUSE_FEATURE, no_stepper_sleep));
|
||||
|
||||
// Manage Heaters (and Watchdog)
|
||||
thermalManager.manage_heater();
|
||||
|
||||
// Max7219 heartbeat, animation, etc
|
||||
#if ENABLED(MAX7219_DEBUG)
|
||||
max7219.idle_tasks();
|
||||
#endif
|
||||
|
||||
ui.update();
|
||||
// Return if setup() isn't completed
|
||||
if (marlin_state == MF_INITIALIZING) return;
|
||||
|
||||
// Handle filament runout sensors
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
runout.run();
|
||||
#endif
|
||||
|
||||
// Run HAL idle tasks
|
||||
#ifdef HAL_IDLETASK
|
||||
HAL_idletask();
|
||||
#endif
|
||||
|
||||
// Handle Power-Loss Recovery
|
||||
#if ENABLED(POWER_LOSS_RECOVERY) && PIN_EXISTS(POWER_LOSS)
|
||||
recovery.outage();
|
||||
#endif
|
||||
|
||||
// Run StallGuard endstop checks
|
||||
#if ENABLED(SPI_ENDSTOPS)
|
||||
if (endstops.tmc_spi_homing.any
|
||||
&& TERN1(IMPROVE_HOMING_RELIABILITY, ELAPSED(millis(), sg_guard_period))
|
||||
) LOOP_L_N(i, 4) // Read SGT 4 times per idle loop
|
||||
if (endstops.tmc_spi_homing_check()) break;
|
||||
#endif
|
||||
|
||||
// Handle SD Card insert / remove
|
||||
#if ENABLED(SDSUPPORT)
|
||||
card.manage_media();
|
||||
#endif
|
||||
|
||||
// Handle USB Flash Drive insert / remove
|
||||
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
|
||||
Sd2Card::idle();
|
||||
#endif
|
||||
|
||||
// Announce Host Keepalive state (if any)
|
||||
#if ENABLED(HOST_KEEPALIVE_FEATURE)
|
||||
gcode.host_keepalive();
|
||||
#endif
|
||||
|
||||
manage_inactivity(
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
no_stepper_sleep
|
||||
#endif
|
||||
);
|
||||
|
||||
thermalManager.manage_heater();
|
||||
|
||||
// Update the Print Job Timer state
|
||||
#if ENABLED(PRINTCOUNTER)
|
||||
print_job_timer.tick();
|
||||
#endif
|
||||
|
||||
// Update the Beeper queue
|
||||
#if USE_BEEPER
|
||||
buzzer.tick();
|
||||
#endif
|
||||
|
||||
// Read Buttons and Update the LCD
|
||||
ui.update();
|
||||
|
||||
// Run i2c Position Encoders
|
||||
#if ENABLED(I2C_POSITION_ENCODERS)
|
||||
static millis_t i2cpem_next_update_ms;
|
||||
if (planner.has_blocks_queued()) {
|
||||
@@ -730,10 +738,7 @@ void idle(
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAL_IDLETASK
|
||||
HAL_idletask();
|
||||
#endif
|
||||
|
||||
// Auto-report Temperatures / SD Status
|
||||
#if HAS_AUTO_REPORTING
|
||||
if (!gcode.autoreport_paused) {
|
||||
#if ENABLED(AUTO_REPORT_TEMPERATURES)
|
||||
@@ -745,14 +750,12 @@ void idle(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
|
||||
Sd2Card::idle();
|
||||
#endif
|
||||
|
||||
// Update the Prusa MMU2
|
||||
#if ENABLED(PRUSA_MMU2)
|
||||
mmu2.mmu_loop();
|
||||
#endif
|
||||
|
||||
// Handle Joystick jogging
|
||||
#if ENABLED(POLL_JOG)
|
||||
joystick.inject_jog_moves();
|
||||
#endif
|
||||
@@ -765,6 +768,10 @@ void idle(
|
||||
void kill(PGM_P const lcd_error/*=nullptr*/, PGM_P const lcd_component/*=nullptr*/, const bool steppers_off/*=false*/) {
|
||||
thermalManager.disable_all_heaters();
|
||||
|
||||
#if HAS_CUTTER
|
||||
cutter.kill(); // Full cutter shutdown including ISR control
|
||||
#endif
|
||||
|
||||
SERIAL_ERROR_MSG(STR_ERR_KILLED);
|
||||
|
||||
#if HAS_DISPLAY
|
||||
@@ -794,6 +801,10 @@ void minkill(const bool steppers_off/*=false*/) {
|
||||
// Reiterate heaters off
|
||||
thermalManager.disable_all_heaters();
|
||||
|
||||
#if HAS_CUTTER
|
||||
cutter.kill(); // Reiterate cutter shutdown
|
||||
#endif
|
||||
|
||||
// Power off all steppers (for M112) or just the E steppers
|
||||
steppers_off ? disable_all_steppers() : disable_e_steppers();
|
||||
|
||||
@@ -813,14 +824,14 @@ void minkill(const bool steppers_off/*=false*/) {
|
||||
// Wait for kill to be pressed
|
||||
while (READ(KILL_PIN)) watchdog_refresh();
|
||||
|
||||
void (*resetFunc)() = 0; // Declare resetFunc() at address 0
|
||||
void (*resetFunc)() = 0; // Declare resetFunc() at address 0
|
||||
resetFunc(); // Jump to address 0
|
||||
|
||||
#else // !HAS_KILL
|
||||
#else
|
||||
|
||||
for (;;) watchdog_refresh(); // Wait for reset
|
||||
for (;;) watchdog_refresh(); // Wait for reset
|
||||
|
||||
#endif // !HAS_KILL
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -995,8 +1006,8 @@ void setup() {
|
||||
SETUP_RUN(ui.show_bootscreen());
|
||||
#endif
|
||||
|
||||
#if ENABLED(SDSUPPORT) && defined(SDCARD_CONNECTION) && !SD_CONNECTION_IS(LCD)
|
||||
SETUP_RUN(card.mount()); // Mount onboard / custom SD card before settings.first_load
|
||||
#if BOTH(SDSUPPORT, SDCARD_EEPROM_EMULATION)
|
||||
SETUP_RUN(card.mount()); // Mount media with settings before first_load
|
||||
#endif
|
||||
|
||||
SETUP_RUN(settings.first_load()); // Load data from EEPROM if available (or use defaults)
|
||||
@@ -1163,10 +1174,6 @@ void setup() {
|
||||
queue.inject_P(PSTR(STARTUP_COMMANDS));
|
||||
#endif
|
||||
|
||||
#if ENABLED(INIT_SDCARD_ON_BOOT) && !HAS_SPI_LCD
|
||||
SETUP_RUN(card.beginautostart());
|
||||
#endif
|
||||
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
SETUP_RUN(host_action_prompt_end());
|
||||
#endif
|
||||
@@ -1208,7 +1215,7 @@ void loop() {
|
||||
#if ENABLED(SDSUPPORT)
|
||||
card.checkautostart();
|
||||
if (card.flag.abort_sd_printing) abortSDPrinting();
|
||||
if (card.sdprinting_done_state) finishSDPrinting();
|
||||
if (marlin_state == MF_SD_COMPLETE) finishSDPrinting();
|
||||
#endif
|
||||
|
||||
queue.advance();
|
||||
|
||||
+5
-13
@@ -38,19 +38,9 @@
|
||||
|
||||
void stop();
|
||||
|
||||
void idle(
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
bool no_stepper_sleep=false // Pass true to keep steppers from timing out
|
||||
#endif
|
||||
);
|
||||
|
||||
inline void idle_no_sleep() {
|
||||
idle(
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
true
|
||||
#endif
|
||||
);
|
||||
}
|
||||
// Pass true to keep steppers from timing out
|
||||
void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep=false));
|
||||
inline void idle_no_sleep() { idle(TERN_(ADVANCED_PAUSE_FEATURE, true)); }
|
||||
|
||||
#if ENABLED(EXPERIMENTAL_I2CBUS)
|
||||
#include "feature/twibus.h"
|
||||
@@ -83,6 +73,7 @@ enum MarlinState : uint8_t {
|
||||
MF_PAUSED = _BV(1),
|
||||
MF_WAITING = _BV(2),
|
||||
MF_STOPPED = _BV(3),
|
||||
MF_SD_COMPLETE = _BV(4),
|
||||
MF_KILLED = _BV(7)
|
||||
};
|
||||
|
||||
@@ -98,6 +89,7 @@ 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
|
||||
|
||||
// Inactivity shutdown timer
|
||||
|
||||
@@ -144,6 +144,7 @@
|
||||
#define BOARD_LEAPFROG_XEED2015 1321 // Leapfrog Xeed 2015
|
||||
#define BOARD_PICA_REVB 1322 // PICA Shield (original version)
|
||||
#define BOARD_PICA 1323 // PICA Shield (rev C or later)
|
||||
#define BOARD_INTAMSYS40 1324 // Intamsys 4.0 (Funmat HT)
|
||||
|
||||
//
|
||||
// ATmega1281, ATmega2561
|
||||
@@ -318,7 +319,7 @@
|
||||
#define BOARD_BLACK_STM32F407ZE 4206 // BLACK_STM32F407ZE
|
||||
#define BOARD_STEVAL_3DP001V1 4207 // STEVAL-3DP001V1 3D PRINTER BOARD
|
||||
#define BOARD_BTT_SKR_PRO_V1_1 4208 // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
|
||||
#define BOARD_BTT_BTT002_V1_0 4209 // BigTreeTech BTT002 v1.0 (STM32F407VE)
|
||||
#define BOARD_BTT_BTT002_V1_0 4209 // BigTreeTech BTT002 v1.0 (STM32F407VG)
|
||||
#define BOARD_BTT_GTR_V1_0 4210 // BigTreeTech GTR v1.0 (STM32F407IGT)
|
||||
#define BOARD_LERDGE_K 4211 // Lerdge K (STM32F407ZG)
|
||||
#define BOARD_LERDGE_X 4212 // Lerdge X (STM32F407VE)
|
||||
|
||||
@@ -174,15 +174,6 @@
|
||||
// Defines that can't be evaluated now
|
||||
#define HAS_TMC_SW_SERIAL ANY_AXIS_HAS(SW_SERIAL)
|
||||
|
||||
//
|
||||
// Stretching 'drivers.h' to include LPC/SAMD51 SD options
|
||||
//
|
||||
#define _SDCARD_LCD 1
|
||||
#define _SDCARD_ONBOARD 2
|
||||
#define _SDCARD_CUSTOM_CABLE 3
|
||||
#define _SDCARD_ID(V) _CAT(_SDCARD_, V)
|
||||
#define SD_CONNECTION_IS(V) (_SDCARD_ID(SDCARD_CONNECTION) == _SDCARD_ID(V))
|
||||
|
||||
#if HAS_DRIVER(L6470) || HAS_DRIVER(L6474) || HAS_DRIVER(L6480) || HAS_DRIVER(POWERSTEP01)
|
||||
#define HAS_L64XX 1
|
||||
#endif
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
#define STR_INVALID_POS_SLOT "Invalid slot. Total: "
|
||||
|
||||
#define STR_SD_CANT_OPEN_SUBDIR "Cannot open subdir "
|
||||
#define STR_SD_INIT_FAIL "SD init fail"
|
||||
#define STR_SD_INIT_FAIL "No SD card"
|
||||
#define STR_SD_VOL_INIT_FAIL "volume.init failed"
|
||||
#define STR_SD_OPENROOT_FAIL "openRoot failed"
|
||||
#define STR_SD_CARD_OK "SD card ok"
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(__has_include)
|
||||
#define __has_include(...) 1
|
||||
#endif
|
||||
|
||||
#define ABCE 4
|
||||
#define XYZE 4
|
||||
#define ABC 3
|
||||
@@ -190,6 +194,9 @@
|
||||
#define DISABLED(V...) DO(DIS,&&,V)
|
||||
|
||||
#define TERN(O,A,B) _TERN(_ENA_1(O),B,A) // OPTION converted to '0' or '1'
|
||||
#define TERN0(O,A) _TERN(_ENA_1(O),0,A) // OPTION converted to A or '0'
|
||||
#define TERN1(O,A) _TERN(_ENA_1(O),1,A) // OPTION converted to A or '1'
|
||||
#define TERN_(O,A) _TERN(_ENA_1(O),,A) // OPTION converted to A or '<nul>'
|
||||
#define _TERN(E,V...) __TERN(_CAT(T_,E),V) // Prepend 'T_' to get 'T_0' or 'T_1'
|
||||
#define __TERN(T,V...) ___TERN(_CAT(_NO,T),V) // Prepend '_NO' to get '_NOT_0' or '_NOT_1'
|
||||
#define ___TERN(P,V...) THIRD(P,V) // If first argument has a comma, A. Else B.
|
||||
|
||||
@@ -25,5 +25,9 @@
|
||||
|
||||
typedef uint32_t millis_t;
|
||||
|
||||
#define SEC_TO_MS(N) millis_t((N)*1000UL)
|
||||
#define MIN_TO_MS(N) SEC_TO_MS((N)*60UL)
|
||||
#define MS_TO_SEC(N) millis_t((N)/1000UL)
|
||||
|
||||
#define PENDING(NOW,SOON) ((int32_t)(NOW-(SOON))<0)
|
||||
#define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON))
|
||||
|
||||
@@ -77,3 +77,7 @@ typedef const char Language_Str[];
|
||||
#define GET_TEXT_F(MSG) (const __FlashStringHelper*)GET_TEXT(MSG)
|
||||
|
||||
#define MSG_CONCAT(A,B) pgm_p_pair_t(GET_TEXT(A),GET_TEXT(B))
|
||||
|
||||
#define MSG_1_LINE(A) A "\0" "\0"
|
||||
#define MSG_2_LINE(A,B) A "\0" B "\0"
|
||||
#define MSG_3_LINE(A,B,C) A "\0" B "\0" C
|
||||
|
||||
@@ -113,7 +113,7 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const
|
||||
error_correction = 0; // Don't take up any backlash in this segment, as it would subtract steps
|
||||
}
|
||||
#endif
|
||||
// Making a correction reduces the residual error and modifies delta_mm
|
||||
// Making a correction reduces the residual error and adds block steps
|
||||
if (error_correction) {
|
||||
block->steps[axis] += ABS(error_correction);
|
||||
residual_error[axis] -= error_correction;
|
||||
|
||||
@@ -49,14 +49,13 @@
|
||||
void unified_bed_leveling::report_current_mesh() {
|
||||
if (!leveling_is_valid()) return;
|
||||
SERIAL_ECHO_MSG(" G29 I99");
|
||||
LOOP_L_N(x, GRID_MAX_POINTS_X)
|
||||
for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++)
|
||||
if (!isnan(z_values[x][y])) {
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOPAIR(" M421 I", int(x), " J", int(y));
|
||||
SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z_values[x][y], 4);
|
||||
serial_delay(75); // Prevent Printrun from exploding
|
||||
}
|
||||
GRID_LOOP(x, y)
|
||||
if (!isnan(z_values[x][y])) {
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOPAIR(" M421 I", int(x), " J", int(y));
|
||||
SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z_values[x][y], 4);
|
||||
serial_delay(75); // Prevent Printrun from exploding
|
||||
}
|
||||
}
|
||||
|
||||
void unified_bed_leveling::report_state() {
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "../bedlevel.h"
|
||||
|
||||
#include "../../../MarlinCore.h"
|
||||
#include "../../../HAL/shared/persistent_store_api.h"
|
||||
#include "../../../HAL/shared/eeprom_api.h"
|
||||
#include "../../../libs/hex_print_routines.h"
|
||||
#include "../../../module/configuration_store.h"
|
||||
#include "../../../lcd/ultralcd.h"
|
||||
@@ -776,12 +776,16 @@
|
||||
: find_closest_mesh_point_of_type(INVALID, near, true);
|
||||
|
||||
if (best.pos.x >= 0) { // mesh point found and is reachable by probe
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onMeshUpdate(best.pos, ExtUI::PROBE_START);
|
||||
#endif
|
||||
const float measured_z = probe.probe_at_point(
|
||||
best.meshpos(),
|
||||
stow_probe ? PROBE_PT_STOW : PROBE_PT_RAISE, g29_verbose_level
|
||||
);
|
||||
z_values[best.pos.x][best.pos.y] = measured_z;
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onMeshUpdate(best.pos, ExtUI::PROBE_FINISH);
|
||||
ExtUI::onMeshUpdate(best.pos, measured_z);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ void ControllerFan::update() {
|
||||
// - If AutoMode is on and steppers have been enabled for CONTROLLERFAN_IDLE_TIME seconds.
|
||||
// - If System is on idle and idle fan speed settings is activated.
|
||||
set_fan_speed(
|
||||
settings.auto_mode && lastMotorOn && PENDING(ms, lastMotorOn + settings.duration * 1000UL)
|
||||
settings.auto_mode && lastMotorOn && PENDING(ms, lastMotorOn + SEC_TO_MS(settings.duration))
|
||||
? settings.active_speed : settings.idle_speed
|
||||
);
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class ControllerFan {
|
||||
#if ENABLED(CONTROLLER_FAN_EDITABLE)
|
||||
static controllerFan_settings_t settings;
|
||||
#else
|
||||
static const controllerFan_settings_t &settings = controllerFan_defaults;
|
||||
static const controllerFan_settings_t constexpr &settings = controllerFan_defaults;
|
||||
#endif
|
||||
static inline bool state() { return speed > 0; }
|
||||
static inline void init() { reset(); }
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
#if BOTH(DIGIPOT_I2C, DIGIPOT_MCP4018)
|
||||
|
||||
#include "Stream.h"
|
||||
#include "utility/twi.h"
|
||||
#include <Stream.h>
|
||||
#include <utility/twi.h>
|
||||
#include <SlowSoftI2CMaster.h> //https://github.com/stawel/SlowSoftI2CMaster
|
||||
|
||||
// Settings for the I2C based DIGIPOT (MCP4018) based on WT150
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#if ENABLED(DIGIPOT_I2C) && DISABLED(DIGIPOT_MCP4018)
|
||||
|
||||
#include "Stream.h"
|
||||
#include <Stream.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#if MB(MKS_SBASE)
|
||||
|
||||
@@ -121,7 +121,7 @@ uint8_t Max7219::suspended; // = 0;
|
||||
#define CRITICAL_SECTION_START() NOOP
|
||||
#define CRITICAL_SECTION_END() NOOP
|
||||
#else
|
||||
#define SIG_DELAY() DELAY_NS(188) // Delay for 0.1875µs (16MHz AVR) or 0.15µs (20MHz AVR)
|
||||
#define SIG_DELAY() DELAY_NS(250)
|
||||
#endif
|
||||
|
||||
void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/*=-1*/) {
|
||||
|
||||
@@ -707,14 +707,13 @@ void MMU2::filament_runout() {
|
||||
if (recover) {
|
||||
LCD_MESSAGEPGM(MSG_MMU2_EJECT_RECOVER);
|
||||
BUZZ(200, 404);
|
||||
wait_for_user = true;
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), CONTINUE_STR);
|
||||
#endif
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired_P(PSTR("MMU2 Eject Recover"));
|
||||
#endif
|
||||
while (wait_for_user) idle();
|
||||
wait_for_user_response();
|
||||
BUZZ(200, 404);
|
||||
BUZZ(200, 404);
|
||||
|
||||
|
||||
@@ -134,15 +134,6 @@ static bool ensure_safe_temperature(const PauseMode mode=PAUSE_MODE_SAME) {
|
||||
return thermalManager.wait_for_hotend(active_extruder);
|
||||
}
|
||||
|
||||
void do_pause_e_move(const float &length, const feedRate_t &fr_mm_s) {
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
runout.reset();
|
||||
#endif
|
||||
current_position.e += length / planner.e_factor[active_extruder];
|
||||
line_to_current_position(fr_mm_s);
|
||||
planner.synchronize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load filament into the hotend
|
||||
*
|
||||
@@ -184,7 +175,6 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
|
||||
#endif
|
||||
|
||||
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
||||
wait_for_user = true; // LCD click or M108 will clear this
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
const char tool = '0'
|
||||
#if NUM_RUNOUT_SENSORS > 1
|
||||
@@ -218,7 +208,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
|
||||
#endif
|
||||
|
||||
// Slow Load filament
|
||||
if (slow_load_length) do_pause_e_move(slow_load_length, FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE);
|
||||
if (slow_load_length) unscaled_e_move(slow_load_length, FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE);
|
||||
|
||||
// Fast Load Filament
|
||||
if (fast_load_length) {
|
||||
@@ -227,7 +217,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
|
||||
planner.settings.retract_acceleration = FILAMENT_CHANGE_FAST_LOAD_ACCEL;
|
||||
#endif
|
||||
|
||||
do_pause_e_move(fast_load_length, FILAMENT_CHANGE_FAST_LOAD_FEEDRATE);
|
||||
unscaled_e_move(fast_load_length, FILAMENT_CHANGE_FAST_LOAD_FEEDRATE);
|
||||
|
||||
#if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0
|
||||
planner.settings.retract_acceleration = saved_acceleration;
|
||||
@@ -246,15 +236,15 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
|
||||
if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_PURGE);
|
||||
#endif
|
||||
|
||||
wait_for_user = true;
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purging..."), CONTINUE_STR);
|
||||
#endif
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired_P(PSTR("Filament Purging..."));
|
||||
#endif
|
||||
wait_for_user = true; // A click or M108 breaks the purge_length loop
|
||||
for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count)
|
||||
do_pause_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE);
|
||||
unscaled_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE);
|
||||
wait_for_user = false;
|
||||
|
||||
#else
|
||||
@@ -267,7 +257,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
|
||||
#endif
|
||||
|
||||
// Extrude filament to get into hotend
|
||||
do_pause_e_move(purge_length, ADVANCED_PAUSE_PURGE_FEEDRATE);
|
||||
unscaled_e_move(purge_length, ADVANCED_PAUSE_PURGE_FEEDRATE);
|
||||
}
|
||||
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
@@ -332,13 +322,13 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/,
|
||||
#endif
|
||||
|
||||
// Retract filament
|
||||
do_pause_e_move(-(FILAMENT_UNLOAD_PURGE_RETRACT) * mix_multiplier, (PAUSE_PARK_RETRACT_FEEDRATE) * mix_multiplier);
|
||||
unscaled_e_move(-(FILAMENT_UNLOAD_PURGE_RETRACT) * mix_multiplier, (PAUSE_PARK_RETRACT_FEEDRATE) * mix_multiplier);
|
||||
|
||||
// Wait for filament to cool
|
||||
safe_delay(FILAMENT_UNLOAD_PURGE_DELAY);
|
||||
|
||||
// Quickly purge
|
||||
do_pause_e_move((FILAMENT_UNLOAD_PURGE_RETRACT + FILAMENT_UNLOAD_PURGE_LENGTH) * mix_multiplier,
|
||||
unscaled_e_move((FILAMENT_UNLOAD_PURGE_RETRACT + FILAMENT_UNLOAD_PURGE_LENGTH) * mix_multiplier,
|
||||
(FILAMENT_UNLOAD_PURGE_FEEDRATE) * mix_multiplier);
|
||||
|
||||
// Unload filament
|
||||
@@ -347,7 +337,7 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/,
|
||||
planner.settings.retract_acceleration = FILAMENT_CHANGE_UNLOAD_ACCEL;
|
||||
#endif
|
||||
|
||||
do_pause_e_move(unload_length * mix_multiplier, (FILAMENT_CHANGE_UNLOAD_FEEDRATE) * mix_multiplier);
|
||||
unscaled_e_move(unload_length * mix_multiplier, (FILAMENT_CHANGE_UNLOAD_FEEDRATE) * mix_multiplier);
|
||||
|
||||
#if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0
|
||||
planner.settings.retract_acceleration = saved_acceleration;
|
||||
@@ -437,7 +427,7 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float
|
||||
|
||||
// Initial retract before move to filament change position
|
||||
if (retract && thermalManager.hotEnoughToExtrude(active_extruder))
|
||||
do_pause_e_move(retract, PAUSE_PARK_RETRACT_FEEDRATE);
|
||||
unscaled_e_move(retract, PAUSE_PARK_RETRACT_FEEDRATE);
|
||||
|
||||
// Park the nozzle by moving up by z_lift and then moving to (x_pos, y_pos)
|
||||
if (!axes_need_homing())
|
||||
@@ -495,7 +485,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
#endif
|
||||
|
||||
// Start the heater idle timers
|
||||
const millis_t nozzle_timeout = (millis_t)(PAUSE_PARK_NOZZLE_TIMEOUT) * 1000UL;
|
||||
const millis_t nozzle_timeout = SEC_TO_MS(PAUSE_PARK_NOZZLE_TIMEOUT);
|
||||
|
||||
HOTEND_LOOP() thermalManager.hotend_idle[e].start(nozzle_timeout);
|
||||
|
||||
@@ -508,13 +498,13 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
|
||||
// Wait for filament insert by user and press button
|
||||
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
||||
wait_for_user = true; // LCD click or M108 will clear this
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Nozzle Parked"), CONTINUE_STR);
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_NOZZLE_PARKED), CONTINUE_STR);
|
||||
#endif
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired_P(PSTR("Nozzle Parked"));
|
||||
ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_NOZZLE_PARKED));
|
||||
#endif
|
||||
wait_for_user = true; // LCD click or M108 will clear this
|
||||
while (wait_for_user) {
|
||||
#if HAS_BUZZER
|
||||
filament_change_beep(max_beep_count);
|
||||
@@ -533,21 +523,20 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
SERIAL_ECHO_MSG(_PMSG(STR_FILAMENT_CHANGE_HEAT));
|
||||
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("HeaterTimeout"), PSTR("Reheat"));
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_HEATER_TIMEOUT), GET_TEXT(MSG_REHEAT));
|
||||
#endif
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired_P(PSTR("HeaterTimeout"));
|
||||
ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_HEATER_TIMEOUT));
|
||||
#endif
|
||||
|
||||
// Wait for LCD click or M108
|
||||
while (wait_for_user) idle_no_sleep();
|
||||
wait_for_user_response(0, true); // Wait for LCD click or M108
|
||||
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
host_prompt_do(PROMPT_INFO, PSTR("Reheating"));
|
||||
host_prompt_do(PROMPT_INFO, GET_TEXT(MSG_REHEATING));
|
||||
#endif
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onStatusChanged(PSTR("Reheating..."));
|
||||
ExtUI::onStatusChanged(GET_TEXT(MSG_REHEATING));
|
||||
#endif
|
||||
|
||||
// Re-enable the heaters if they timed out
|
||||
@@ -560,7 +549,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
show_continue_prompt(is_reload);
|
||||
|
||||
// Start the heater idle timers
|
||||
const millis_t nozzle_timeout = (millis_t)(PAUSE_PARK_NOZZLE_TIMEOUT) * 1000UL;
|
||||
const millis_t nozzle_timeout = SEC_TO_MS(PAUSE_PARK_NOZZLE_TIMEOUT);
|
||||
|
||||
HOTEND_LOOP() thermalManager.hotend_idle[e].start(nozzle_timeout);
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
@@ -633,11 +622,11 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
|
||||
#if ENABLED(FWRETRACT)
|
||||
// If retracted before goto pause
|
||||
if (fwretract.retracted[active_extruder])
|
||||
do_pause_e_move(-fwretract.settings.retract_length, fwretract.settings.retract_feedrate_mm_s);
|
||||
unscaled_e_move(-fwretract.settings.retract_length, fwretract.settings.retract_feedrate_mm_s);
|
||||
#endif
|
||||
|
||||
// If resume_position is negative
|
||||
if (resume_position.e < 0) do_pause_e_move(resume_position.e, feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE));
|
||||
if (resume_position.e < 0) unscaled_e_move(resume_position.e, feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE));
|
||||
|
||||
// Move XY to starting position, then Z
|
||||
do_blocking_move_to_xy(resume_position, feedRate_t(NOZZLE_PARK_XY_FEEDRATE));
|
||||
@@ -646,7 +635,7 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
|
||||
do_blocking_move_to_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE));
|
||||
|
||||
#if ADVANCED_PAUSE_RESUME_PRIME != 0
|
||||
do_pause_e_move(ADVANCED_PAUSE_RESUME_PRIME, feedRate_t(ADVANCED_PAUSE_PURGE_FEEDRATE));
|
||||
unscaled_e_move(ADVANCED_PAUSE_RESUME_PRIME, feedRate_t(ADVANCED_PAUSE_PURGE_FEEDRATE));
|
||||
#endif
|
||||
|
||||
// Now all extrusion positions are resumed and ready to be confirmed
|
||||
|
||||
@@ -83,8 +83,6 @@ extern uint8_t did_pause_print;
|
||||
#define DXC_PASS
|
||||
#endif
|
||||
|
||||
void do_pause_e_move(const float &length, const feedRate_t &fr_mm_s);
|
||||
|
||||
bool pause_print(const float &retract, const xyz_pos_t &park_point, const float &unload_length=0, const bool show_lcd=false DXC_PARAMS);
|
||||
|
||||
void wait_for_confirmation(const bool is_reload=false, const int8_t max_beep_count=0 DXC_PARAMS);
|
||||
|
||||
@@ -98,7 +98,7 @@ void Power::check() {
|
||||
nextPowerCheck = ms + 2500UL;
|
||||
if (is_power_needed())
|
||||
power_on();
|
||||
else if (!lastPowerOn || ELAPSED(ms, lastPowerOn + (POWER_TIMEOUT) * 1000UL))
|
||||
else if (!lastPowerOn || ELAPSED(ms, lastPowerOn + SEC_TO_MS(POWER_TIMEOUT)))
|
||||
power_off();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
|
||||
ProbeTempComp temp_comp;
|
||||
|
||||
int16_t ProbeTempComp::z_offsets_probe[ProbeTempComp::cali_info_init[TSI_PROBE].measurements], // = {0}
|
||||
ProbeTempComp::z_offsets_bed[ProbeTempComp::cali_info_init[TSI_BED].measurements]; // = {0}
|
||||
int16_t ProbeTempComp::z_offsets_probe[cali_info_init[TSI_PROBE].measurements], // = {0}
|
||||
ProbeTempComp::z_offsets_bed[cali_info_init[TSI_BED].measurements]; // = {0}
|
||||
|
||||
#if ENABLED(USE_TEMP_EXT_COMPENSATION)
|
||||
int16_t ProbeTempComp::z_offsets_ext[ProbeTempComp::cali_info_init[TSI_EXT].measurements]; // = {0}
|
||||
int16_t ProbeTempComp::z_offsets_ext[cali_info_init[TSI_EXT].measurements]; // = {0}
|
||||
#endif
|
||||
|
||||
int16_t *ProbeTempComp::sensor_z_offsets[TSI_COUNT] = {
|
||||
@@ -44,9 +44,9 @@ int16_t *ProbeTempComp::sensor_z_offsets[TSI_COUNT] = {
|
||||
};
|
||||
|
||||
const temp_calib_t ProbeTempComp::cali_info[TSI_COUNT] = {
|
||||
ProbeTempComp::cali_info_init[TSI_PROBE], ProbeTempComp::cali_info_init[TSI_BED]
|
||||
cali_info_init[TSI_PROBE], cali_info_init[TSI_BED]
|
||||
#if ENABLED(USE_TEMP_EXT_COMPENSATION)
|
||||
, ProbeTempComp::cali_info_init[TSI_EXT]
|
||||
, cali_info_init[TSI_EXT]
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -44,30 +44,28 @@ typedef struct {
|
||||
* Z-probes like the P.I.N.D.A V2 allow for compensation of
|
||||
* measurement errors/shifts due to changed temperature.
|
||||
*/
|
||||
|
||||
static constexpr temp_calib_t cali_info_init[TSI_COUNT] = {
|
||||
{ 10, 5, 30, 30 + 10 * 5 }, // Probe
|
||||
{ 10, 5, 60, 60 + 10 * 5 }, // Bed
|
||||
#if ENABLED(USE_TEMP_EXT_COMPENSATION)
|
||||
{ 20, 5, 180, 180 + 5 * 20 } // Extruder
|
||||
#endif
|
||||
};
|
||||
|
||||
class ProbeTempComp {
|
||||
public:
|
||||
|
||||
static constexpr temp_calib_t cali_info_init[TSI_COUNT] = {
|
||||
{ 10, 5, 30, 30 + 10 * 5 }, // Probe
|
||||
{ 10, 5, 60, 60 + 10 * 5 }, // Bed
|
||||
#if ENABLED(USE_TEMP_EXT_COMPENSATION)
|
||||
{ 20, 5, 180, 180 + 5 * 20 } // Extruder
|
||||
#endif
|
||||
};
|
||||
static const temp_calib_t cali_info[TSI_COUNT];
|
||||
|
||||
// Where to park nozzle to wait for probe cooldown
|
||||
static constexpr float park_point_x = PTC_PARK_POS_X,
|
||||
park_point_y = PTC_PARK_POS_Y,
|
||||
park_point_z = PTC_PARK_POS_Z,
|
||||
// XY coordinates of nozzle for probing the bed
|
||||
measure_point_x = PTC_PROBE_POS_X, // Coordinates to probe
|
||||
measure_point_y = PTC_PROBE_POS_Y;
|
||||
//measure_point_x = 12.0f, // Coordinates to probe on MK52 magnetic heatbed
|
||||
//measure_point_y = 7.3f;
|
||||
static constexpr xyz_pos_t park_point = PTC_PARK_POS;
|
||||
|
||||
static constexpr int max_bed_temp = PTC_MAX_BED_TEMP, // Max temperature to avoid heating errors
|
||||
probe_calib_bed_temp = max_bed_temp, // Bed temperature while calibrating probe
|
||||
// XY coordinates of nozzle for probing the bed
|
||||
static constexpr xy_pos_t measure_point = PTC_PROBE_POS; // Coordinates to probe
|
||||
//measure_point = { 12.0f, 7.3f }; // Coordinates for the MK52 magnetic heatbed
|
||||
|
||||
static constexpr int probe_calib_bed_temp = BED_MAXTEMP - 10, // Bed temperature while calibrating probe
|
||||
bed_calib_probe_temp = 30; // Probe temperature while calibrating bed
|
||||
|
||||
static int16_t *sensor_z_offsets[TSI_COUNT],
|
||||
|
||||
@@ -32,10 +32,17 @@
|
||||
|
||||
SpindleLaser cutter;
|
||||
|
||||
cutter_power_t SpindleLaser::power; // = 0
|
||||
|
||||
cutter_power_t SpindleLaser::power;
|
||||
bool SpindleLaser::isOn; // state to determine when to apply setPower to power
|
||||
cutter_setPower_t SpindleLaser::setPower = interpret_power(SPEED_POWER_MIN); // spindle/laser speed/power control in PWM, Percentage or RPM
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
cutter_frequency_t SpindleLaser::frequency; // setting PWM frequency; range: 2K - 50K
|
||||
#endif
|
||||
#define SPINDLE_LASER_PWM_OFF ((SPINDLE_LASER_PWM_INVERT) ? 255 : 0)
|
||||
|
||||
//
|
||||
// Init the cutter to a safe OFF state
|
||||
//
|
||||
void SpindleLaser::init() {
|
||||
OUT_WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_HIGH); // Init spindle to off
|
||||
#if ENABLED(SPINDLE_CHANGE_DIR)
|
||||
@@ -45,41 +52,39 @@ void SpindleLaser::init() {
|
||||
SET_PWM(SPINDLE_LASER_PWM_PIN);
|
||||
analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // set to lowest speed
|
||||
#endif
|
||||
#if ENABLED(HAL_CAN_SET_PWM_FREQ) && defined(SPINDLE_LASER_FREQUENCY)
|
||||
set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY);
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
frequency = SPINDLE_LASER_FREQUENCY;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLED(SPINDLE_LASER_PWM)
|
||||
|
||||
/**
|
||||
* ocr_val_mode() is used for debugging and to get the points needed to compute the RPM vs ocr_val line
|
||||
*
|
||||
* it accepts inputs of 0-255
|
||||
*/
|
||||
* Set the cutter PWM directly to the given ocr value
|
||||
**/
|
||||
void SpindleLaser::set_ocr(const uint8_t ocr) {
|
||||
WRITE(SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_HIGH); // turn spindle on (active low)
|
||||
WRITE(SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_HIGH); // turn spindle on
|
||||
analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// Set cutter ON state (and PWM) to the given cutter power value
|
||||
//
|
||||
void SpindleLaser::apply_power(const cutter_power_t inpow) {
|
||||
static cutter_power_t last_power_applied = 0;
|
||||
if (inpow == last_power_applied) return;
|
||||
last_power_applied = inpow;
|
||||
#if ENABLED(SPINDLE_LASER_PWM)
|
||||
if (enabled()) {
|
||||
#define _scaled(F) ((F - (SPEED_POWER_INTERCEPT)) * inv_slope)
|
||||
constexpr float inv_slope = RECIPROCAL(SPEED_POWER_SLOPE),
|
||||
min_ocr = _scaled(SPEED_POWER_MIN),
|
||||
max_ocr = _scaled(SPEED_POWER_MAX);
|
||||
int16_t ocr_val;
|
||||
if (inpow <= SPEED_POWER_MIN) ocr_val = min_ocr; // Use minimum if set below
|
||||
else if (inpow >= SPEED_POWER_MAX) ocr_val = max_ocr; // Use maximum if set above
|
||||
else ocr_val = _scaled(inpow); // Use calculated OCR value
|
||||
set_ocr(ocr_val & 0xFF); // ...limited to Atmel PWM max
|
||||
}
|
||||
if (enabled())
|
||||
set_ocr(translate_power(inpow));
|
||||
else {
|
||||
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_HIGH); // Turn spindle off (active low)
|
||||
analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Only write low byte
|
||||
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_HIGH); // Turn spindle off
|
||||
analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Only write low byte
|
||||
}
|
||||
#else
|
||||
WRITE(SPINDLE_LASER_ENA_PIN, (SPINDLE_LASER_ACTIVE_HIGH) ? enabled() : !enabled());
|
||||
@@ -88,6 +93,10 @@ void SpindleLaser::apply_power(const cutter_power_t inpow) {
|
||||
|
||||
#if ENABLED(SPINDLE_CHANGE_DIR)
|
||||
|
||||
//
|
||||
// Set the spindle direction and apply immediately
|
||||
// Stop on direction change if SPINDLE_STOP_ON_DIR_CHANGE is enabled
|
||||
//
|
||||
void SpindleLaser::set_direction(const bool reverse) {
|
||||
const bool dir_state = (reverse == SPINDLE_INVERT_DIR); // Forward (M3) HIGH when not inverted
|
||||
#if ENABLED(SPINDLE_STOP_ON_DIR_CHANGE)
|
||||
|
||||
@@ -28,55 +28,98 @@
|
||||
|
||||
#include "../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(SPINDLE_FEATURE)
|
||||
#define _MSG_CUTTER(M) MSG_SPINDLE_##M
|
||||
#else
|
||||
#define _MSG_CUTTER(M) MSG_LASER_##M
|
||||
#endif
|
||||
#define MSG_CUTTER(M) _MSG_CUTTER(M)
|
||||
#include "spindle_laser_types.h"
|
||||
|
||||
#if SPEED_POWER_MAX > 255
|
||||
typedef uint16_t cutter_power_t;
|
||||
#define CUTTER_MENU_TYPE uint16_5
|
||||
#else
|
||||
typedef uint8_t cutter_power_t;
|
||||
#define CUTTER_MENU_TYPE uint8
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
#include "../module/planner.h"
|
||||
#endif
|
||||
|
||||
class SpindleLaser {
|
||||
public:
|
||||
static bool isOn; // state to determine when to apply setPower to power
|
||||
static cutter_power_t power;
|
||||
static inline uint8_t powerPercent(const uint8_t pp) { return ui8_to_percent(pp); } // for display
|
||||
static cutter_setPower_t setPower; // spindle/laser menu set power; in PWM, Percentage or RPM
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
static cutter_frequency_t frequency; // set PWM frequency; range: 2K-50K
|
||||
#endif
|
||||
|
||||
static cutter_setPower_t interpret_power(const float pwr) { // convert speed/power to configured PWM, Percentage or RPM in relative or normal range
|
||||
#if CUTTER_DISPLAY_IS(PERCENT)
|
||||
return (pwr / SPEED_POWER_MAX) * 100; // to percent
|
||||
#elif CUTTER_DISPLAY_IS(RPM) // to RPM is unaltered
|
||||
return pwr;
|
||||
#else // to PWM
|
||||
#if ENABLED(CUTTER_POWER_RELATIVE)
|
||||
return (pwr - SPEED_POWER_MIN) / (SPEED_POWER_MAX - SPEED_POWER_MIN) * 255; // using rpm range as relative percentage
|
||||
#else
|
||||
return (pwr / SPEED_POWER_MAX) * 255;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* Translate speed/power --> percentage --> PWM value
|
||||
**/
|
||||
static cutter_power_t translate_power(const float pwr) {
|
||||
float pwrpc;
|
||||
#if CUTTER_DISPLAY_IS(PERCENT)
|
||||
pwrpc = pwr;
|
||||
#elif CUTTER_DISPLAY_IS(RPM) // RPM to percent
|
||||
#if ENABLED(CUTTER_POWER_RELATIVE)
|
||||
pwrpc = (pwr - SPEED_POWER_MIN) / (SPEED_POWER_MAX - SPEED_POWER_MIN) * 100;
|
||||
#else
|
||||
pwrpc = pwr / SPEED_POWER_MAX * 100;
|
||||
#endif
|
||||
#else
|
||||
return pwr; // PWM
|
||||
#endif
|
||||
|
||||
#if ENABLED(SPINDLE_FEATURE)
|
||||
#if ENABLED(CUTTER_POWER_RELATIVE)
|
||||
constexpr float spmin = 0;
|
||||
#else
|
||||
constexpr float spmin = SPEED_POWER_MIN / SPEED_POWER_MAX * 100; // convert to percentage
|
||||
#endif
|
||||
constexpr float spmax = 100;
|
||||
#else
|
||||
constexpr float spmin = SPEED_POWER_MIN;
|
||||
constexpr float spmax = SPEED_POWER_MAX;
|
||||
#endif
|
||||
|
||||
constexpr float inv_slope = RECIPROCAL(SPEED_POWER_SLOPE),
|
||||
min_ocr = (spmin - (SPEED_POWER_INTERCEPT)) * inv_slope, // Minimum allowed
|
||||
max_ocr = (spmax - (SPEED_POWER_INTERCEPT)) * inv_slope; // Maximum allowed
|
||||
float ocr_val;
|
||||
if (pwrpc < spmin) ocr_val = min_ocr; // Use minimum if set below
|
||||
else if (pwrpc > spmax) ocr_val = max_ocr; // Use maximum if set above
|
||||
else ocr_val = (pwrpc - (SPEED_POWER_INTERCEPT)) * inv_slope; // Use calculated OCR value
|
||||
return ocr_val; // ...limited to Atmel PWM max
|
||||
}
|
||||
|
||||
static void init();
|
||||
|
||||
static inline bool enabled() { return !!power; }
|
||||
|
||||
static inline void set_power(const cutter_power_t pwr) { power = pwr; }
|
||||
|
||||
static inline void refresh() { apply_power(power); }
|
||||
|
||||
static inline void set_enabled(const bool enable) {
|
||||
const bool was = enabled();
|
||||
set_power(enable ? 255 : 0);
|
||||
if (was != enable) power_delay();
|
||||
}
|
||||
|
||||
// Modifying this function should update everywhere
|
||||
static inline bool enabled(const cutter_power_t pwr) { return pwr > 0; }
|
||||
static inline bool enabled() { return enabled(power); }
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
static inline void refresh_frequency() { set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency); }
|
||||
#endif
|
||||
static void apply_power(const cutter_power_t inpow);
|
||||
|
||||
//static bool active() { return READ(SPINDLE_LASER_ENA_PIN) == SPINDLE_LASER_ACTIVE_HIGH; }
|
||||
FORCE_INLINE static void refresh() { apply_power(power); }
|
||||
FORCE_INLINE static void set_power(const cutter_power_t pwr) { power = pwr; refresh(); }
|
||||
|
||||
static void update_output();
|
||||
static inline void set_enabled(const bool enable) { set_power(enable ? (power ?: interpret_power(SPEED_POWER_STARTUP)) : 0); }
|
||||
|
||||
#if ENABLED(SPINDLE_LASER_PWM)
|
||||
static void set_ocr(const uint8_t ocr);
|
||||
static inline void set_ocr_power(const cutter_power_t pwr) { power = pwr; set_ocr(pwr); }
|
||||
static inline void set_ocr_power(const uint8_t pwr) { power = pwr; set_ocr(pwr); }
|
||||
// static uint8_t translate_power(const cutter_power_t pwr); // Used by update output for power->OCR translation
|
||||
#endif
|
||||
|
||||
// Wait for spindle to spin up or spin down
|
||||
static inline void power_delay() {
|
||||
#if SPINDLE_LASER_POWERUP_DELAY || SPINDLE_LASER_POWERDOWN_DELAY
|
||||
safe_delay(enabled() ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY);
|
||||
static inline void power_delay(const bool on) {
|
||||
#if DISABLED(LASER_POWER_INLINE)
|
||||
safe_delay(on ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -86,10 +129,44 @@ public:
|
||||
static inline void set_direction(const bool) {}
|
||||
#endif
|
||||
|
||||
static inline void disable() { set_enabled(false); }
|
||||
static inline void enable_forward() { set_direction(false); set_enabled(true); }
|
||||
static inline void enable_reverse() { set_direction(true); set_enabled(true); }
|
||||
static inline void disable() { isOn = false; set_enabled(false); }
|
||||
#if HAS_LCD_MENU
|
||||
static inline void enable_forward() { isOn = true; setPower ? (power = setPower) : (setPower = interpret_power(SPEED_POWER_STARTUP)); set_direction(false); set_enabled(true); }
|
||||
static inline void enable_reverse() { isOn = true; setPower ? (power = setPower) : (setPower = interpret_power(SPEED_POWER_STARTUP)); set_direction(true); set_enabled(true); }
|
||||
#endif
|
||||
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
// Force disengage planner power control
|
||||
static inline void inline_disable() { planner.settings.laser.status = 0; planner.settings.laser.power = 0; isOn = false;}
|
||||
|
||||
// Inline modes of all other functions; all enable planner inline power control
|
||||
static inline void inline_enabled(const bool enable) { enable ? inline_power(SPEED_POWER_STARTUP) : inline_ocr_power(0); }
|
||||
|
||||
static void inline_power(const cutter_power_t pwr) {
|
||||
#if ENABLED(SPINDLE_LASER_PWM)
|
||||
inline_ocr_power(translate_power(pwr));
|
||||
#else
|
||||
planner.settings.laser.status = enabled(pwr) ? 0x03 : 0x01;
|
||||
planner.settings.laser.power = pwr;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void inline_direction(const bool reverse) { UNUSED(reverse); } // TODO is this ever going to be needed
|
||||
|
||||
#if ENABLED(SPINDLE_LASER_PWM)
|
||||
static inline void inline_ocr_power(const uint8_t pwr) {
|
||||
planner.settings.laser.status = pwr ? 0x03 : 0x01;
|
||||
planner.settings.laser.power = pwr;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static inline void kill() {
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
inline_disable();
|
||||
#endif
|
||||
disable();
|
||||
}
|
||||
};
|
||||
|
||||
extern SpindleLaser cutter;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* feature/spindle_laser_types.h
|
||||
* Support for Laser Power or Spindle Power & Direction
|
||||
*/
|
||||
|
||||
#include "../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(SPINDLE_FEATURE)
|
||||
#define _MSG_CUTTER(M) MSG_SPINDLE_##M
|
||||
#else
|
||||
#define _MSG_CUTTER(M) MSG_LASER_##M
|
||||
#endif
|
||||
#define MSG_CUTTER(M) _MSG_CUTTER(M)
|
||||
#if CUTTER_DISPLAY_IS(RPM) && SPEED_POWER_MAX > 255
|
||||
#define cutter_power_t uint16_t
|
||||
#define cutter_setPower_t uint16_t
|
||||
#define CUTTER_MENU_POWER_TYPE uint16_5
|
||||
#else
|
||||
#define cutter_power_t uint8_t
|
||||
#define cutter_setPower_t uint8_t
|
||||
#define CUTTER_MENU_POWER_TYPE uint8
|
||||
#endif
|
||||
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
#define cutter_frequency_t uint16_t
|
||||
#define CUTTER_MENU_FREQUENCY_TYPE uint16_5
|
||||
#endif
|
||||
@@ -1254,7 +1254,7 @@ void test_tmc_connection(const bool test_x, const bool test_y, const bool test_z
|
||||
#endif
|
||||
}
|
||||
|
||||
if (axis_connection) ui.set_status_P(GET_TEXT(MSG_ERROR_TMC));
|
||||
if (axis_connection) LCD_MESSAGEPGM(MSG_ERROR_TMC);
|
||||
}
|
||||
|
||||
#endif // HAS_TRINAMIC_CONFIG
|
||||
|
||||
@@ -49,37 +49,27 @@ void TWIBus::address(const uint8_t adr) {
|
||||
|
||||
addr = adr;
|
||||
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
debug(PSTR("address"), adr);
|
||||
#endif
|
||||
debug(PSTR("address"), adr);
|
||||
}
|
||||
|
||||
void TWIBus::addbyte(const char c) {
|
||||
if (buffer_s >= COUNT(buffer)) return;
|
||||
buffer[buffer_s++] = c;
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
debug(PSTR("addbyte"), c);
|
||||
#endif
|
||||
debug(PSTR("addbyte"), c);
|
||||
}
|
||||
|
||||
void TWIBus::addbytes(char src[], uint8_t bytes) {
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
debug(PSTR("addbytes"), bytes);
|
||||
#endif
|
||||
debug(PSTR("addbytes"), bytes);
|
||||
while (bytes--) addbyte(*src++);
|
||||
}
|
||||
|
||||
void TWIBus::addstring(char str[]) {
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
debug(PSTR("addstring"), str);
|
||||
#endif
|
||||
debug(PSTR("addstring"), str);
|
||||
while (char c = *str++) addbyte(c);
|
||||
}
|
||||
|
||||
void TWIBus::send() {
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
debug(PSTR("send"), addr);
|
||||
#endif
|
||||
debug(PSTR("send"), addr);
|
||||
|
||||
Wire.beginTransmission(I2C_ADDRESS(addr));
|
||||
Wire.write(buffer, buffer_s);
|
||||
@@ -89,21 +79,21 @@ void TWIBus::send() {
|
||||
}
|
||||
|
||||
// static
|
||||
void TWIBus::echoprefix(uint8_t bytes, const char prefix[], uint8_t adr) {
|
||||
void TWIBus::echoprefix(uint8_t bytes, const char pref[], uint8_t adr) {
|
||||
SERIAL_ECHO_START();
|
||||
serialprintPGM(prefix);
|
||||
serialprintPGM(pref);
|
||||
SERIAL_ECHOPAIR(": from:", adr, " bytes:", bytes, " data:");
|
||||
}
|
||||
|
||||
// static
|
||||
void TWIBus::echodata(uint8_t bytes, const char prefix[], uint8_t adr) {
|
||||
echoprefix(bytes, prefix, adr);
|
||||
void TWIBus::echodata(uint8_t bytes, const char pref[], uint8_t adr) {
|
||||
echoprefix(bytes, pref, adr);
|
||||
while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read());
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
void TWIBus::echobuffer(const char prefix[], uint8_t adr) {
|
||||
echoprefix(buffer_s, prefix, adr);
|
||||
void TWIBus::echobuffer(const char pref[], uint8_t adr) {
|
||||
echoprefix(buffer_s, pref, adr);
|
||||
LOOP_L_N(i, buffer_s) SERIAL_CHAR(buffer[i]);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
@@ -111,15 +101,11 @@ void TWIBus::echobuffer(const char prefix[], uint8_t adr) {
|
||||
bool TWIBus::request(const uint8_t bytes) {
|
||||
if (!addr) return false;
|
||||
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
debug(PSTR("request"), bytes);
|
||||
#endif
|
||||
debug(PSTR("request"), bytes);
|
||||
|
||||
// requestFrom() is a blocking function
|
||||
if (Wire.requestFrom(addr, bytes) == 0) {
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
debug("request fail", addr);
|
||||
#endif
|
||||
debug("request fail", addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -127,9 +113,7 @@ bool TWIBus::request(const uint8_t bytes) {
|
||||
}
|
||||
|
||||
void TWIBus::relay(const uint8_t bytes) {
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
debug(PSTR("relay"), bytes);
|
||||
#endif
|
||||
debug(PSTR("relay"), bytes);
|
||||
|
||||
if (request(bytes))
|
||||
echodata(bytes, PSTR("i2c-reply"), addr);
|
||||
@@ -141,9 +125,7 @@ uint8_t TWIBus::capture(char *dst, const uint8_t bytes) {
|
||||
while (count < bytes && Wire.available())
|
||||
dst[count++] = Wire.read();
|
||||
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
debug(PSTR("capture"), count);
|
||||
#endif
|
||||
debug(PSTR("capture"), count);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -156,16 +138,12 @@ void TWIBus::flush() {
|
||||
#if I2C_SLAVE_ADDRESS > 0
|
||||
|
||||
void TWIBus::receive(uint8_t bytes) {
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
debug(PSTR("receive"), bytes);
|
||||
#endif
|
||||
debug(PSTR("receive"), bytes);
|
||||
echodata(bytes, PSTR("i2c-receive"), 0);
|
||||
}
|
||||
|
||||
void TWIBus::reply(char str[]/*=nullptr*/) {
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
debug(PSTR("reply"), str);
|
||||
#endif
|
||||
debug(PSTR("reply"), str);
|
||||
|
||||
if (str) {
|
||||
reset();
|
||||
|
||||
@@ -223,7 +223,6 @@ class TWIBus {
|
||||
#endif
|
||||
|
||||
#if ENABLED(DEBUG_TWIBUS)
|
||||
|
||||
/**
|
||||
* @brief Prints a debug message
|
||||
* @details Prints a simple debug message "TWIBus::function: value"
|
||||
@@ -233,6 +232,10 @@ class TWIBus {
|
||||
static void debug(const char func[], char c);
|
||||
static void debug(const char func[], char adr[]);
|
||||
static inline void debug(const char func[], uint8_t v) { debug(func, (uint32_t)v); }
|
||||
|
||||
#else
|
||||
static inline void debug(const char[], uint32_t) {}
|
||||
static inline void debug(const char[], char) {}
|
||||
static inline void debug(const char[], char[]) {}
|
||||
static inline void debug(const char[], uint8_t) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -155,21 +155,18 @@ void GcodeSuite::M420() {
|
||||
|
||||
// Get the sum and average of all mesh values
|
||||
float mesh_sum = 0;
|
||||
for (uint8_t x = GRID_MAX_POINTS_X; x--;)
|
||||
for (uint8_t y = GRID_MAX_POINTS_Y; y--;)
|
||||
mesh_sum += Z_VALUES(x, y);
|
||||
GRID_LOOP(x, y) mesh_sum += Z_VALUES(x, y);
|
||||
const float zmean = mesh_sum / float(GRID_MAX_POINTS);
|
||||
|
||||
#else
|
||||
|
||||
// Find the low and high mesh values
|
||||
float lo_val = 100, hi_val = -100;
|
||||
for (uint8_t x = GRID_MAX_POINTS_X; x--;)
|
||||
for (uint8_t y = GRID_MAX_POINTS_Y; y--;) {
|
||||
const float z = Z_VALUES(x, y);
|
||||
NOMORE(lo_val, z);
|
||||
NOLESS(hi_val, z);
|
||||
}
|
||||
GRID_LOOP(x, y) {
|
||||
const float z = Z_VALUES(x, y);
|
||||
NOMORE(lo_val, z);
|
||||
NOLESS(hi_val, z);
|
||||
}
|
||||
// Take the mean of the lowest and highest
|
||||
const float zmean = (lo_val + hi_val) / 2.0 + cval;
|
||||
|
||||
@@ -179,13 +176,12 @@ void GcodeSuite::M420() {
|
||||
if (!NEAR_ZERO(zmean)) {
|
||||
set_bed_leveling_enabled(false);
|
||||
// Subtract the mean from all values
|
||||
for (uint8_t x = GRID_MAX_POINTS_X; x--;)
|
||||
for (uint8_t y = GRID_MAX_POINTS_Y; y--;) {
|
||||
Z_VALUES(x, y) -= zmean;
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onMeshUpdate(x, y, Z_VALUES(x, y));
|
||||
#endif
|
||||
}
|
||||
GRID_LOOP(x, y) {
|
||||
Z_VALUES(x, y) -= zmean;
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onMeshUpdate(x, y, Z_VALUES(x, y));
|
||||
#endif
|
||||
}
|
||||
#if ENABLED(ABL_BILINEAR_SUBDIVISION)
|
||||
bed_level_virt_interpolate();
|
||||
#endif
|
||||
|
||||
@@ -255,28 +255,28 @@ void GcodeSuite::G28() {
|
||||
#define HAS_HOMING_CURRENT (HAS_CURRENT_HOME(X) || HAS_CURRENT_HOME(X2) || HAS_CURRENT_HOME(Y) || HAS_CURRENT_HOME(Y2))
|
||||
|
||||
#if HAS_HOMING_CURRENT
|
||||
auto debug_current = [](const char * const s, const int16_t a, const int16_t b){
|
||||
DEBUG_ECHO(s); DEBUG_ECHOLNPAIR(" current: ", a, " -> ", b);
|
||||
auto debug_current = [](PGM_P const s, const int16_t a, const int16_t b){
|
||||
serialprintPGM(s); DEBUG_ECHOLNPAIR(" current: ", a, " -> ", b);
|
||||
};
|
||||
#if HAS_CURRENT_HOME(X)
|
||||
const int16_t tmc_save_current_X = stepperX.getMilliamps();
|
||||
stepperX.rms_current(X_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current("X", tmc_save_current_X, X_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(PSTR("X"), tmc_save_current_X, X_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(X2)
|
||||
const int16_t tmc_save_current_X2 = stepperX2.getMilliamps();
|
||||
stepperX2.rms_current(X2_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current("X2", tmc_save_current_X2, X2_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(PSTR("X2"), tmc_save_current_X2, X2_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Y)
|
||||
const int16_t tmc_save_current_Y = stepperY.getMilliamps();
|
||||
stepperY.rms_current(Y_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current("Y", tmc_save_current_Y, Y_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(PSTR("Y"), tmc_save_current_Y, Y_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Y2)
|
||||
const int16_t tmc_save_current_Y2 = stepperY2.getMilliamps();
|
||||
stepperY2.rms_current(Y2_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current("Y2", tmc_save_current_Y2, Y2_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(PSTR("Y2"), tmc_save_current_Y2, Y2_CURRENT_HOME);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -345,12 +345,8 @@ void GcodeSuite::G28() {
|
||||
#endif
|
||||
|
||||
// Home Y (before X)
|
||||
#if ENABLED(HOME_Y_BEFORE_X)
|
||||
|
||||
if (doY || (doX && ENABLED(CODEPENDENT_XY_HOMING)))
|
||||
homeaxis(Y_AXIS);
|
||||
|
||||
#endif
|
||||
if (ENABLED(HOME_Y_BEFORE_X) && (doY || (ENABLED(CODEPENDENT_XY_HOMING) && doX)))
|
||||
homeaxis(Y_AXIS);
|
||||
|
||||
// Home X
|
||||
if (doX || (doY && ENABLED(CODEPENDENT_XY_HOMING) && DISABLED(HOME_Y_BEFORE_X))) {
|
||||
|
||||
@@ -37,6 +37,21 @@
|
||||
#include "../../module/endstops.h"
|
||||
#include "../../feature/bedlevel/bedlevel.h"
|
||||
|
||||
#if !AXIS_CAN_CALIBRATE(X)
|
||||
#undef CALIBRATION_MEASURE_LEFT
|
||||
#undef CALIBRATION_MEASURE_RIGHT
|
||||
#endif
|
||||
|
||||
#if !AXIS_CAN_CALIBRATE(Y)
|
||||
#undef CALIBRATION_MEASURE_FRONT
|
||||
#undef CALIBRATION_MEASURE_BACK
|
||||
#endif
|
||||
|
||||
#if !AXIS_CAN_CALIBRATE(Z)
|
||||
#undef CALIBRATION_MEASURE_AT_TOP_EDGES
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* G425 backs away from the calibration object by various distances
|
||||
* depending on the confidence level:
|
||||
@@ -207,42 +222,52 @@ inline float measure(const AxisEnum axis, const int dir, const bool stop_state,
|
||||
inline void probe_side(measurements_t &m, const float uncertainty, const side_t side, const bool probe_top_at_edge=false) {
|
||||
const xyz_float_t dimensions = CALIBRATION_OBJECT_DIMENSIONS;
|
||||
AxisEnum axis;
|
||||
float dir;
|
||||
float dir = 1;
|
||||
|
||||
park_above_object(m, uncertainty);
|
||||
|
||||
switch (side) {
|
||||
case TOP: {
|
||||
const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
|
||||
m.obj_center.z = measurement - dimensions.z / 2;
|
||||
m.obj_side[TOP] = measurement;
|
||||
return;
|
||||
}
|
||||
case RIGHT: axis = X_AXIS; dir = -1; break;
|
||||
case FRONT: axis = Y_AXIS; dir = 1; break;
|
||||
case LEFT: axis = X_AXIS; dir = 1; break;
|
||||
case BACK: axis = Y_AXIS; dir = -1; break;
|
||||
#if AXIS_CAN_CALIBRATE(Z)
|
||||
case TOP: {
|
||||
const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
|
||||
m.obj_center.z = measurement - dimensions.z / 2;
|
||||
m.obj_side[TOP] = measurement;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if AXIS_CAN_CALIBRATE(X)
|
||||
case LEFT: axis = X_AXIS; break;
|
||||
case RIGHT: axis = X_AXIS; dir = -1; break;
|
||||
#endif
|
||||
#if AXIS_CAN_CALIBRATE(Y)
|
||||
case FRONT: axis = Y_AXIS; break;
|
||||
case BACK: axis = Y_AXIS; dir = -1; break;
|
||||
#endif
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (probe_top_at_edge) {
|
||||
// Probe top nearest the side we are probing
|
||||
current_position[axis] = m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 - m.nozzle_outer_dimension[axis]);
|
||||
calibration_move();
|
||||
m.obj_side[TOP] = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
|
||||
m.obj_center.z = m.obj_side[TOP] - dimensions.z / 2;
|
||||
#if AXIS_CAN_CALIBRATE(Z)
|
||||
// Probe top nearest the side we are probing
|
||||
current_position[axis] = m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 - m.nozzle_outer_dimension[axis]);
|
||||
calibration_move();
|
||||
m.obj_side[TOP] = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
|
||||
m.obj_center.z = m.obj_side[TOP] - dimensions.z / 2;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Move to safe distance to the side of the calibration object
|
||||
current_position[axis] = m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2 + uncertainty);
|
||||
calibration_move();
|
||||
if (AXIS_CAN_CALIBRATE(X) && axis == X_AXIS || AXIS_CAN_CALIBRATE(Y) && axis == Y_AXIS) {
|
||||
// Move to safe distance to the side of the calibration object
|
||||
current_position[axis] = m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2 + uncertainty);
|
||||
calibration_move();
|
||||
|
||||
// Plunge below the side of the calibration object and measure
|
||||
current_position.z = m.obj_side[TOP] - CALIBRATION_NOZZLE_TIP_HEIGHT * 0.7;
|
||||
calibration_move();
|
||||
const float measurement = measure(axis, dir, true, &m.backlash[side], uncertainty);
|
||||
m.obj_center[axis] = measurement + dir * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2);
|
||||
m.obj_side[side] = measurement;
|
||||
// Plunge below the side of the calibration object and measure
|
||||
current_position.z = m.obj_side[TOP] - (CALIBRATION_NOZZLE_TIP_HEIGHT) * 0.7f;
|
||||
calibration_move();
|
||||
const float measurement = measure(axis, dir, true, &m.backlash[side], uncertainty);
|
||||
m.obj_center[axis] = measurement + dir * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2);
|
||||
m.obj_side[side] = measurement;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,7 +277,7 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
|
||||
* uncertainty in - How far away from the calibration object to begin probing
|
||||
*/
|
||||
inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||
#ifdef CALIBRATION_MEASURE_AT_TOP_EDGES
|
||||
#if ENABLED(CALIBRATION_MEASURE_AT_TOP_EDGES)
|
||||
constexpr bool probe_top_at_edge = true;
|
||||
#else
|
||||
// Probing at the exact center only works if the center is flat. Probing on a washer
|
||||
@@ -261,18 +286,18 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||
probe_side(m, uncertainty, TOP);
|
||||
#endif
|
||||
|
||||
#ifdef CALIBRATION_MEASURE_RIGHT
|
||||
#if ENABLED(CALIBRATION_MEASURE_RIGHT)
|
||||
probe_side(m, uncertainty, RIGHT, probe_top_at_edge);
|
||||
#endif
|
||||
|
||||
#ifdef CALIBRATION_MEASURE_FRONT
|
||||
#if ENABLED(CALIBRATION_MEASURE_FRONT)
|
||||
probe_side(m, uncertainty, FRONT, probe_top_at_edge);
|
||||
#endif
|
||||
|
||||
#ifdef CALIBRATION_MEASURE_LEFT
|
||||
#if ENABLED(CALIBRATION_MEASURE_LEFT)
|
||||
probe_side(m, uncertainty, LEFT, probe_top_at_edge);
|
||||
#endif
|
||||
#ifdef CALIBRATION_MEASURE_BACK
|
||||
#if ENABLED(CALIBRATION_MEASURE_BACK)
|
||||
probe_side(m, uncertainty, BACK, probe_top_at_edge);
|
||||
#endif
|
||||
|
||||
@@ -313,7 +338,9 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||
#if ENABLED(CALIBRATION_REPORTING)
|
||||
inline void report_measured_faces(const measurements_t &m) {
|
||||
SERIAL_ECHOLNPGM("Sides:");
|
||||
SERIAL_ECHOLNPAIR(" Top: ", m.obj_side[TOP]);
|
||||
#if AXIS_CAN_CALIBRATE(Z)
|
||||
SERIAL_ECHOLNPAIR(" Top: ", m.obj_side[TOP]);
|
||||
#endif
|
||||
#if ENABLED(CALIBRATION_MEASURE_LEFT)
|
||||
SERIAL_ECHOLNPAIR(" Left: ", m.obj_side[LEFT]);
|
||||
#endif
|
||||
@@ -343,19 +370,25 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||
|
||||
inline void report_measured_backlash(const measurements_t &m) {
|
||||
SERIAL_ECHOLNPGM("Backlash:");
|
||||
#if ENABLED(CALIBRATION_MEASURE_LEFT)
|
||||
SERIAL_ECHOLNPAIR(" Left: ", m.backlash[LEFT]);
|
||||
#if AXIS_CAN_CALIBRATE(X)
|
||||
#if ENABLED(CALIBRATION_MEASURE_LEFT)
|
||||
SERIAL_ECHOLNPAIR(" Left: ", m.backlash[LEFT]);
|
||||
#endif
|
||||
#if ENABLED(CALIBRATION_MEASURE_RIGHT)
|
||||
SERIAL_ECHOLNPAIR(" Right: ", m.backlash[RIGHT]);
|
||||
#endif
|
||||
#endif
|
||||
#if ENABLED(CALIBRATION_MEASURE_RIGHT)
|
||||
SERIAL_ECHOLNPAIR(" Right: ", m.backlash[RIGHT]);
|
||||
#if AXIS_CAN_CALIBRATE(Y)
|
||||
#if ENABLED(CALIBRATION_MEASURE_FRONT)
|
||||
SERIAL_ECHOLNPAIR(" Front: ", m.backlash[FRONT]);
|
||||
#endif
|
||||
#if ENABLED(CALIBRATION_MEASURE_BACK)
|
||||
SERIAL_ECHOLNPAIR(" Back: ", m.backlash[BACK]);
|
||||
#endif
|
||||
#endif
|
||||
#if ENABLED(CALIBRATION_MEASURE_FRONT)
|
||||
SERIAL_ECHOLNPAIR(" Front: ", m.backlash[FRONT]);
|
||||
#if AXIS_CAN_CALIBRATE(Z)
|
||||
SERIAL_ECHOLNPAIR(" Top: ", m.backlash[TOP]);
|
||||
#endif
|
||||
#if ENABLED(CALIBRATION_MEASURE_BACK)
|
||||
SERIAL_ECHOLNPAIR(" Back: ", m.backlash[BACK]);
|
||||
#endif
|
||||
SERIAL_ECHOLNPAIR(" Top: ", m.backlash[TOP]);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
@@ -369,7 +402,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||
#if HAS_Y_CENTER
|
||||
SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.pos_error.y);
|
||||
#endif
|
||||
SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.pos_error.z);
|
||||
if (AXIS_CAN_CALIBRATE(Z)) SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.pos_error.z);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
@@ -417,6 +450,7 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
||||
probe_sides(m, uncertainty);
|
||||
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
|
||||
#if HAS_X_CENTER
|
||||
backlash.distance_mm.x = (m.backlash[LEFT] + m.backlash[RIGHT]) / 2;
|
||||
#elif ENABLED(CALIBRATION_MEASURE_LEFT)
|
||||
@@ -433,18 +467,18 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
||||
backlash.distance_mm.y = m.backlash[BACK];
|
||||
#endif
|
||||
|
||||
backlash.distance_mm.z = m.backlash[TOP];
|
||||
if (AXIS_CAN_CALIBRATE(Z)) backlash.distance_mm.z = m.backlash[TOP];
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
// Turn on backlash compensation and move in all
|
||||
// directions to take up any backlash
|
||||
// allowed directions to take up any backlash
|
||||
{
|
||||
// New scope for TEMPORARY_BACKLASH_CORRECTION
|
||||
TEMPORARY_BACKLASH_CORRECTION(all_on);
|
||||
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||
const xyz_float_t move = { 3, 3, 3 };
|
||||
const xyz_float_t move = { AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3 };
|
||||
current_position += move; calibration_move();
|
||||
current_position -= move; calibration_move();
|
||||
}
|
||||
@@ -482,26 +516,18 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const
|
||||
|
||||
// Adjust the hotend offset
|
||||
#if HAS_HOTEND_OFFSET
|
||||
#if HAS_X_CENTER
|
||||
hotend_offset[extruder].x += m.pos_error.x;
|
||||
#endif
|
||||
#if HAS_Y_CENTER
|
||||
hotend_offset[extruder].y += m.pos_error.y;
|
||||
#endif
|
||||
hotend_offset[extruder].z += m.pos_error.z;
|
||||
if (ENABLED(HAS_X_CENTER) && AXIS_CAN_CALIBRATE(X)) hotend_offset[extruder].x += m.pos_error.x;
|
||||
if (ENABLED(HAS_Y_CENTER) && AXIS_CAN_CALIBRATE(Y)) hotend_offset[extruder].y += m.pos_error.y;
|
||||
if (AXIS_CAN_CALIBRATE(Z)) hotend_offset[extruder].z += m.pos_error.z;
|
||||
normalize_hotend_offsets();
|
||||
#endif
|
||||
|
||||
// Correct for positional error, so the object
|
||||
// is at the known actual spot
|
||||
planner.synchronize();
|
||||
#if HAS_X_CENTER
|
||||
update_measurements(m, X_AXIS);
|
||||
#endif
|
||||
#if HAS_Y_CENTER
|
||||
update_measurements(m, Y_AXIS);
|
||||
#endif
|
||||
update_measurements(m, Z_AXIS);
|
||||
if (ENABLED(HAS_X_CENTER) && AXIS_CAN_CALIBRATE(X)) update_measurements(m, X_AXIS);
|
||||
if (ENABLED(HAS_Y_CENTER) && AXIS_CAN_CALIBRATE(Y)) update_measurements(m, Y_AXIS);
|
||||
if (AXIS_CAN_CALIBRATE(Z)) update_measurements(m, Z_AXIS);
|
||||
|
||||
sync_plan_position();
|
||||
}
|
||||
|
||||
@@ -103,13 +103,19 @@ void GcodeSuite::G76() {
|
||||
return false;
|
||||
};
|
||||
|
||||
auto g76_probe = [](const xy_pos_t &xypos) {
|
||||
auto g76_probe = [](const TempSensorID sid, uint16_t &targ, const xy_pos_t &nozpos) {
|
||||
do_blocking_move_to_z(5.0); // Raise nozzle before probing
|
||||
const float measured_z = probe.probe_at_point(xypos, PROBE_PT_NONE, 0, false); // verbose=0, probe_relative=false
|
||||
const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_NONE, 0, false); // verbose=0, probe_relative=false
|
||||
if (isnan(measured_z))
|
||||
SERIAL_ECHOLNPGM("!Received NAN. Aborting.");
|
||||
else
|
||||
else {
|
||||
SERIAL_ECHOLNPAIR_F("Measured: ", measured_z);
|
||||
if (targ == cali_info_init[sid].start_temp)
|
||||
temp_comp.prepare_new_calibration(measured_z);
|
||||
else
|
||||
temp_comp.push_back_new_measurement(sid, measured_z);
|
||||
targ += cali_info_init[sid].temp_res;
|
||||
}
|
||||
return measured_z;
|
||||
};
|
||||
|
||||
@@ -125,8 +131,9 @@ void GcodeSuite::G76() {
|
||||
// Synchronize with planner
|
||||
planner.synchronize();
|
||||
|
||||
const xyz_pos_t parkpos = { temp_comp.park_point_x, temp_comp.park_point_y, temp_comp.park_point_z };
|
||||
const xy_pos_t ppos = { temp_comp.measure_point_x, temp_comp.measure_point_y };
|
||||
const xyz_pos_t parkpos = temp_comp.park_point,
|
||||
probe_pos_xyz = temp_comp.measure_point + xyz_pos_t({ 0.0f, 0.0f, 0.5f }),
|
||||
noz_pos_xyz = probe_pos_xyz - probe.offset_xy; // Nozzle position based on probe position
|
||||
|
||||
if (do_bed_cal || do_probe_cal) {
|
||||
// Ensure park position is reachable
|
||||
@@ -135,7 +142,7 @@ void GcodeSuite::G76() {
|
||||
SERIAL_ECHOLNPGM("!Park");
|
||||
else {
|
||||
// Ensure probe position is reachable
|
||||
reachable = probe.can_reach(ppos);
|
||||
reachable = probe.can_reach(probe_pos_xyz);
|
||||
if (!reachable) SERIAL_ECHOLNPGM("!Probe");
|
||||
}
|
||||
|
||||
@@ -149,8 +156,6 @@ void GcodeSuite::G76() {
|
||||
|
||||
remember_feedrate_scaling_off();
|
||||
|
||||
// Nozzle position based on probe position
|
||||
const xy_pos_t noz_pos = ppos - probe.offset_xy;
|
||||
|
||||
/******************************************
|
||||
* Calibrate bed temperature offsets
|
||||
@@ -159,9 +164,13 @@ void GcodeSuite::G76() {
|
||||
// Report temperatures every second and handle heating timeouts
|
||||
millis_t next_temp_report = millis() + 1000;
|
||||
|
||||
auto report_targets = [&](const uint16_t tb, const uint16_t tp) {
|
||||
SERIAL_ECHOLNPAIR("Target Bed:", tb, " Probe:", tp);
|
||||
};
|
||||
|
||||
if (do_bed_cal) {
|
||||
|
||||
uint16_t target_bed = temp_comp.cali_info_init[TSI_BED].start_temp,
|
||||
uint16_t target_bed = cali_info_init[TSI_BED].start_temp,
|
||||
target_probe = temp_comp.bed_calib_probe_temp;
|
||||
|
||||
SERIAL_ECHOLNPGM("Waiting for cooling.");
|
||||
@@ -176,33 +185,25 @@ void GcodeSuite::G76() {
|
||||
for (;;) {
|
||||
thermalManager.setTargetBed(target_bed);
|
||||
|
||||
SERIAL_ECHOLNPAIR("Target Bed:", target_bed, " Probe:", target_probe);
|
||||
report_targets(target_bed, target_probe);
|
||||
|
||||
// Park nozzle
|
||||
do_blocking_move_to(parkpos);
|
||||
|
||||
// Wait for heatbed to reach target temp and probe to cool below target temp
|
||||
if (wait_for_temps(target_bed, target_probe, next_temp_report, millis() + 900UL * 1000UL)) {
|
||||
if (wait_for_temps(target_bed, target_probe, next_temp_report, millis() + MIN_TO_MS(15))) {
|
||||
SERIAL_ECHOLNPGM("!Bed heating timeout.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Move the nozzle to the probing point and wait for the probe to reach target temp
|
||||
do_blocking_move_to_xy(noz_pos);
|
||||
do_blocking_move_to(noz_pos_xyz);
|
||||
SERIAL_ECHOLNPGM("Waiting for probe heating.");
|
||||
while (thermalManager.degProbe() < target_probe)
|
||||
report_temps(next_temp_report);
|
||||
|
||||
const float measured_z = g76_probe(noz_pos);
|
||||
if (isnan(measured_z)) break;
|
||||
|
||||
if (target_bed == temp_comp.cali_info_init[TSI_BED].start_temp)
|
||||
temp_comp.prepare_new_calibration(measured_z);
|
||||
else
|
||||
temp_comp.push_back_new_measurement(TSI_BED, measured_z);
|
||||
|
||||
target_bed += temp_comp.cali_info_init[TSI_BED].temp_res;
|
||||
if (target_bed > temp_comp.max_bed_temp) break;
|
||||
const float measured_z = g76_probe(TSI_BED, target_bed, noz_pos_xyz);
|
||||
if (isnan(measured_z) || target_bed > BED_MAXTEMP - 10) break;
|
||||
}
|
||||
|
||||
SERIAL_ECHOLNPAIR("Retrieved measurements: ", temp_comp.get_index());
|
||||
@@ -231,7 +232,9 @@ void GcodeSuite::G76() {
|
||||
const uint16_t target_bed = temp_comp.probe_calib_bed_temp;
|
||||
thermalManager.setTargetBed(target_bed);
|
||||
|
||||
uint16_t target_probe = temp_comp.cali_info_init[TSI_PROBE].start_temp;
|
||||
uint16_t target_probe = cali_info_init[TSI_PROBE].start_temp;
|
||||
|
||||
report_targets(target_bed, target_probe);
|
||||
|
||||
// Wait for heatbed to reach target temp and probe to cool below target temp
|
||||
wait_for_temps(target_bed, target_probe, next_temp_report);
|
||||
@@ -244,7 +247,7 @@ void GcodeSuite::G76() {
|
||||
bool timeout = false;
|
||||
for (;;) {
|
||||
// Move probe to probing point and wait for it to reach target temperature
|
||||
do_blocking_move_to_xy(noz_pos);
|
||||
do_blocking_move_to(noz_pos_xyz);
|
||||
|
||||
SERIAL_ECHOLNPAIR("Waiting for probe heating. Bed:", target_bed, " Probe:", target_probe);
|
||||
const millis_t probe_timeout_ms = millis() + 900UL * 1000UL;
|
||||
@@ -257,16 +260,8 @@ void GcodeSuite::G76() {
|
||||
}
|
||||
if (timeout) break;
|
||||
|
||||
const float measured_z = g76_probe(noz_pos);
|
||||
if (isnan(measured_z)) break;
|
||||
|
||||
if (target_probe == temp_comp.cali_info_init[TSI_PROBE].start_temp)
|
||||
temp_comp.prepare_new_calibration(measured_z);
|
||||
else
|
||||
temp_comp.push_back_new_measurement(TSI_PROBE, measured_z);
|
||||
|
||||
target_probe += temp_comp.cali_info_init[TSI_PROBE].temp_res;
|
||||
if (target_probe > temp_comp.cali_info_init[TSI_PROBE].end_temp) break;
|
||||
const float measured_z = g76_probe(TSI_PROBE, target_probe, noz_pos_xyz);
|
||||
if (isnan(measured_z) || target_probe > cali_info_init[TSI_PROBE].end_temp) break;
|
||||
}
|
||||
|
||||
SERIAL_ECHOLNPAIR("Retrieved measurements: ", temp_comp.get_index());
|
||||
|
||||
@@ -47,7 +47,7 @@ void GcodeSuite::M425() {
|
||||
bool noArgs = true;
|
||||
|
||||
LOOP_XYZ(a) {
|
||||
if (parser.seen(XYZ_CHAR(a))) {
|
||||
if (CAN_CALIBRATE(a) && parser.seen(XYZ_CHAR(a))) {
|
||||
planner.synchronize();
|
||||
backlash.distance_mm[a] = parser.has_value() ? parser.value_linear_units() : backlash.get_measurement(AxisEnum(a));
|
||||
noArgs = false;
|
||||
@@ -74,7 +74,7 @@ void GcodeSuite::M425() {
|
||||
SERIAL_ECHOLNPGM("active:");
|
||||
SERIAL_ECHOLNPAIR(" Correction Amount/Fade-out: F", backlash.get_correction(), " (F1.0 = full, F0.0 = none)");
|
||||
SERIAL_ECHOPGM(" Backlash Distance (mm): ");
|
||||
LOOP_XYZ(a) {
|
||||
LOOP_XYZ(a) if (CAN_CALIBRATE(a)) {
|
||||
SERIAL_CHAR(' ', XYZ_CHAR(a));
|
||||
SERIAL_ECHO(backlash.distance_mm[a]);
|
||||
SERIAL_EOL();
|
||||
@@ -87,7 +87,7 @@ void GcodeSuite::M425() {
|
||||
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
||||
SERIAL_ECHOPGM(" Average measured backlash (mm):");
|
||||
if (backlash.has_any_measurement()) {
|
||||
LOOP_XYZ(a) if (backlash.has_measurement(AxisEnum(a))) {
|
||||
LOOP_XYZ(a) if (CAN_CALIBRATE(a) && backlash.has_measurement(AxisEnum(a))) {
|
||||
SERIAL_CHAR(' ', XYZ_CHAR(a));
|
||||
SERIAL_ECHO(backlash.get_measurement(AxisEnum(a)));
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
* S<percent> : Set the feed rate percentage factor
|
||||
*
|
||||
* Report the current speed percentage factor if no parameter is specified
|
||||
*
|
||||
*
|
||||
* With PRUSA_MMU2...
|
||||
* B : Flag to back up the current factor
|
||||
* R : Flag to restore the last-saved factor
|
||||
|
||||
@@ -67,7 +67,11 @@ inline void toggle_pins() {
|
||||
else {
|
||||
watchdog_refresh();
|
||||
report_pin_state_extended(pin, ignore_protection, true, PSTR("Pulsing "));
|
||||
const bool prior_mode = GET_PINMODE(pin);
|
||||
#ifdef __STM32F1__
|
||||
const auto prior_mode = _GET_MODE(i);
|
||||
#else
|
||||
const bool prior_mode = GET_PINMODE(pin);
|
||||
#endif
|
||||
#if AVR_AT90USB1286_FAMILY // Teensy IDEs don't know about these pins so must use FASTIO
|
||||
if (pin == TEENSY_E2) {
|
||||
SET_OUTPUT(TEENSY_E2);
|
||||
@@ -96,7 +100,11 @@ inline void toggle_pins() {
|
||||
watchdog_refresh();
|
||||
}
|
||||
}
|
||||
pinMode(pin, prior_mode);
|
||||
#ifdef __STM32F1__
|
||||
_SET_MODE(i, prior_mode);
|
||||
#else
|
||||
pinMode(pin, prior_mode);
|
||||
#endif
|
||||
}
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
#include "../../feature/spindle_laser.h"
|
||||
#include "../../module/stepper.h"
|
||||
|
||||
inline cutter_power_t get_s_power() {
|
||||
return cutter_power_t(
|
||||
parser.intval('S', cutter.interpret_power(SPEED_POWER_STARTUP))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Laser:
|
||||
*
|
||||
@@ -71,29 +77,52 @@
|
||||
*/
|
||||
void GcodeSuite::M3_M4(const bool is_M4) {
|
||||
|
||||
#if ENABLED(SPINDLE_FEATURE)
|
||||
planner.synchronize(); // Wait for movement to complete before changing power
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
if (parser.seen('I') == DISABLED(LASER_POWER_INLINE_INVERT)) {
|
||||
// Laser power in inline mode
|
||||
cutter.inline_direction(is_M4); // Should always be unused
|
||||
|
||||
#if ENABLED(SPINDLE_LASER_PWM)
|
||||
if (parser.seen('O'))
|
||||
cutter.inline_ocr_power(parser.value_byte()); // The OCR is a value from 0 to 255 (uint8_t)
|
||||
else
|
||||
cutter.inline_power(get_s_power());
|
||||
#else
|
||||
cutter.inline_enabled(true);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
// Non-inline, standard case
|
||||
cutter.inline_disable(); // Prevent future blocks re-setting the power
|
||||
#endif
|
||||
|
||||
planner.synchronize(); // Wait for previous movement commands (G0/G0/G2/G3) to complete before changing power
|
||||
|
||||
cutter.set_direction(is_M4);
|
||||
|
||||
#if ENABLED(SPINDLE_LASER_PWM)
|
||||
if (parser.seenval('O'))
|
||||
cutter.set_ocr_power(parser.value_byte()); // The OCR is a value from 0 to 255 (uint8_t)
|
||||
else
|
||||
cutter.set_power(parser.intval('S', 255));
|
||||
cutter.set_power(get_s_power());
|
||||
#else
|
||||
cutter.set_enabled(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* M5 - Cutter OFF
|
||||
* M5 - Cutter OFF (when moves are complete)
|
||||
*/
|
||||
void GcodeSuite::M5() {
|
||||
#if ENABLED(SPINDLE_FEATURE)
|
||||
planner.synchronize();
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
if (parser.seen('I') == DISABLED(LASER_POWER_INLINE_INVERT)) {
|
||||
cutter.inline_enabled(false); // Laser power in inline mode
|
||||
return;
|
||||
}
|
||||
// Non-inline, standard case
|
||||
cutter.inline_disable(); // Prevent future blocks re-setting the power
|
||||
#endif
|
||||
planner.synchronize();
|
||||
cutter.set_enabled(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,14 +48,8 @@
|
||||
|
||||
#ifdef PHOTO_RETRACT_MM
|
||||
inline void e_move_m240(const float length, const feedRate_t &fr_mm_s) {
|
||||
if (length && thermalManager.hotEnoughToExtrude(active_extruder)) {
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
do_pause_e_move(length, fr_mm_s);
|
||||
#else
|
||||
current_position.e += length / planner.e_factor[active_extruder];
|
||||
line_to_current_position(fr_mm_s);
|
||||
#endif
|
||||
}
|
||||
if (length && thermalManager.hotEnoughToExtrude(active_extruder))
|
||||
unscaled_e_move(length, fr_mm_s);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
|
||||
void M710_report(const bool forReplay) {
|
||||
if (!forReplay) { SERIAL_ECHOLNPGM("; Controller Fan"); SERIAL_ECHO_START(); }
|
||||
SERIAL_ECHOLNPAIR("M710 "
|
||||
"S", int(controllerFan.settings.active_speed),
|
||||
"I", int(controllerFan.settings.idle_speed),
|
||||
"A", int(controllerFan.settings.auto_mode),
|
||||
"D", controllerFan.settings.duration,
|
||||
SERIAL_ECHOLNPAIR(" M710"
|
||||
" S", int(controllerFan.settings.active_speed),
|
||||
" I", int(controllerFan.settings.idle_speed),
|
||||
" A", int(controllerFan.settings.auto_mode),
|
||||
" D", controllerFan.settings.duration,
|
||||
" ; (", (int(controllerFan.settings.active_speed) * 100) / 255, "%"
|
||||
" ", (int(controllerFan.settings.idle_speed) * 100) / 255, "%)"
|
||||
);
|
||||
|
||||
@@ -63,7 +63,7 @@ void GcodeSuite::M1000() {
|
||||
#if HAS_LCD_MENU
|
||||
ui.goto_screen(menu_job_recovery);
|
||||
#elif ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::OnPowerLossResume();
|
||||
ExtUI::onPowerLossResume();
|
||||
#else
|
||||
SERIAL_ECHO_MSG("Resume requires LCD.");
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user