Merge branch 'bugfix-2.0.x' into CrealityDwin2.0_Bleeding

This commit is contained in:
InsanityAutomation
2021-05-04 11:08:03 -04:00
356 changed files with 5892 additions and 2366 deletions
+2 -2
View File
@@ -4,10 +4,10 @@ root = true
[{*.patch,syntax_test_*}]
trim_trailing_whitespace = false
[{*.c,*.cpp,*.h}]
[{*.c,*.cpp,*.h,*.ino}]
charset = utf-8
[{*.c,*.cpp,*.h,Makefile}]
[{*.c,*.cpp,*.h,*.ino,Makefile}]
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
+1
View File
@@ -90,6 +90,7 @@ jobs:
- NUCLEO_F767ZI
- REMRAM_V1
- BTT_SKR_SE_BX
- chitu_f103
# Put lengthy tests last
-23
View File
@@ -122,29 +122,6 @@ tags
.gcc-flags.json
/lib/
# Workaround for Deviot+platformio quirks
Marlin/lib
Marlin/platformio.ini
Marlin/*/platformio.ini
Marlin/*/*/platformio.ini
Marlin/*/*/*/platformio.ini
Marlin/*/*/*/*/platformio.ini
Marlin/.travis.yml
Marlin/*/.travis.yml
Marlin/*/*/.travis.yml
Marlin/*/*/*/.travis.yml
Marlin/*/*/*/*/.travis.yml
Marlin/.gitignore
Marlin/*/.gitignore
Marlin/*/*/.gitignore
Marlin/*/*/*/.gitignore
Marlin/*/*/*/*/.gitignore
Marlin/readme.txt
Marlin/*/readme.txt
Marlin/*/*/readme.txt
Marlin/*/*/*/readme.txt
Marlin/*/*/*/*/readme.txt
# Secure Credentials
Configuration_Secure.h
+7
View File
@@ -2486,6 +2486,11 @@
*/
//#define DEBUG_LEVELING_FEATURE
#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL, PROBE_MANUALLY)
// Set a height for the start of manual adjustment
#define MANUAL_PROBE_START_Z 0.2 // (mm) Comment out to use the last-measured height
#endif
#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL)
// Gradually reduce leveling correction until a set height is reached,
// at which point movement will be level to the machine's XY plane.
@@ -2583,6 +2588,8 @@
#define UBL_Z_RAISE_WHEN_OFF_MESH 0 // When the nozzle is off the mesh, this value is used
// as the Z-Height correction value.
//#define UBL_MESH_WIZARD // Run several commands in a row to get a complete mesh
#elif ENABLED(MESH_BED_LEVELING)
//===========================================================================
+79 -11
View File
@@ -1024,6 +1024,9 @@
#define BACKLASH_DISTANCE_MM { 0, 0, 0 } // (mm)
#define BACKLASH_CORRECTION 0.0 // 0.0 = no correction; 1.0 = full correction
// Add steps for motor direction changes on CORE kinematics
//#define CORE_BACKLASH
// Set BACKLASH_SMOOTHING_MM to spread backlash correction over multiple segments
// to reduce print artifacts. (Enabling this is costly in memory and computation!)
//#define BACKLASH_SMOOTHING_MM 3 // (mm)
@@ -1703,6 +1706,31 @@
#endif
#endif // HAS_DGUS_LCD
//
// Additional options for AnyCubic Chiron TFT displays
//
#if ENABLED(ANYCUBIC_LCD_CHIRON)
// By default the type of panel is automatically detected.
// Enable one of these options if you know the panel type.
//#define CHIRON_TFT_STANDARD
//#define CHIRON_TFT_NEW
// Enable the longer Anycubic powerup startup tune
//#define AC_DEFAULT_STARTUP_TUNE
/**
* Display Folders
* By default the file browser lists all G-code files (including those in subfolders) in a flat list.
* Enable this option to display a hierarchical file browser.
*
* NOTES:
* - Without this option it helps to enable SDCARD_SORT_ALPHA so files are sorted before/after folders.
* - When used with the "new" panel, folder names will also have '.gcode' appended to their names.
* This hack is currently required to force the panel to show folders.
*/
#define AC_SD_FOLDER_VIEW
#endif
//
// Specify additional languages for the UI. Default specified by LCD_LANGUAGE.
//
@@ -2223,8 +2251,19 @@
#endif
/**
* Realtime Reporting
* Add support for commands S000 State, P000 Pause, and R000 Resume
* Realtime Reporting (requires EMERGENCY_PARSER)
*
* - Report position and state of the machine (like Grbl).
* - Auto-report position during long moves.
* - Useful for CNC/LASER.
*
* Adds support for commands:
* S000 : Report State and Position while moving.
* P000 : Instant Pause / Hold while moving.
* R000 : Resume from Pause / Hold.
*
* - During Hold all Emergency Parser commands are available, as usual.
* - Enable NANODLP_Z_SYNC and NANODLP_ALL_AXIS for move command end-state reports.
*/
//#define REALTIME_REPORTING_COMMANDS
#if ENABLED(REALTIME_REPORTING_COMMANDS)
@@ -2952,7 +2991,7 @@
/**
* Enable M122 debugging command for TMC stepper drivers.
* M122 S0/1 will enable continous reporting.
* M122 S0/1 will enable continuous reporting.
*/
#if ENABLED(SKR_UART) && DISABLED(SKRMiniE3V2)
#define TMC_DEBUG
@@ -3275,10 +3314,22 @@
#define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR and LPC)
//#define SPINDLE_SERVO // A servo converting an angle to spindle power
//#define AIR_EVACUATION // Cutter Vacuum / Laser Blower motor control with G-codes M10-M11
#if ENABLED(AIR_EVACUATION)
#define AIR_EVACUATION_ACTIVE LOW // Set to "HIGH" if the on/off function is active HIGH
//#define AIR_EVACUATION_PIN 42 // Override the default Cutter Vacuum or Laser Blower pin
#endif
//#define AIR_ASSIST // Air Assist control with G-codes M8-M9
#if ENABLED(AIR_ASSIST)
#define AIR_ASSIST_ACTIVE LOW // Active state on air assist pin
//#define AIR_ASSIST_PIN 44 // Override the default Air Assist pin
#endif
//#define SPINDLE_SERVO // A servo converting an angle to spindle power
#ifdef SPINDLE_SERVO
#define SPINDLE_SERVO_NR 0 // Index of servo used for spindle control
#define SPINDLE_SERVO_MIN 10 // Minimum angle for servo spindle
#define SPINDLE_SERVO_NR 0 // Index of servo used for spindle control
#define SPINDLE_SERVO_MIN 10 // Minimum angle for servo spindle
#endif
/**
@@ -3493,6 +3544,15 @@
#define POWER_MONITOR_VOLTAGE_OFFSET 0 // Offset (in volts) applied to the calculated voltage
#endif
/**
* Stepper Driver Anti-SNAFU Protection
*
* If the SAFE_POWER_PIN is defined for your board, Marlin will check
* that stepper drivers are properly plugged in before applying power.
* Disable protection if your stepper drivers don't support the feature.
*/
//#define DISABLE_DRIVER_SAFE_POWER_PROTECT
/**
* CNC Coordinate Systems
*
@@ -3775,6 +3835,9 @@
#if NONE(MachineCR10Orig, LowMemoryBoard, EXTENSIBLE_UI, SKRMiniE3V2)
#define CANCEL_OBJECTS
#endif
#if ENABLED(CANCEL_OBJECTS)
#define CANCEL_OBJECTS_REPORTING // Emit the current object as a status message
#endif
/**
* I2C position encoders for closed loop control.
@@ -3932,14 +3995,13 @@
/**
* NanoDLP Sync support
*
* Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp"
* string to enable synchronization with DLP projector exposure. This change will allow to use
* [[WaitForDoneMessage]] instead of populating your gcode with M400 commands
* Support for Synchronized Z moves when used with NanoDLP. G0/G1 axis moves will
* output a "Z_move_comp" string to enable synchronization with DLP projector exposure.
* This feature allows you to use [[WaitForDoneMessage]] instead of M400 commands.
*/
//#define NANODLP_Z_SYNC
#if ENABLED(NANODLP_Z_SYNC)
//#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move.
// Default behavior is limited to Z axis only.
//#define NANODLP_ALL_AXIS // Send a "Z_move_comp" report for any axis move (not just Z).
#endif
/**
@@ -4116,3 +4178,9 @@
* a crash from a remote location. Requires ~400 bytes of SRAM and 5Kb of flash.
*/
//#define POSTMORTEM_DEBUGGING
/**
* Software Reset options
*/
//#define SOFT_RESET_VIA_SERIAL // 'KILL' and '^X' commands will soft-reset the controller
//#define SOFT_RESET_ON_KILL // Use a digital button to soft-reset the controller after KILL
+1 -1
View File
@@ -993,5 +993,5 @@ clean:
.PHONY: all build elf hex eep lss sym program coff extcoff clean depend sizebefore sizeafter
# Automaticaly include the dependency files created by gcc
# Automatically include the dependency files created by gcc
-include ${patsubst %.o, %.d, ${OBJ}}
+9
View File
@@ -58,6 +58,15 @@ void HAL_init() {
#endif
}
void HAL_reboot() {
#if ENABLED(USE_WATCHDOG)
while (1) { /* run out the watchdog */ }
#else
void (*resetFunc)() = 0; // Declare resetFunc() at address 0
resetFunc(); // Jump to address 0
#endif
}
#if ENABLED(SDSUPPORT)
#include "../../sd/SdFatUtil.h"
+5 -5
View File
@@ -93,13 +93,13 @@ typedef int8_t pin_t;
#define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0)
#else
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#error "SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#define MYSERIAL1 customizedSerial1
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#define MYSERIAL2 customizedSerial2
#endif
@@ -107,14 +107,14 @@ typedef int8_t pin_t;
#ifdef MMU2_SERIAL_PORT
#if !WITHIN(MMU2_SERIAL_PORT, -1, 3)
#error "MMU2_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#error "MMU2_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#define MMU2_SERIAL mmuSerial
#endif
#ifdef LCD_SERIAL_PORT
#if !WITHIN(LCD_SERIAL_PORT, -1, 3)
#error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#define LCD_SERIAL lcdSerial
#if HAS_DGUS_LCD
@@ -135,7 +135,7 @@ void HAL_init();
inline void HAL_clear_reset_source() { MCUSR = 0; }
inline uint8_t HAL_get_reset_source() { return MCUSR; }
inline void HAL_reboot() {} // reboot the board or restart the bootloader
void HAL_reboot();
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
+2
View File
@@ -77,6 +77,8 @@ uint8_t HAL_get_reset_source() {
}
}
void HAL_reboot() { rstc_start_software_reset(RSTC); }
void _delay_ms(const int delay_ms) {
// Todo: port for Due?
delay(delay_ms);
+5 -5
View File
@@ -56,7 +56,7 @@ extern DefaultSerial4 MSerial3;
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "The required SERIAL_PORT must be from -1 to 3. Please update your configuration."
#error "The required SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#ifdef SERIAL_PORT_2
@@ -65,7 +65,7 @@ extern DefaultSerial4 MSerial3;
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
@@ -73,7 +73,7 @@ extern DefaultSerial4 MSerial3;
#if WITHIN(MMU2_SERIAL_PORT, 0, 3)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
#error "MMU2_SERIAL_PORT must be from 0 to 3. Please update your configuration."
#error "MMU2_SERIAL_PORT must be from 0 to 3."
#endif
#endif
@@ -83,7 +83,7 @@ extern DefaultSerial4 MSerial3;
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
#error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
@@ -113,7 +113,7 @@ void sei(); // Enable interrupts
void HAL_clear_reset_source(); // clear reset reason
uint8_t HAL_get_reset_source(); // get reset reason
inline void HAL_reboot() {} // reboot the board or restart the bootloader
void HAL_reboot();
//
// ADC
+2
View File
@@ -141,6 +141,8 @@ void HAL_clear_reset_source() { }
uint8_t HAL_get_reset_source() { return rtc_get_reset_reason(1); }
void HAL_reboot() { ESP.restart(); }
void _delay_ms(int delay_ms) { delay(delay_ms); }
// return free memory between end of heap (or end bss) and whatever is current
+1 -1
View File
@@ -101,7 +101,7 @@ void HAL_clear_reset_source();
// reset reason
uint8_t HAL_get_reset_source();
inline void HAL_reboot() {} // reboot the board or restart the bootloader
void HAL_reboot();
void _delay_ms(int delay);
+2
View File
@@ -73,4 +73,6 @@ void HAL_pwm_init() {
}
void HAL_reboot() { /* Reset the application state and GPIO */ }
#endif // __PLAT_LINUX__
+1 -1
View File
@@ -107,7 +107,7 @@ uint16_t HAL_adc_get_result();
inline void HAL_clear_reset_source(void) {}
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
inline void HAL_reboot() {} // reboot the board or restart the bootloader
void HAL_reboot(); // Reset the application state and GPIO
/* ---------------- Delay in cycles */
FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {
+3 -1
View File
@@ -67,7 +67,7 @@ void flashFirmware(const int16_t) {
delay(500); // Give OS time to disconnect
USB_Connect(false); // USB clear connection
delay(1000); // Give OS time to notice
NVIC_SystemReset();
HAL_reboot();
}
void HAL_clear_reset_source(void) {
@@ -81,4 +81,6 @@ uint8_t HAL_get_reset_source(void) {
return RST_POWER_ON;
}
void HAL_reboot() { NVIC_SystemReset(); }
#endif // TARGET_LPC1768
+5 -5
View File
@@ -71,7 +71,7 @@ extern DefaultSerial1 USBSerial;
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#error "SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#ifdef SERIAL_PORT_2
@@ -80,7 +80,7 @@ extern DefaultSerial1 USBSerial;
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
@@ -90,7 +90,7 @@ extern DefaultSerial1 USBSerial;
#elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
#error "MMU2_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#error "MMU2_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
@@ -100,7 +100,7 @@ extern DefaultSerial1 USBSerial;
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
#error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#if HAS_DGUS_LCD
#define SERIAL_GET_TX_BUFFER_FREE() MSerial0.available()
@@ -218,4 +218,4 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255,
void HAL_clear_reset_source(void);
uint8_t HAL_get_reset_source(void);
inline void HAL_reboot() {} // reboot the board or restart the bootloader
void HAL_reboot();
+1 -1
View File
@@ -117,7 +117,7 @@ void HAL_init() {
PinCfg.Pinmode = 2; // no pull-up/pull-down
PINSEL_ConfigPin(&PinCfg);
// now set CLKOUT_EN bit
LPC_SC->CLKOUTCFG |= (1<<8);
SBI(LPC_SC->CLKOUTCFG, 8);
#endif
USB_Init(); // USB Initialization
+2
View File
@@ -436,6 +436,8 @@ uint8_t HAL_get_reset_source() {
}
#pragma pop_macro("WDT")
void HAL_reboot() { NVIC_SystemReset(); }
extern "C" {
void * _sbrk(int incr);
+5 -5
View File
@@ -54,7 +54,7 @@
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#error "SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#ifdef SERIAL_PORT_2
@@ -63,7 +63,7 @@
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
@@ -73,7 +73,7 @@
#elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
#error "MMU2_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#error "MMU2_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
@@ -83,7 +83,7 @@
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
#error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
@@ -109,7 +109,7 @@ typedef int8_t pin_t;
void HAL_clear_reset_source(); // clear reset reason
uint8_t HAL_get_reset_source(); // get reset reason
inline void HAL_reboot() {} // reboot the board or restart the bootloader
void HAL_reboot();
//
// ADC
+4 -2
View File
@@ -133,6 +133,8 @@ uint8_t HAL_get_reset_source() {
;
}
void HAL_reboot() { NVIC_SystemReset(); }
void _delay_ms(const int delay_ms) { delay(delay_ms); }
extern "C" {
@@ -147,8 +149,8 @@ extern "C" {
void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRead(adc_pin); }
uint16_t HAL_adc_get_result() { return HAL_adc_result; }
// Reset the system (to initiate a firmware flash)
void flashFirmware(const int16_t) { NVIC_SystemReset(); }
// Reset the system to initiate a firmware flash
void flashFirmware(const int16_t) { HAL_reboot(); }
// Maple Compatibility
volatile uint32_t systick_uptime_millis = 0;
+5 -5
View File
@@ -55,7 +55,7 @@
#elif WITHIN(SERIAL_PORT, 1, 6)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
#error "SERIAL_PORT must be from 1 to 6. You can also use -1 if the board supports Native USB."
#endif
#ifdef SERIAL_PORT_2
@@ -64,7 +64,7 @@
#elif WITHIN(SERIAL_PORT_2, 1, 6)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be -1 or from 1 to 6. Please update your configuration."
#error "SERIAL_PORT_2 must be from 1 to 6. You can also use -1 if the board supports Native USB."
#endif
#endif
@@ -74,7 +74,7 @@
#elif WITHIN(MMU2_SERIAL_PORT, 1, 6)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
#error "MMU2_SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
#error "MMU2_SERIAL_PORT must be from 1 to 6. You can also use -1 if the board supports Native USB."
#endif
#endif
@@ -84,7 +84,7 @@
#elif WITHIN(LCD_SERIAL_PORT, 1, 6)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
#error "LCD_SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
#error "LCD_SERIAL_PORT must be from 1 to 6. You can also use -1 if the board supports Native USB."
#endif
#if HAS_DGUS_LCD
#define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite()
@@ -144,7 +144,7 @@ void HAL_clear_reset_source();
// Reset reason
uint8_t HAL_get_reset_source();
inline void HAL_reboot() {} // reboot the board or restart the bootloader
void HAL_reboot();
void _delay_ms(const int delay);
+2 -2
View File
@@ -71,8 +71,8 @@ static void TXBegin() {
volatile uint32_t ICER[32];
};
NVICMin * nvicBase = (NVICMin*)0xE000E100;
nvicBase->ICER[nvicIndex / 32] |= _BV32(nvicIndex % 32);
NVICMin *nvicBase = (NVICMin*)0xE000E100;
SBI32(nvicBase->ICER[nvicIndex >> 5], nvicIndex & 0x1F);
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
+1 -1
View File
@@ -38,7 +38,7 @@ public:
return &card.media_usbFlashDrive;
#endif
#else
return diskIODriver();
return card.diskIODriver();
#endif
}
+11 -14
View File
@@ -45,7 +45,6 @@
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command) {
__IO uint32_t tmpmrd =0;
@@ -192,7 +191,7 @@ void LTDC_Config() {
hltdc_F.Instance = LTDC;
/* Layer0 Configuration ------------------------------------------------------*/
/* Layer0 Configuration ------------------------------------------------------*/
/* Windowing configuration */
pLayerCfg.WindowX0 = 0;
@@ -289,22 +288,21 @@ void TFT_LTDC::DrawRect(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint
uint16_t offline = TFT_WIDTH - (ex - sx);
uint32_t addr = (uint32_t)&framebuffer[(TFT_WIDTH * sy) + sx];
DMA2D->CR &= ~(1 << 0);
CBI(DMA2D->CR, 0);
DMA2D->CR = 3 << 16;
DMA2D->OPFCCR = 0X02;
DMA2D->OOR = offline;
DMA2D->OMAR = addr;
DMA2D->NLR = (ey - sy) | ((ex - sx) << 16);
DMA2D->OCOLR = color;
DMA2D->CR |= 1<<0;
SBI(DMA2D->CR, 0);
uint32_t timeout = 0;
while((DMA2D->ISR & (1<<1)) == 0)
{
while (!TEST(DMA2D->ISR, 1)) {
timeout++;
if(timeout>0X1FFFFF)break;
if (timeout > 0x1FFFFF) break;
}
DMA2D->IFCR |= 1<<1;
SBI(DMA2D->IFCR, 1);
}
void TFT_LTDC::DrawImage(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *colors) {
@@ -314,7 +312,7 @@ void TFT_LTDC::DrawImage(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uin
uint16_t offline = TFT_WIDTH - (ex - sx);
uint32_t addr = (uint32_t)&framebuffer[(TFT_WIDTH * sy) + sx];
DMA2D->CR &= ~(1 << 0);
CBI(DMA2D->CR, 0)
DMA2D->CR = 0 << 16;
DMA2D->FGPFCCR = 0X02;
DMA2D->FGOR = 0;
@@ -322,15 +320,14 @@ void TFT_LTDC::DrawImage(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uin
DMA2D->FGMAR = (uint32_t)colors;
DMA2D->OMAR = addr;
DMA2D->NLR = (ey - sy) | ((ex - sx) << 16);
DMA2D->CR |= 1<<0;
SBI(DMA2D->CR, 0);
uint32_t timeout = 0;
while((DMA2D->ISR & (1<<1)) == 0)
{
while (!TEST(DMA2D->ISR, 1)) {
timeout++;
if(timeout>0X1FFFFF)break;
if (timeout > 0x1FFFFF) break;
}
DMA2D->IFCR |= 1<<1;
SBI(DMA2D->IFCR, 1);
}
void TFT_LTDC::WriteData(uint16_t data) {
+1 -1
View File
@@ -110,7 +110,7 @@ uint8_t BulkStorage::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t bl
}
uint8_t BulkStorage::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t * buf) {
return USBH_MSC_Write(&hUsbHost, lun, addr, const_cast <uint8_t*>(buf), blocks) != USBH_OK;
return USBH_MSC_Write(&hUsbHost, lun, addr, const_cast<uint8_t*>(buf), blocks) != USBH_OK;
}
#endif // USE_OTG_USB_HOST && USBHOST
+3 -1
View File
@@ -453,6 +453,8 @@ void analogWrite(pin_t pin, int pwm_val8) {
analogWrite(uint8_t(pin), pwm_val8);
}
void flashFirmware(const int16_t) { nvic_sys_reset(); }
void HAL_reboot() { nvic_sys_reset(); }
void flashFirmware(const int16_t) { HAL_reboot(); }
#endif // __STM32F1__
+9 -9
View File
@@ -87,9 +87,9 @@
#else
#define MYSERIAL1 MSERIAL(1) // dummy port
#if NUM_UARTS == 5
#error "SERIAL_PORT must be -1 or from 1 to 5. Please update your configuration."
#error "SERIAL_PORT must be from 1 to 5. You can also use -1 if the board supports Native USB."
#else
#error "SERIAL_PORT must be -1 or from 1 to 3. Please update your configuration."
#error "SERIAL_PORT must be from 1 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
@@ -101,9 +101,9 @@
#else
#define MYSERIAL2 MSERIAL(1) // dummy port
#if NUM_UARTS == 5
#error "SERIAL_PORT_2 must be -1 or from 1 to 5. Please update your configuration."
#error "SERIAL_PORT_2 must be from 1 to 5. You can also use -1 if the board supports Native USB."
#else
#error "SERIAL_PORT_2 must be -1 or from 1 to 3. Please update your configuration."
#error "SERIAL_PORT_2 must be from 1 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
#endif
@@ -116,9 +116,9 @@
#else
#define MMU2_SERIAL MSERIAL(1) // dummy port
#if NUM_UARTS == 5
#error "MMU2_SERIAL_PORT must be -1 or from 1 to 5. Please update your configuration."
#error "MMU2_SERIAL_PORT must be from 1 to 5. You can also use -1 if the board supports Native USB."
#else
#error "MMU2_SERIAL_PORT must be -1 or from 1 to 3. Please update your configuration."
#error "MMU2_SERIAL_PORT must be from 1 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
#endif
@@ -131,9 +131,9 @@
#else
#define LCD_SERIAL MSERIAL(1) // dummy port
#if NUM_UARTS == 5
#error "LCD_SERIAL_PORT must be -1 or from 1 to 5. Please update your configuration."
#error "LCD_SERIAL_PORT must be from 1 to 5. You can also use -1 if the board supports Native USB."
#else
#error "LCD_SERIAL_PORT must be -1 or from 1 to 3. Please update your configuration."
#error "LCD_SERIAL_PORT must be from 1 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
#if HAS_DGUS_LCD
@@ -207,7 +207,7 @@ void HAL_clear_reset_source();
// Reset reason
uint8_t HAL_get_reset_source();
inline void HAL_reboot() {} // reboot the board or restart the bootloader
void HAL_reboot();
void _delay_ms(const int delay);
+1 -1
View File
@@ -55,7 +55,7 @@ static void TXBegin() {
nvic_irq_disable(dev->irq_num);
// Use this if removing libmaple
//NVIC_BASE->ICER[1] |= _BV(irq - 32);
//SBI(NVIC_BASE->ICER[1], irq - 32);
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
+1 -1
View File
@@ -60,7 +60,7 @@ static inline __always_inline void my_usart_irq(ring_buffer *rb, ring_buffer *wb
}
else if (srflags & USART_SR_ORE) {
// overrun and empty data, just do a dummy read to clear ORE
// and prevent a raise condition where a continous interrupt stream (due to ORE set) occurs
// and prevent a raise condition where a continuous interrupt stream (due to ORE set) occurs
// (see chapter "Overrun error" ) in STM32 reference manual
regs->DR;
}
+4
View File
@@ -35,6 +35,8 @@
#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X)
#if WITHIN(SERIAL_PORT, 0, 3)
IMPLEMENT_SERIAL(SERIAL_PORT);
#else
#error "SERIAL_PORT must be from 0 to 3."
#endif
USBSerialType USBSerial(false, SerialUSB);
@@ -76,6 +78,8 @@ uint8_t HAL_get_reset_source() {
return 0;
}
void HAL_reboot() { _reboot_Teensyduino_(); }
extern "C" {
extern char __bss_end;
extern char __heap_start;
+1 -2
View File
@@ -34,7 +34,6 @@
#include "fastio.h"
#include "watchdog.h"
#include <stdint.h>
#define ST7920_DELAY_1 DELAY_NS(600)
@@ -93,7 +92,7 @@ void HAL_clear_reset_source();
// Get the reason for the reset
uint8_t HAL_get_reset_source();
inline void HAL_reboot() {} // reboot the board or restart the bootloader
void HAL_reboot();
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
+2
View File
@@ -86,6 +86,8 @@ uint8_t HAL_get_reset_source() {
return 0;
}
void HAL_reboot() { _reboot_Teensyduino_(); }
extern "C" {
extern char __bss_end;
extern char __heap_start;
+3 -1
View File
@@ -72,6 +72,8 @@ extern USBSerialType USBSerial;
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
DECLARE_SERIAL(SERIAL_PORT);
#else
#error "SERIAL_PORT must be from 0 to 3, or -1 for Native USB."
#endif
#define HAL_SERVO_LIB libServo
@@ -99,7 +101,7 @@ void HAL_clear_reset_source();
// Reset reason
uint8_t HAL_get_reset_source();
inline void HAL_reboot() {} // reboot the board or restart the bootloader
void HAL_reboot();
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
+2
View File
@@ -120,6 +120,8 @@ uint8_t HAL_get_reset_source() {
return 0;
}
void HAL_reboot() { _reboot_Teensyduino_(); }
#define __bss_end _ebss
extern "C" {
+4 -2
View File
@@ -74,7 +74,7 @@ extern USBSerialType USBSerial;
DECLARE_SERIAL(SERIAL_PORT);
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "The required SERIAL_PORT must be from -1 to 8. Please update your configuration."
#error "The required SERIAL_PORT must be from 0 to 8, or -1 for Native USB."
#endif
#ifdef SERIAL_PORT_2
@@ -85,7 +85,7 @@ extern USBSerialType USBSerial;
#elif WITHIN(SERIAL_PORT_2, 0, 8)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -2 to 8. Please update your configuration."
#error "SERIAL_PORT_2 must be from 0 to 8, or -1 for Native USB, or -2 for Ethernet."
#endif
#endif
@@ -121,6 +121,8 @@ void HAL_clear_reset_source();
// Reset reason
uint8_t HAL_get_reset_source();
void HAL_reboot();
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
#if GCC_VERSION <= 50000
+40 -11
View File
@@ -232,6 +232,10 @@
#include "lcd/extui/lib/dgus/DGUSScreenHandler.h"
#endif
#if HAS_DRIVER_SAFE_POWER_PROTECT
#include "feature/stepper_driver_safety.h"
#endif
PGMSTR(M112_KILL_STR, "M112 Shutdown");
MarlinState marlin_state = MF_INITIALIZING;
@@ -453,7 +457,8 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
already_shutdown_steppers = false;
}
#if PIN_EXISTS(CHDK) // Check if pin should be set to LOW (after M240 set it HIGH)
#if ENABLED(PHOTO_GCODE) && PIN_EXISTS(CHDK)
// Check if CHDK should be set to LOW (after M240 set it HIGH)
extern millis_t chdk_timeout;
if (chdk_timeout && ELAPSED(ms, chdk_timeout)) {
chdk_timeout = 0;
@@ -599,7 +604,7 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
TERN_(HOTEND_IDLE_TIMEOUT, hotend_idle.check());
#if ENABLED(EXTRUDER_RUNOUT_PREVENT)
if (thermalManager.degHotend(active_extruder) > EXTRUDER_RUNOUT_MINTEMP
if (thermalManager.degHotend(active_extruder) > (EXTRUDER_RUNOUT_MINTEMP)
&& ELAPSED(ms, gcode.previous_move_ms + SEC_TO_MS(EXTRUDER_RUNOUT_SECONDS))
&& !planner.has_blocks_queued()
) {
@@ -862,20 +867,22 @@ void minkill(const bool steppers_off/*=false*/) {
TERN_(HAS_SUICIDE, suicide());
#if HAS_KILL
#if EITHER(HAS_KILL, SOFT_RESET_ON_KILL)
// Wait for kill to be released
while (kill_state()) watchdog_refresh();
// Wait for both KILL and ENC to be released
while (TERN0(HAS_KILL, !kill_state()) || TERN0(SOFT_RESET_ON_KILL, !ui.button_pressed()))
watchdog_refresh();
// Wait for kill to be pressed
while (!kill_state()) watchdog_refresh();
// Wait for either KILL or ENC press
while (TERN1(HAS_KILL, kill_state()) && TERN1(SOFT_RESET_ON_KILL, ui.button_pressed()))
watchdog_refresh();
void (*resetFunc)() = 0; // Declare resetFunc() at address 0
resetFunc(); // Jump to address 0
// Reboot the board
HAL_reboot();
#else
for (;;) watchdog_refresh(); // Wait for reset
for (;;) watchdog_refresh(); // Wait for RESET button or power-cycle
#endif
}
@@ -1213,12 +1220,22 @@ void setup() {
DWIN_UpdateLCD(); // Show bootscreen (first image)
#else
SETUP_RUN(ui.init());
#if HAS_WIRED_LCD && ENABLED(SHOW_BOOTSCREEN)
#if BOTH(HAS_WIRED_LCD, SHOW_BOOTSCREEN)
SETUP_RUN(ui.show_bootscreen());
const millis_t bootscreen_ms = millis();
#endif
SETUP_RUN(ui.reset_status()); // Load welcome message early. (Retained if no errors exist.)
#endif
#if PIN_EXISTS(SAFE_POWER)
#if HAS_DRIVER_SAFE_POWER_PROTECT
SETUP_RUN(stepper_driver_backward_check());
#else
SETUP_LOG("SAFE_POWER");
OUT_WRITE(SAFE_POWER_PIN, HIGH);
#endif
#endif
#if ENABLED(PROBE_TARE)
SETUP_RUN(probe.tare_init());
#endif
@@ -1463,6 +1480,10 @@ void setup() {
SETUP_RUN(test_tmc_connection(true, true, true, true));
#endif
#if HAS_DRIVER_SAFE_POWER_PROTECT
SETUP_RUN(stepper_driver_backward_report());
#endif
#if HAS_PRUSA_MMU2
SETUP_RUN(mmu2.init());
#endif
@@ -1500,6 +1521,14 @@ void setup() {
SETUP_RUN(tft_lvgl_init());
#endif
#if BOTH(HAS_WIRED_LCD, SHOW_BOOTSCREEN)
const millis_t elapsed = millis() - bootscreen_ms;
#if ENABLED(MARLIN_DEV_MODE)
SERIAL_ECHOLNPAIR("elapsed=", elapsed);
#endif
SETUP_RUN(ui.bootscreen_completion(elapsed));
#endif
#if ENABLED(PASSWORD_ON_STARTUP)
SETUP_RUN(password.lock_machine()); // Will not proceed until correct password provided
#endif
+20 -18
View File
@@ -363,24 +363,26 @@
#define BOARD_BLACK_STM32F407VE 4204 // BLACK_STM32F407VE
#define BOARD_BLACK_STM32F407ZE 4205 // BLACK_STM32F407ZE
#define BOARD_STEVAL_3DP001V1 4206 // STEVAL-3DP001V1 3D PRINTER BOARD
#define BOARD_BTT_SKR_PRO_V1_1 4207 // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
#define BOARD_BTT_SKR_PRO_V1_2 4208 // BigTreeTech SKR Pro v1.2 (STM32F407ZG)
#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_S 4212 // Lerdge S (STM32F407VE)
#define BOARD_LERDGE_X 4213 // Lerdge X (STM32F407VE)
#define BOARD_VAKE403D 4214 // VAkE 403D (STM32F446VET6)
#define BOARD_FYSETC_S6 4215 // FYSETC S6 (STM32F446VET6)
#define BOARD_FYSETC_S6_V2_0 4216 // FYSETC S6 v2.0 (STM32F446VET6)
#define BOARD_FYSETC_SPIDER 4217 // FYSETC Spider (STM32F446VET6)
#define BOARD_FLYF407ZG 4218 // FLYF407ZG (STM32F407ZG)
#define BOARD_MKS_ROBIN2 4219 // MKS_ROBIN2 (STM32F407ZE)
#define BOARD_MKS_ROBIN_PRO_V2 4220 // MKS Robin Pro V2 (STM32F407VE)
#define BOARD_MKS_ROBIN_NANO_V3 4221 // MKS Robin Nano V3 (STM32F407VG)
#define BOARD_ANET_ET4 4222 // ANET ET4 V1.x (STM32F407VGT6)
#define BOARD_ANET_ET4P 4223 // ANET ET4P V1.x (STM32F407VGT6)
#define BOARD_FYSETC_CHEETAH_V20 4224 // FYSETC Cheetah V2.0
#define BOARD_BTT_SKR_PRO_V1_1 4207 // BigTreeTech SKR Pro v1.1 (STM32F407ZGT6)
#define BOARD_BTT_SKR_PRO_V1_2 4208 // BigTreeTech SKR Pro v1.2 (STM32F407ZGT6)
#define BOARD_BTT_BTT002_V1_0 4209 // BigTreeTech BTT002 v1.0 (STM32F407VGT6)
#define BOARD_BTT_E3_RRF 4210 // BigTreeTech E3 RRF (STM32F407VGT6)
#define BOARD_BTT_SKR_V2_0 4211 // BigTreeTech SKR v2.0 (STM32F407VGT6)
#define BOARD_BTT_GTR_V1_0 4212 // BigTreeTech GTR v1.0 (STM32F407IGT)
#define BOARD_LERDGE_K 4213 // Lerdge K (STM32F407ZG)
#define BOARD_LERDGE_S 4214 // Lerdge S (STM32F407VE)
#define BOARD_LERDGE_X 4215 // Lerdge X (STM32F407VE)
#define BOARD_VAKE403D 4216 // VAkE 403D (STM32F446VET6)
#define BOARD_FYSETC_S6 4217 // FYSETC S6 (STM32F446VET6)
#define BOARD_FYSETC_S6_V2_0 4218 // FYSETC S6 v2.0 (STM32F446VET6)
#define BOARD_FYSETC_SPIDER 4219 // FYSETC Spider (STM32F446VET6)
#define BOARD_FLYF407ZG 4220 // FLYF407ZG (STM32F407ZG)
#define BOARD_MKS_ROBIN2 4221 // MKS_ROBIN2 (STM32F407ZE)
#define BOARD_MKS_ROBIN_PRO_V2 4222 // MKS Robin Pro V2 (STM32F407VE)
#define BOARD_MKS_ROBIN_NANO_V3 4223 // MKS Robin Nano V3 (STM32F407VG)
#define BOARD_ANET_ET4 4224 // ANET ET4 V1.x (STM32F407VGT6)
#define BOARD_ANET_ET4P 4225 // ANET ET4P V1.x (STM32F407VGT6)
#define BOARD_FYSETC_CHEETAH_V20 4226 // FYSETC Cheetah V2.0
//
// ARM Cortex M7
+11 -9
View File
@@ -77,6 +77,7 @@ typedef float feedRate_t;
// For more resolition (e.g., for a chocolate printer) this may later be changed to Celsius x 100
//
typedef int16_t celsius_t;
typedef float celsius_float_t;
//
// On AVR pointers are only 2 bytes so use 'const float &' for 'const float'
@@ -87,17 +88,18 @@ typedef int16_t celsius_t;
typedef const float const_float_t;
#endif
typedef const_float_t const_feedRate_t;
typedef const_float_t const_celsius_float_t;
// Conversion macros
#define MMM_TO_MMS(MM_M) feedRate_t(float(MM_M) / 60.0f)
#define MMS_TO_MMM(MM_S) (float(MM_S) * 60.0f)
#define MMM_TO_MMS(MM_M) feedRate_t(static_cast<float>(MM_M) / 60.0f)
#define MMS_TO_MMM(MM_S) (static_cast<float>(MM_S) * 60.0f)
//
// Coordinates structures for XY, XYZ, XYZE...
//
// Helpers
#define _RECIP(N) ((N) ? 1.0f / float(N) : 0.0f)
#define _RECIP(N) ((N) ? 1.0f / static_cast<float>(N) : 0.0f)
#define _ABS(N) ((N) < 0 ? -(N) : (N))
#define _LS(N) (N = (T)(uint32_t(N) << v))
#define _RS(N) (N = (T)(uint32_t(N) >> v))
@@ -214,8 +216,8 @@ struct XYval {
FI XYval<int32_t> asLong() const { return { int32_t(x), int32_t(y) }; }
FI XYval<int32_t> ROUNDL() { return { int32_t(LROUND(x)), int32_t(LROUND(y)) }; }
FI XYval<int32_t> ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)) }; }
FI XYval<float> asFloat() { return { float(x), float(y) }; }
FI XYval<float> asFloat() const { return { float(x), float(y) }; }
FI XYval<float> asFloat() { return { static_cast<float>(x), static_cast<float>(y) }; }
FI XYval<float> asFloat() const { return { static_cast<float>(x), static_cast<float>(y) }; }
FI XYval<float> reciprocal() const { return { _RECIP(x), _RECIP(y) }; }
FI XYval<float> asLogical() const { XYval<float> o = asFloat(); toLogical(o); return o; }
FI XYval<float> asNative() const { XYval<float> o = asFloat(); toNative(o); return o; }
@@ -325,8 +327,8 @@ struct XYZval {
FI XYZval<int32_t> asLong() const { return { int32_t(x), int32_t(y), int32_t(z) }; }
FI XYZval<int32_t> ROUNDL() { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)) }; }
FI XYZval<int32_t> ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)) }; }
FI XYZval<float> asFloat() { return { float(x), float(y), float(z) }; }
FI XYZval<float> asFloat() const { return { float(x), float(y), float(z) }; }
FI XYZval<float> asFloat() { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) }; }
FI XYZval<float> asFloat() const { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) }; }
FI XYZval<float> reciprocal() const { return { _RECIP(x), _RECIP(y), _RECIP(z) }; }
FI XYZval<float> asLogical() const { XYZval<float> o = asFloat(); toLogical(o); return o; }
FI XYZval<float> asNative() const { XYZval<float> o = asFloat(); toNative(o); return o; }
@@ -436,8 +438,8 @@ struct XYZEval {
FI XYZEval<int32_t> asLong() const { return { int32_t(x), int32_t(y), int32_t(z), int32_t(e) }; }
FI XYZEval<int32_t> ROUNDL() { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(e)) }; }
FI XYZEval<int32_t> ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(e)) }; }
FI XYZEval<float> asFloat() { return { float(x), float(y), float(z), float(e) }; }
FI XYZEval<float> asFloat() const { return { float(x), float(y), float(z), float(e) }; }
FI XYZEval<float> asFloat() { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(e) }; }
FI XYZEval<float> asFloat() const { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(e) }; }
FI XYZEval<float> reciprocal() const { return { _RECIP(x), _RECIP(y), _RECIP(z), _RECIP(e) }; }
FI XYZEval<float> asLogical() const { XYZEval<float> o = asFloat(); toLogical(o); return o; }
FI XYZEval<float> asNative() const { XYZEval<float> o = asFloat(); toNative(o); return o; }
+1 -2
View File
@@ -25,8 +25,7 @@
#include "../core/types.h"
#include "../core/millis_t.h"
// Delay that ensures heaters and watchdog are kept alive
void safe_delay(millis_t ms);
void safe_delay(millis_t ms); // Delay ensuring that temperatures are updated and the watchdog is kept alive.
#if ENABLED(SERIAL_OVERRUN_PROTECTION)
void serial_delay(const millis_t ms);
+39 -8
View File
@@ -63,10 +63,24 @@ Backlash backlash;
void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const uint8_t dm, block_t * const block) {
static uint8_t last_direction_bits;
uint8_t changed_dir = last_direction_bits ^ dm;
// Ignore direction change if no steps are taken in that direction
if (da == 0) CBI(changed_dir, X_AXIS);
if (db == 0) CBI(changed_dir, Y_AXIS);
if (dc == 0) CBI(changed_dir, Z_AXIS);
// Ignore direction change unless steps are taken in that direction
#if DISABLED(CORE_BACKLASH) || ENABLED(MARKFORGED_XY)
if (!da) CBI(changed_dir, X_AXIS);
if (!db) CBI(changed_dir, Y_AXIS);
if (!dc) CBI(changed_dir, Z_AXIS);
#elif CORE_IS_XY
if (!(da + db)) CBI(changed_dir, X_AXIS);
if (!(da - db)) CBI(changed_dir, Y_AXIS);
if (!dc) CBI(changed_dir, Z_AXIS);
#elif CORE_IS_XZ
if (!(da + dc)) CBI(changed_dir, X_AXIS);
if (!(da - dc)) CBI(changed_dir, Z_AXIS);
if (!db) CBI(changed_dir, Y_AXIS);
#elif CORE_IS_YZ
if (!(db + dc)) CBI(changed_dir, Y_AXIS);
if (!(db - dc)) CBI(changed_dir, Z_AXIS);
if (!da) CBI(changed_dir, X_AXIS);
#endif
last_direction_bits ^= changed_dir;
if (correction == 0) return;
@@ -105,18 +119,35 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const
// Take up a portion of the residual_error in this segment, but only when
// the current segment travels in the same direction as the correction
if (reversing == (error_correction < 0)) {
if (segment_proportion == 0)
segment_proportion = _MIN(1.0f, block->millimeters / smoothing_mm);
if (segment_proportion == 0) segment_proportion = _MIN(1.0f, block->millimeters / smoothing_mm);
error_correction = CEIL(segment_proportion * error_correction);
}
else
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 adds block steps
// This correction reduces the residual error and adds block steps
if (error_correction) {
block->steps[axis] += ABS(error_correction);
residual_error[axis] -= error_correction;
#if ENABLED(CORE_BACKLASH)
switch (axis) {
case CORE_AXIS_1:
//block->steps[CORE_AXIS_2] += influence_distance_mm[axis] * planner.settings.axis_steps_per_mm[CORE_AXIS_2];
//SERIAL_ECHOLNPAIR("CORE_AXIS_1 dir change. distance=", distance_mm[axis], " r.err=", residual_error[axis],
// " da=", da, " db=", db, " block->steps[axis]=", block->steps[axis], " err_corr=", error_correction);
break;
case CORE_AXIS_2:
//block->steps[CORE_AXIS_1] += influence_distance_mm[axis] * planner.settings.axis_steps_per_mm[CORE_AXIS_1];;
//SERIAL_ECHOLNPAIR("CORE_AXIS_2 dir change. distance=", distance_mm[axis], " r.err=", residual_error[axis],
// " da=", da, " db=", db, " block->steps[axis]=", block->steps[axis], " err_corr=", error_correction);
break;
case NORMAL_AXIS: break;
}
residual_error[axis] = 0; // No residual_error needed for next CORE block, I think...
#else
residual_error[axis] -= error_correction;
#endif
}
}
}
+15 -15
View File
@@ -213,27 +213,27 @@ void reset_bed_level() {
void _manual_goto_xy(const xy_pos_t &pos) {
// Get the resting Z position for after the XY move
#ifdef MANUAL_PROBE_START_Z
constexpr float startz = _MAX(0, MANUAL_PROBE_START_Z);
#if MANUAL_PROBE_HEIGHT > 0
do_blocking_move_to_xy_z(pos, MANUAL_PROBE_HEIGHT);
do_blocking_move_to_z(startz);
#else
do_blocking_move_to_xy_z(pos, startz);
#endif
#elif MANUAL_PROBE_HEIGHT > 0
const float prev_z = current_position.z;
do_blocking_move_to_xy_z(pos, MANUAL_PROBE_HEIGHT);
do_blocking_move_to_z(prev_z);
constexpr float finalz = _MAX(0, MANUAL_PROBE_START_Z); // If a MANUAL_PROBE_START_Z value is set, always respect it
#else
do_blocking_move_to_xy(pos);
#warning "It's recommended to set some MANUAL_PROBE_START_Z value for manual leveling."
#endif
#if Z_CLEARANCE_BETWEEN_MANUAL_PROBES > 0 // A probe/obstacle clearance exists so there is a raise:
#ifndef MANUAL_PROBE_START_Z
const float finalz = current_position.z; // - Use the current Z for starting-Z if no MANUAL_PROBE_START_Z was provided
#endif
do_blocking_move_to_xy_z(pos, Z_CLEARANCE_BETWEEN_MANUAL_PROBES); // - Raise Z, then move to the new XY
do_blocking_move_to_z(finalz); // - Lower down to the starting Z height, ready for adjustment!
#elif defined(MANUAL_PROBE_START_Z) // A starting-Z was provided, but there's no raise:
do_blocking_move_to_xy_z(pos, finalz); // - Move in XY then down to the starting Z height, ready for adjustment!
#else // Zero raise and no starting Z height either:
do_blocking_move_to_xy(pos); // - Move over with no raise, ready for adjustment!
#endif
current_position = pos;
TERN_(LCD_BED_LEVELING, ui.wait_for_move = false);
}
#endif
#endif // MESH_BED_LEVELING || PROBE_MANUALLY
#endif // HAS_LEVELING
+45
View File
@@ -35,6 +35,7 @@ unified_bed_leveling ubl;
#include "../../../module/planner.h"
#include "../../../module/motion.h"
#include "../../../module/probe.h"
#include "../../../module/temperature.h"
#if ENABLED(EXTENSIBLE_UI)
#include "../../../lcd/extui/ui_api.h"
@@ -254,4 +255,48 @@ bool unified_bed_leveling::sanity_check() {
return !!error_flag;
}
#if ENABLED(UBL_MESH_WIZARD)
/**
* M1004: UBL Mesh Wizard - One-click mesh creation with or without a probe
*/
void GcodeSuite::M1004() {
#define ALIGN_GCODE TERN(Z_STEPPER_AUTO_ALIGN, "G34", "")
#define PROBE_GCODE TERN(HAS_BED_PROBE, "G29P1\nG29P3", "G29P4R255")
#if HAS_HOTEND
if (parser.seenval('H')) { // Handle H# parameter to set Hotend temp
const celsius_t hotend_temp = parser.value_int(); // Marlin never sends itself F or K, always C
thermalManager.setTargetHotend(hotend_temp, 0);
thermalManager.wait_for_hotend(false);
}
#endif
#if HAS_HEATED_BED
if (parser.seenval('B')) { // Handle B# parameter to set Bed temp
const celsius_t bed_temp = parser.value_int(); // Marlin never sends itself F or K, always C
thermalManager.setTargetBed(bed_temp);
thermalManager.wait_for_bed(false);
}
#endif
process_subcommands_now_P(G28_STR); // Home
process_subcommands_now_P(PSTR(ALIGN_GCODE "\n" // Align multi z axis if available
PROBE_GCODE "\n" // Build mesh with available hardware
"G29P3\nG29P3")); // Ensure mesh is complete by running smart fill twice
if (parser.seenval('S')) {
char umw_gcode[32];
sprintf_P(umw_gcode, PSTR("G29S%i"), parser.value_int());
queue.inject(umw_gcode);
}
process_subcommands_now_P(PSTR("G29A\nG29F10\n" // Set UBL Active & Fade 10
"M140S0\nM104S0\n" // Turn off heaters
"M500")); // Store settings
}
#endif // UBL_MESH_WIZARD
#endif // AUTO_BED_LEVELING_UBL
+1 -1
View File
@@ -43,7 +43,7 @@ void CancelObject::set_active_object(const int8_t obj) {
else
skipping = false;
#if HAS_STATUS_MESSAGE
#if BOTH(HAS_STATUS_MESSAGE, CANCEL_OBJECTS_REPORTING)
if (active_object >= 0)
ui.status_printf_P(0, PSTR(S_FMT " %i"), GET_TEXT(MSG_PRINTING_OBJECT), int(active_object));
else
+1 -1
View File
@@ -34,7 +34,7 @@ public:
static void set_current_value(const uint8_t channel, uint16_t val);
static void print_values();
static void commit_eeprom();
static uint8_t get_current_percent(AxisEnum axis);
static uint8_t get_current_percent(const AxisEnum axis);
static void set_current_percents(xyze_uint8_t &pct);
};
@@ -40,6 +40,9 @@
#elif MB(AZTEEG_X5_MINI, AZTEEG_X5_MINI_WIFI)
#define DIGIPOT_I2C_FACTOR 113.5f
#define DIGIPOT_I2C_MAX_CURRENT 2.0f
#elif MB(AZTEEG_X5_GT)
#define DIGIPOT_I2C_FACTOR 51.0f
#define DIGIPOT_I2C_MAX_CURRENT 3.0f
#else
#define DIGIPOT_I2C_FACTOR 106.7f
#define DIGIPOT_I2C_MAX_CURRENT 2.5f
+20
View File
@@ -41,6 +41,8 @@ extern bool wait_for_user, wait_for_heatup;
void quickresume_stepper();
#endif
void HAL_reboot();
class EmergencyParser {
public:
@@ -62,6 +64,10 @@ public:
EP_R, EP_R0, EP_R00, EP_GRBL_RESUME,
EP_P, EP_P0, EP_P00, EP_GRBL_PAUSE,
#endif
#if ENABLED(SOFT_RESET_VIA_SERIAL)
EP_ctrl,
EP_K, EP_KI, EP_KIL, EP_KILL,
#endif
EP_IGNORE // to '\n'
};
@@ -89,6 +95,10 @@ public:
case 'P': state = EP_P; break;
case 'R': state = EP_R; break;
#endif
#if ENABLED(SOFT_RESET_VIA_SERIAL)
case '^': state = EP_ctrl; break;
case 'K': state = EP_K; break;
#endif
default: state = EP_IGNORE;
}
break;
@@ -121,6 +131,13 @@ public:
case EP_P00: state = (c == '0') ? EP_GRBL_PAUSE : EP_IGNORE; break;
#endif
#if ENABLED(SOFT_RESET_VIA_SERIAL)
case EP_ctrl: state = (c == 'X') ? EP_KILL : EP_IGNORE; break;
case EP_K: state = (c == 'I') ? EP_KI : EP_IGNORE; break;
case EP_KI: state = (c == 'L') ? EP_KIL : EP_IGNORE; break;
case EP_KIL: state = (c == 'L') ? EP_KILL : EP_IGNORE; break;
#endif
case EP_M:
switch (c) {
case ' ': break;
@@ -189,6 +206,9 @@ public:
case EP_GRBL_PAUSE: quickpause_stepper(); break;
case EP_GRBL_RESUME: quickresume_stepper(); break;
#endif
#if ENABLED(SOFT_RESET_VIA_SERIAL)
case EP_KILL: HAL_reboot(); break;
#endif
default: break;
}
state = EP_RESET;
+2 -2
View File
@@ -149,13 +149,13 @@ void host_action(PGM_P const pstr, const bool eol) {
switch (response) {
case 0: // "Purge More" button
#if BOTH(HAS_LCD_MENU, ADVANCED_PAUSE_FEATURE)
#if BOTH(M600_PURGE_MORE_RESUMABLE, ADVANCED_PAUSE_FEATURE)
pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE; // Simulate menu selection (menu exits, doesn't extrude more)
#endif
break;
case 1: // "Continue" / "Disable Runout" button
#if BOTH(HAS_LCD_MENU, ADVANCED_PAUSE_FEATURE)
#if BOTH(M600_PURGE_MORE_RESUMABLE, ADVANCED_PAUSE_FEATURE)
pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; // Simulate menu selection
#endif
#if HAS_FILAMENT_SENSOR
+1 -1
View File
@@ -45,7 +45,7 @@ void HotendIdleProtection::check_hotends(const millis_t &ms) {
bool do_prot = false;
HOTEND_LOOP() {
const bool busy = (TERN0(HAS_RESUME_CONTINUE, wait_for_user) || planner.has_blocks_queued());
if (thermalManager.degHotend(e) >= HOTEND_IDLE_MIN_TRIGGER && !busy) {
if (thermalManager.degHotend(e) >= (HOTEND_IDLE_MIN_TRIGGER) && !busy) {
do_prot = true; break;
}
}
@@ -40,9 +40,9 @@ PrinterEventLEDs printerEventLEDs;
uint8_t PrinterEventLEDs::old_intensity = 0;
inline uint8_t pel_intensity(const_float_t start, const_float_t current, const_float_t target) {
if (uint16_t(start) == uint16_t(target)) return 255;
return (uint8_t)map(constrain(current, start, target), start, target, 0.f, 255.f);
inline uint8_t pel_intensity(const celsius_t start, const celsius_t current, const celsius_t target) {
if (start == target) return 255;
return (uint8_t)map(constrain(current, start, target), start, target, 0, 255);
}
inline void pel_set_rgb(const uint8_t r, const uint8_t g, const uint8_t b) {
@@ -58,7 +58,7 @@ PrinterEventLEDs printerEventLEDs;
#if HAS_TEMP_HOTEND
void PrinterEventLEDs::onHotendHeating(const_float_t start, const_float_t current, const_float_t target) {
void PrinterEventLEDs::onHotendHeating(const celsius_t start, const celsius_t current, const celsius_t target) {
const uint8_t blue = pel_intensity(start, current, target);
if (blue != old_intensity) {
old_intensity = blue;
@@ -70,7 +70,7 @@ PrinterEventLEDs printerEventLEDs;
#if HAS_HEATED_BED
void PrinterEventLEDs::onBedHeating(const_float_t start, const_float_t current, const_float_t target) {
void PrinterEventLEDs::onBedHeating(const celsius_t start, const celsius_t current, const celsius_t target) {
const uint8_t red = pel_intensity(start, current, target);
if (red != old_intensity) {
old_intensity = red;
@@ -82,7 +82,7 @@ PrinterEventLEDs printerEventLEDs;
#if HAS_HEATED_CHAMBER
void PrinterEventLEDs::onChamberHeating(const_float_t start, const_float_t current, const_float_t target) {
void PrinterEventLEDs::onChamberHeating(const celsius_t start, const celsius_t current, const celsius_t target) {
const uint8_t green = pel_intensity(start, current, target);
if (green != old_intensity) {
old_intensity = green;
+5 -11
View File
@@ -36,32 +36,26 @@ private:
static bool leds_off_after_print;
#endif
static inline void set_done() {
#if ENABLED(LED_COLOR_PRESETS)
leds.set_default();
#else
leds.set_off();
#endif
}
static inline void set_done() { TERN(LED_COLOR_PRESETS, leds.set_default(), leds.set_off()); }
public:
#if HAS_TEMP_HOTEND
static inline LEDColor onHotendHeatingStart() { old_intensity = 0; return leds.get_color(); }
static void onHotendHeating(const_float_t start, const_float_t current, const_float_t target);
static void onHotendHeating(const celsius_t start, const celsius_t current, const celsius_t target);
#endif
#if HAS_HEATED_BED
static inline LEDColor onBedHeatingStart() { old_intensity = 127; return leds.get_color(); }
static void onBedHeating(const_float_t start, const_float_t current, const_float_t target);
static void onBedHeating(const celsius_t start, const celsius_t current, const celsius_t target);
#endif
#if HAS_HEATED_CHAMBER
static inline LEDColor onChamberHeatingStart() { old_intensity = 127; return leds.get_color(); }
static void onChamberHeating(const_float_t start, const_float_t current, const_float_t target);
static void onChamberHeating(const celsius_t start, const celsius_t current, const celsius_t target);
#endif
#if HAS_TEMP_HOTEND || HAS_HEATED_BED || HAS_HEATED_CHAMBER
static inline void onHeatingDone() { leds.set_white(); }
static inline void onHeatingDone() { leds.set_white(); }
static inline void onPidTuningDone(LEDColor c) { leds.set_color(c); }
#endif
+3 -3
View File
@@ -36,10 +36,10 @@ void handle_status_leds() {
static millis_t next_status_led_update_ms = 0;
if (ELAPSED(millis(), next_status_led_update_ms)) {
next_status_led_update_ms += 500; // Update every 0.5s
float max_temp = TERN0(HAS_HEATED_BED, _MAX(thermalManager.degTargetBed(), thermalManager.degBed()));
celsius_t max_temp = TERN0(HAS_HEATED_BED, _MAX(thermalManager.degTargetBed(), thermalManager.wholeDegBed()));
HOTEND_LOOP()
max_temp = _MAX(max_temp, thermalManager.degHotend(e), thermalManager.degTargetHotend(e));
const int8_t new_red = (max_temp > 55.0) ? HIGH : (max_temp < 54.0 || old_red < 0) ? LOW : old_red;
max_temp = _MAX(max_temp, thermalManager.wholeDegHotend(e), thermalManager.degTargetHotend(e));
const int8_t new_red = (max_temp > 55) ? HIGH : (max_temp < 54 || old_red < 0) ? LOW : old_red;
if (new_red != old_red) {
old_red = new_red;
#if PIN_EXISTS(STAT_LED_RED)
+24 -17
View File
@@ -75,7 +75,7 @@
static xyze_pos_t resume_position;
#if HAS_LCD_MENU
#if M600_PURGE_MORE_RESUMABLE
PauseMenuResponse pause_menu_response;
PauseMode pause_mode = PAUSE_MODE_PAUSE_PRINT;
#endif
@@ -143,7 +143,7 @@ static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=P
// Allow interruption by Emergency Parser M108
wait_for_heatup = TERN1(PREVENT_COLD_EXTRUSION, !thermalManager.allow_cold_extrude);
while (wait_for_heatup && ABS(thermalManager.degHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > TEMP_WINDOW)
while (wait_for_heatup && ABS(thermalManager.wholeDegHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > (TEMP_WINDOW))
idle();
wait_for_heatup = false;
@@ -257,18 +257,22 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
TERN_(HOST_PROMPT_SUPPORT, filament_load_host_prompt()); // Initiate another host prompt.
#if HAS_LCD_MENU
#if M600_PURGE_MORE_RESUMABLE
if (show_lcd) {
// Show "Purge More" / "Resume" menu and wait for reply
KEEPALIVE_STATE(PAUSED_FOR_USER);
wait_for_user = false;
ui.pause_show_message(PAUSE_MESSAGE_OPTION);
#if HAS_LCD_MENU
ui.pause_show_message(PAUSE_MESSAGE_OPTION); // Also sets PAUSE_RESPONSE_WAIT_FOR
#else
pause_menu_response = PAUSE_RESPONSE_WAIT_FOR;
#endif
while (pause_menu_response == PAUSE_RESPONSE_WAIT_FOR) idle_no_sleep();
}
#endif
// Keep looping if "Purge More" was selected
} while (TERN0(HAS_LCD_MENU, show_lcd && pause_menu_response == PAUSE_RESPONSE_EXTRUDE_MORE));
} while (TERN0(M600_PURGE_MORE_RESUMABLE, show_lcd && pause_menu_response == PAUSE_RESPONSE_EXTRUDE_MORE));
#endif
TERN_(HOST_PROMPT_SUPPORT, host_action_prompt_end());
@@ -312,7 +316,7 @@ bool unload_filament(const_float_t unload_length, const bool show_lcd/*=false*/,
);
#if !BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
constexpr float mix_multiplier = 1.0;
constexpr float mix_multiplier = 1.0f;
#endif
if (!ensure_safe_temperature(false, mode)) {
@@ -367,7 +371,7 @@ bool unload_filament(const_float_t unload_length, const bool show_lcd/*=false*/,
*/
uint8_t did_pause_print = 0;
bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const_float_t unload_length/*=0*/, const bool show_lcd/*=false*/ DXC_ARGS) {
bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool show_lcd/*=false*/, const_float_t unload_length/*=0*/ DXC_ARGS) {
DEBUG_SECTION(pp, "pause_print", true);
DEBUG_ECHOLNPAIR("... park.x:", park_point.x, " y:", park_point.y, " z:", park_point.z, " unloadlen:", unload_length, " showlcd:", show_lcd DXC_SAY);
@@ -390,7 +394,8 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const_float
// Pause the print job and timer
#if ENABLED(SDSUPPORT)
if (IS_SD_PRINTING()) {
const bool was_sd_printing = IS_SD_PRINTING();
if (was_sd_printing) {
card.pauseSDPrint();
++did_pause_print; // Indicate SD pause also
}
@@ -414,7 +419,7 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const_float
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)
// Park the nozzle by doing a Minimum Z Raise followed by an XY Move
if (!axes_should_home())
nozzle.park(0, park_point);
@@ -598,7 +603,7 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
if (!axes_should_home()) {
// Move XY back to saved position
destination.set(resume_position.x, resume_position.y, current_position.z);
destination.set(resume_position.x, resume_position.y, current_position.z, current_position.e);
prepare_internal_move_to_destination(NOZZLE_PARK_XY_FEEDRATE);
// Move Z back to saved position
@@ -626,9 +631,6 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
// Set extruder to saved position
planner.set_e_position_mm((destination.e = current_position.e = resume_position.e));
// Write PLR now to update the z axis value
TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true));
ui.pause_show_message(PAUSE_MESSAGE_STATUS);
#ifdef ACTION_ON_RESUMED
@@ -641,8 +643,16 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
TERN_(HOST_PROMPT_SUPPORT, host_prompt_open(PROMPT_INFO, PSTR("Resuming"), DISMISS_STR));
// Resume the print job timer if it was running
if (print_job_timer.isPaused()) print_job_timer.start();
#if ENABLED(SDSUPPORT)
if (did_pause_print) { card.startFileprint(); --did_pause_print; }
if (did_pause_print) {
--did_pause_print;
card.startFileprint();
// Write PLR now to update the z axis value
TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true));
}
#endif
#if ENABLED(ADVANCED_PAUSE_FANS_PAUSE) && HAS_FAN
@@ -651,9 +661,6 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
TERN_(HAS_FILAMENT_SENSOR, runout.reset());
// Resume the print job timer if it was running
if (print_job_timer.isPaused()) print_job_timer.start();
TERN_(HAS_STATUS_MESSAGE, ui.reset_status());
TERN_(HAS_LCD_MENU, ui.return_to_status());
}
+37 -9
View File
@@ -59,7 +59,7 @@ enum PauseMessage : char {
PAUSE_MESSAGE_HEATING
};
#if HAS_LCD_MENU
#if M600_PURGE_MORE_RESUMABLE
enum PauseMenuResponse : char {
PAUSE_RESPONSE_WAIT_FOR,
PAUSE_RESPONSE_EXTRUDE_MORE,
@@ -85,19 +85,47 @@ extern uint8_t did_pause_print;
#define DXC_SAY
#endif
bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const_float_t unload_length=0, const bool show_lcd=false DXC_PARAMS);
// Pause the print. If unload_length is set, do a Filament Unload
bool pause_print(
const_float_t retract, // (mm) Retraction length
const xyz_pos_t &park_point, // Parking XY Position and Z Raise
const bool show_lcd=false, // Set LCD status messages?
const_float_t unload_length=0 // (mm) Filament Change Unload Length - 0 to skip
DXC_PARAMS // Dual-X-Carriage extruder index
);
void wait_for_confirmation(const bool is_reload=false, const int8_t max_beep_count=0 DXC_PARAMS);
void wait_for_confirmation(
const bool is_reload=false, // Reload Filament? (otherwise Resume Print)
const int8_t max_beep_count=0 // Beep alert for attention
DXC_PARAMS // Dual-X-Carriage extruder index
);
void resume_print(const_float_t slow_load_length=0, const_float_t fast_load_length=0, const_float_t extrude_length=ADVANCED_PAUSE_PURGE_LENGTH,
const int8_t max_beep_count=0, const celsius_t targetTemp=0 DXC_PARAMS);
void resume_print(
const_float_t slow_load_length=0, // (mm) Slow Load Length for finishing move
const_float_t fast_load_length=0, // (mm) Fast Load Length for initial move
const_float_t extrude_length=ADVANCED_PAUSE_PURGE_LENGTH, // (mm) Purge length
const int8_t max_beep_count=0, // Beep alert for attention
const celsius_t targetTemp=0 // (°C) A target temperature for the hotend
DXC_PARAMS // Dual-X-Carriage extruder index
);
bool load_filament(const_float_t slow_load_length=0, const_float_t fast_load_length=0, const_float_t extrude_length=0, const int8_t max_beep_count=0,
const bool show_lcd=false, const bool pause_for_user=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT DXC_PARAMS);
bool load_filament(
const_float_t slow_load_length=0, // (mm) Slow Load Length for finishing move
const_float_t fast_load_length=0, // (mm) Fast Load Length for initial move
const_float_t extrude_length=0, // (mm) Purge length
const int8_t max_beep_count=0, // Beep alert for attention
const bool show_lcd=false, // Set LCD status messages?
const bool pause_for_user=false, // Pause for user before returning?
const PauseMode mode=PAUSE_MODE_PAUSE_PRINT // Pause Mode to apply
DXC_PARAMS // Dual-X-Carriage extruder index
);
bool unload_filament(const_float_t unload_length, const bool show_lcd=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT
bool unload_filament(
const_float_t unload_length, // (mm) Filament Unload Length - 0 to skip
const bool show_lcd=false, // Set LCD status messages?
const PauseMode mode=PAUSE_MODE_PAUSE_PRINT // Pause Mode to apply
#if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
, const_float_t mix_multiplier=1.0
, const_float_t mix_multiplier=1.0f // Extrusion multiplier (for a Mixing Extruder)
#endif
);
+8 -4
View File
@@ -85,20 +85,24 @@ bool Power::is_power_needed() {
if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0 || thermalManager.temp_bed.soft_pwm_amount > 0)) return true;
#if HAS_HOTEND && AUTO_POWER_E_TEMP
HOTEND_LOOP() if (thermalManager.degHotend(e) >= AUTO_POWER_E_TEMP) return true;
HOTEND_LOOP() if (thermalManager.degHotend(e) >= (AUTO_POWER_E_TEMP)) return true;
#endif
#if HAS_HEATED_CHAMBER && AUTO_POWER_CHAMBER_TEMP
if (thermalManager.degChamber() >= AUTO_POWER_CHAMBER_TEMP) return true;
if (thermalManager.degChamber() >= (AUTO_POWER_CHAMBER_TEMP)) return true;
#endif
#if HAS_COOLER && AUTO_POWER_COOLER_TEMP
if (thermalManager.degCooler() >= AUTO_POWER_COOLER_TEMP) return true;
if (thermalManager.degCooler() >= (AUTO_POWER_COOLER_TEMP)) return true;
#endif
return false;
}
#ifndef POWER_TIMEOUT
#define POWER_TIMEOUT 0
#endif
void Power::check() {
static millis_t nextPowerCheck = 0;
millis_t ms = millis();
@@ -106,7 +110,7 @@ void Power::check() {
nextPowerCheck = ms + 2500UL;
if (is_power_needed())
power_on();
else if (!lastPowerOn || ELAPSED(ms, lastPowerOn + SEC_TO_MS(POWER_TIMEOUT)))
else if (!lastPowerOn || (POWER_TIMEOUT > 0 && ELAPSED(ms, lastPowerOn + SEC_TO_MS(POWER_TIMEOUT))))
power_off();
}
}
+27 -21
View File
@@ -149,6 +149,8 @@ void PrintJobRecovery::prepare() {
*/
void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=0*/) {
// We don't check IS_SD_PRINTING here so a save may occur during a pause
#if SAVE_INFO_INTERVAL_MS > 0
static millis_t next_save_ms; // = 0
millis_t ms = millis();
@@ -192,7 +194,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=0*/
#endif
#if DISABLED(NO_VOLUMETRICS)
info.volumetric_enabled = parser.volumetric_enabled;
info.flag.volumetric_enabled = parser.volumetric_enabled;
#if HAS_MULTI_EXTRUDER
for (int8_t e = 0; e < EXTRUDERS; e++) info.filament_size[e] = planner.filament_size[e];
#else
@@ -366,13 +368,16 @@ void PrintJobRecovery::resume() {
}
#endif
// Reset E, raise Z, home XY...
//
// Home the axes that can safely be homed, and
// establish the current position as best we can
//
#if Z_HOME_DIR > 0
// If Z homing goes to max, just reset E and home all
// If Z homing goes to max...
gcode.process_subcommands_now_P(PSTR(
"G92.9 E0\n"
"G28R0"
"G92.9 E0\n" // Reset E to 0
"G28R0" // Home all axes (no raise)
));
#else // "G92.9 E0 ..."
@@ -391,19 +396,20 @@ void PrintJobRecovery::resume() {
#endif
#ifdef POWER_LOSS_ZHOME_POS
// If defined move to a safe Z homing position that avoids the print
#if ENABLED(POWER_LOSS_RECOVER_ZHOME) && defined(POWER_LOSS_ZHOME_POS)
// Move to a safe XY position where Z can home while avoiding the print.
// If Z_SAFE_HOMING is enabled, its position must also be outside the print area!
constexpr xy_pos_t p = POWER_LOSS_ZHOME_POS;
sprintf_P(cmd, PSTR("G1 X%s Y%s F1000\nG28Z"), dtostrf(p.x, 1, 3, str_1), dtostrf(p.y, 1, 3, str_2));
sprintf_P(cmd, PSTR("G1X%sY%sF1000\nG28Z"), dtostrf(p.x, 1, 3, str_1), dtostrf(p.y, 1, 3, str_2));
gcode.process_subcommands_now(cmd);
#endif
// Ensure that all axes are marked as homed
// Mark all axes as having been homed (no effect on current_position)
set_all_homed();
#if ENABLED(POWER_LOSS_RECOVER_ZHOME)
// Now move to ZsavedPos + POWER_LOSS_ZRAISE
sprintf_P(cmd, PSTR("G1 F500 Z%s"), dtostrf(info.current_position.z + POWER_LOSS_ZRAISE, 1, 3, str_1));
// Z was homed. Now move Z back up to the saved Z height, plus the POWER_LOSS_ZRAISE.
sprintf_P(cmd, PSTR("G1Z%sF500"), dtostrf(info.current_position.z + POWER_LOSS_ZRAISE, 1, 3, str_1));
gcode.process_subcommands_now(cmd);
#endif
@@ -411,16 +417,16 @@ void PrintJobRecovery::resume() {
#if DISABLED(NO_VOLUMETRICS)
#if HAS_MULTI_EXTRUDER
for (int8_t e = 0; e < EXTRUDERS; e++) {
sprintf_P(cmd, PSTR("M200 T%i D%s"), e, dtostrf(info.filament_size[e], 1, 3, str_1));
sprintf_P(cmd, PSTR("M200T%iD%s"), e, dtostrf(info.filament_size[e], 1, 3, str_1));
gcode.process_subcommands_now(cmd);
}
if (!info.volumetric_enabled) {
sprintf_P(cmd, PSTR("M200 T%i D0"), info.active_extruder);
if (!info.flag.volumetric_enabled) {
sprintf_P(cmd, PSTR("M200T%iD0"), info.active_extruder);
gcode.process_subcommands_now(cmd);
}
#else
if (info.volumetric_enabled) {
sprintf_P(cmd, PSTR("M200 D%s"), dtostrf(info.filament_size[0], 1, 3, str_1));
if (info.flag.volumetric_enabled) {
sprintf_P(cmd, PSTR("M200D%s"), dtostrf(info.filament_size[0], 1, 3, str_1));
gcode.process_subcommands_now(cmd);
}
#endif
@@ -437,13 +443,13 @@ void PrintJobRecovery::resume() {
FANS_LOOP(i) {
const int f = info.fan_speed[i];
if (f) {
sprintf_P(cmd, PSTR("M106 P%i S%i"), i, f);
sprintf_P(cmd, PSTR("M106P%iS%i"), i, f);
gcode.process_subcommands_now(cmd);
}
}
#endif
// Restore retract and hop state
// Restore retract and hop state from an active `G10` command
#if ENABLED(FWRETRACT)
LOOP_L_N(e, EXTRUDERS) {
if (info.retract[e] != 0.0) {
@@ -458,7 +464,7 @@ void PrintJobRecovery::resume() {
// Restore leveling state before 'G92 Z' to ensure
// the Z stepper count corresponds to the native Z.
if (info.fade || info.flag.leveling) {
sprintf_P(cmd, PSTR("M420 S%i Z%s"), int(info.flag.leveling), dtostrf(info.fade, 1, 1, str_1));
sprintf_P(cmd, PSTR("M420S%cZ%s"), '0' + (char)info.flag.leveling, dtostrf(info.fade, 1, 1, str_1));
gcode.process_subcommands_now(cmd);
}
#endif
@@ -468,11 +474,11 @@ void PrintJobRecovery::resume() {
#endif
// Un-retract if there was a retract at outage
#if POWER_LOSS_RETRACT_LEN
#if ENABLED(BACKUP_POWER_SUPPLY) && POWER_LOSS_RETRACT_LEN > 0
gcode.process_subcommands_now_P(PSTR("G1 E" STRINGIFY(POWER_LOSS_RETRACT_LEN) " F3000"));
#endif
// Additional purge if configured
// Additional purge on resume if configured
#if POWER_LOSS_PURGE_LEN
sprintf_P(cmd, PSTR("G1 E%d F3000"), (POWER_LOSS_PURGE_LEN) + (POWER_LOSS_RETRACT_LEN));
gcode.process_subcommands_now(cmd);
+4 -2
View File
@@ -70,7 +70,6 @@ typedef struct {
#endif
#if DISABLED(NO_VOLUMETRICS)
bool volumetric_enabled;
float filament_size[EXTRUDERS];
#endif
@@ -116,7 +115,10 @@ typedef struct {
bool dryrun:1; // M111 S8
bool allow_cold_extrusion:1; // M302 P1
#if ENABLED(HAS_LEVELING)
bool leveling:1;
bool leveling:1; // M420 S
#endif
#if DISABLED(NO_VOLUMETRICS)
bool volumetric_enabled:1; // M200 S D
#endif
} flag;
+18 -17
View File
@@ -52,7 +52,7 @@ const temp_calib_t ProbeTempComp::cali_info[TSI_COUNT] = {
constexpr xyz_pos_t ProbeTempComp::park_point;
constexpr xy_pos_t ProbeTempComp::measure_point;
constexpr int ProbeTempComp::probe_calib_bed_temp;
constexpr celsius_t ProbeTempComp::probe_calib_bed_temp;
uint8_t ProbeTempComp::calib_idx; // = 0
float ProbeTempComp::init_measurement; // = 0.0
@@ -71,7 +71,7 @@ bool ProbeTempComp::set_offset(const TempSensorID tsi, const uint8_t idx, const
void ProbeTempComp::print_offsets() {
LOOP_L_N(s, TSI_COUNT) {
float temp = cali_info[s].start_temp;
celsius_t temp = cali_info[s].start_temp;
for (int16_t i = -1; i < cali_info[s].measurements; ++i) {
SERIAL_ECHOPGM_P(s == TSI_BED ? PSTR("Bed") :
#if ENABLED(USE_TEMP_EXT_COMPENSATION)
@@ -114,8 +114,8 @@ bool ProbeTempComp::finish_calibration(const TempSensorID tsi) {
}
const uint8_t measurements = cali_info[tsi].measurements;
const float start_temp = cali_info[tsi].start_temp,
res_temp = cali_info[tsi].temp_res;
const celsius_t start_temp = cali_info[tsi].start_temp,
res_temp = cali_info[tsi].temp_res;
int16_t * const data = sensor_z_offsets[tsi];
// Extrapolate
@@ -126,7 +126,7 @@ bool ProbeTempComp::finish_calibration(const TempSensorID tsi) {
SERIAL_ECHOPGM("Applying linear extrapolation");
calib_idx--;
for (; calib_idx < measurements; ++calib_idx) {
const float temp = start_temp + float(calib_idx) * res_temp;
const celsius_float_t temp = start_temp + float(calib_idx) * res_temp;
data[calib_idx] = static_cast<int16_t>(k * temp + d);
}
}
@@ -159,29 +159,29 @@ bool ProbeTempComp::finish_calibration(const TempSensorID tsi) {
return true;
}
void ProbeTempComp::compensate_measurement(const TempSensorID tsi, const_float_t temp, float &meas_z) {
void ProbeTempComp::compensate_measurement(const TempSensorID tsi, const celsius_t temp, float &meas_z) {
if (WITHIN(temp, cali_info[tsi].start_temp, cali_info[tsi].end_temp))
meas_z -= get_offset_for_temperature(tsi, temp);
}
float ProbeTempComp::get_offset_for_temperature(const TempSensorID tsi, const_float_t temp) {
float ProbeTempComp::get_offset_for_temperature(const TempSensorID tsi, const celsius_t temp) {
const uint8_t measurements = cali_info[tsi].measurements;
const float start_temp = cali_info[tsi].start_temp,
res_temp = cali_info[tsi].temp_res;
const celsius_t start_temp = cali_info[tsi].start_temp,
res_temp = cali_info[tsi].temp_res;
const int16_t * const data = sensor_z_offsets[tsi];
auto point = [&](uint8_t i) {
return xy_float_t({start_temp + i*res_temp, static_cast<float>(data[i])});
auto point = [&](uint8_t i) -> xy_float_t {
return xy_float_t({ static_cast<float>(start_temp) + i * res_temp, static_cast<float>(data[i]) });
};
auto linear_interp = [](float x, xy_float_t p1, xy_float_t p2) {
auto linear_interp = [](const_float_t x, xy_float_t p1, xy_float_t p2) {
return (p2.y - p1.y) / (p2.x - p2.y) * (x - p1.x) + p1.y;
};
// Linear interpolation
uint8_t idx = static_cast<uint8_t>((temp - start_temp) / res_temp);
// offset in um
// offset in µm
float offset = 0.0f;
#if !defined(PTC_LINEAR_EXTRAPOLATION) || PTC_LINEAR_EXTRAPOLATION <= 0
@@ -207,17 +207,18 @@ bool ProbeTempComp::linear_regression(const TempSensorID tsi, float &k, float &d
if (!WITHIN(calib_idx, 2, cali_info[tsi].measurements)) return false;
const float start_temp = cali_info[tsi].start_temp,
res_temp = cali_info[tsi].temp_res;
const celsius_t start_temp = cali_info[tsi].start_temp,
res_temp = cali_info[tsi].temp_res;
const int16_t * const data = sensor_z_offsets[tsi];
float sum_x = start_temp,
sum_x2 = sq(start_temp),
sum_xy = 0, sum_y = 0;
float xi = static_cast<float>(start_temp);
LOOP_L_N(i, calib_idx) {
const float xi = start_temp + (i + 1) * res_temp,
yi = static_cast<float>(data[i]);
const float yi = static_cast<float>(data[i]);
xi += res_temp;
sum_x += xi;
sum_x2 += sq(xi);
sum_xy += xi * yi;
+16 -16
View File
@@ -34,9 +34,9 @@ enum TempSensorID : uint8_t {
typedef struct {
uint8_t measurements; // Max. number of measurements to be stored (35 - 80°C)
float temp_res, // Resolution in °C between measurements
start_temp, // Base measurement; z-offset == 0
end_temp;
celsius_t temp_res, // Resolution in °C between measurements
start_temp, // Base measurement; z-offset == 0
end_temp;
} temp_calib_t;
/**
@@ -50,25 +50,25 @@ typedef struct {
#define PTC_SAMPLE_COUNT 10U
#endif
#ifndef PTC_SAMPLE_RES
#define PTC_SAMPLE_RES 5.0f
#define PTC_SAMPLE_RES 5
#endif
#ifndef PTC_SAMPLE_START
#define PTC_SAMPLE_START 30.0f
#define PTC_SAMPLE_START 30
#endif
#define PTC_SAMPLE_END ((PTC_SAMPLE_START) + (PTC_SAMPLE_COUNT) * (PTC_SAMPLE_RES))
// Bed temperature calibration constants
#ifndef BTC_PROBE_TEMP
#define BTC_PROBE_TEMP 30.0f
#define BTC_PROBE_TEMP 30
#endif
#ifndef BTC_SAMPLE_COUNT
#define BTC_SAMPLE_COUNT 10U
#endif
#ifndef BTC_SAMPLE_STEP
#define BTC_SAMPLE_RES 5.0f
#define BTC_SAMPLE_RES 5
#endif
#ifndef BTC_SAMPLE_START
#define BTC_SAMPLE_START 60.0f
#define BTC_SAMPLE_START 60
#endif
#define BTC_SAMPLE_END ((BTC_SAMPLE_START) + (BTC_SAMPLE_COUNT) * (BTC_SAMPLE_RES))
@@ -77,14 +77,14 @@ typedef struct {
#endif
#ifndef PTC_PROBE_RAISE
#define PTC_PROBE_RAISE 10.0f
#define PTC_PROBE_RAISE 10
#endif
static constexpr temp_calib_t cali_info_init[TSI_COUNT] = {
{ PTC_SAMPLE_COUNT, PTC_SAMPLE_RES, PTC_SAMPLE_START, PTC_SAMPLE_END }, // Probe
{ BTC_SAMPLE_COUNT, BTC_SAMPLE_RES, BTC_SAMPLE_START, BTC_SAMPLE_END }, // Bed
{ PTC_SAMPLE_COUNT, PTC_SAMPLE_RES, PTC_SAMPLE_START, PTC_SAMPLE_END }, // Probe
{ BTC_SAMPLE_COUNT, BTC_SAMPLE_RES, BTC_SAMPLE_START, BTC_SAMPLE_END }, // Bed
#if ENABLED(USE_TEMP_EXT_COMPENSATION)
{ 20, 5, 180, 180 + 5 * 20 } // Extruder
{ 20, 5, 180, 180 + 5 * 20 } // Extruder
#endif
};
@@ -100,8 +100,8 @@ class ProbeTempComp {
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_MAX_TARGET, // Bed temperature while calibrating probe
bed_calib_probe_temp = BTC_PROBE_TEMP; // Probe temperature while calibrating bed
static constexpr celsius_t probe_calib_bed_temp = BED_MAX_TARGET, // Bed temperature while calibrating probe
bed_calib_probe_temp = BTC_PROBE_TEMP; // Probe temperature while calibrating bed
static int16_t *sensor_z_offsets[TSI_COUNT],
z_offsets_probe[cali_info_init[TSI_PROBE].measurements], // (µm)
@@ -124,7 +124,7 @@ class ProbeTempComp {
static void prepare_new_calibration(const_float_t init_meas_z);
static void push_back_new_measurement(const TempSensorID tsi, const_float_t meas_z);
static bool finish_calibration(const TempSensorID tsi);
static void compensate_measurement(const TempSensorID tsi, const_float_t temp, float &meas_z);
static void compensate_measurement(const TempSensorID tsi, const celsius_t temp, float &meas_z);
private:
static uint8_t calib_idx;
@@ -135,7 +135,7 @@ class ProbeTempComp {
*/
static float init_measurement;
static float get_offset_for_temperature(const TempSensorID tsi, const_float_t temp);
static float get_offset_for_temperature(const TempSensorID tsi, const celsius_t temp);
/**
* Fit a linear function in measured temperature offsets
+28
View File
@@ -68,6 +68,12 @@ void SpindleLaser::init() {
set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY);
TERN_(MARLIN_DEV_MODE, frequency = SPINDLE_LASER_FREQUENCY);
#endif
#if ENABLED(AIR_EVACUATION)
OUT_WRITE(AIR_EVACUATION_PIN, !AIR_EVACUATION_ACTIVE); // Init Vacuum/Blower OFF
#endif
#if ENABLED(AIR_ASSIST)
OUT_WRITE(AIR_ASSIST_PIN, !AIR_ASSIST_ACTIVE); // Init Air Assist OFF
#endif
}
#if ENABLED(SPINDLE_LASER_PWM)
@@ -135,4 +141,26 @@ void SpindleLaser::apply_power(const uint8_t opwr) {
}
#endif
#if ENABLED(AIR_EVACUATION)
// Enable / disable Cutter Vacuum or Laser Blower motor
void SpindleLaser::air_evac_enable() { WRITE(AIR_EVACUATION_PIN, AIR_EVACUATION_ACTIVE); } // Turn ON
void SpindleLaser::air_evac_disable() { WRITE(AIR_EVACUATION_PIN, !AIR_EVACUATION_ACTIVE); } // Turn OFF
void SpindleLaser::air_evac_toggle() { TOGGLE(AIR_EVACUATION_PIN); } // Toggle state
#endif // AIR_EVACUATION
#if ENABLED(AIR_ASSIST)
// Enable / disable air assist
void SpindleLaser::air_assist_enable() { WRITE(AIR_ASSIST_PIN, AIR_ASSIST_PIN); } // Turn ON
void SpindleLaser::air_assist_disable() { WRITE(AIR_ASSIST_PIN, !AIR_ASSIST_PIN); } // Turn OFF
void SpindleLaser::air_assist_toggle() { TOGGLE(AIR_ASSIST_PIN); } // Toggle state
#endif // AIR_ASSIST
#endif // HAS_CUTTER
+18
View File
@@ -212,6 +212,24 @@ public:
static bool is_reverse() { return false; }
#endif
#if ENABLED(AIR_EVACUATION)
static void air_evac_enable(); // Turn On Cutter Vacuum or Laser Blower motor
static void air_evac_disable(); // Turn Off Cutter Vacuum or Laser Blower motor
static void air_evac_toggle(); // Toggle Cutter Vacuum or Laser Blower motor
static inline bool air_evac_state() { // Get current state
return (READ(AIR_EVACUATION_PIN) == AIR_EVACUATION_ACTIVE);
}
#endif
#if ENABLED(AIR_ASSIST)
static void air_assist_enable(); // Turn on air assist
static void air_assist_disable(); // Turn off air assist
static void air_assist_toggle(); // Toggle air assist
static inline bool air_assist_state() { // Get current state
return (READ(AIR_ASSIST_PIN) == AIR_ASSIST_ACTIVE);
}
#endif
static inline void disable() { isReady = false; set_enabled(false); }
#if HAS_LCD_MENU
@@ -0,0 +1,171 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../inc/MarlinConfig.h"
#include "../lcd/marlinui.h"
#if HAS_DRIVER_SAFE_POWER_PROTECT
#include "stepper_driver_safety.h"
static uint32_t axis_plug_backward = 0;
void stepper_driver_backward_error(PGM_P str) {
SERIAL_ERROR_START();
SERIAL_ECHOPGM_P(str);
SERIAL_ECHOLNPGM(" driver is backward!");
ui.status_printf_P(2, PSTR(S_FMT S_FMT), str, GET_TEXT(MSG_DRIVER_BACKWARD));
}
void stepper_driver_backward_check() {
OUT_WRITE(SAFE_POWER_PIN, LOW);
#define TEST_BACKWARD(AXIS, BIT) do { \
SET_INPUT(AXIS##_ENABLE_PIN); \
OUT_WRITE(AXIS##_STEP_PIN, false); \
delay(20); \
if (READ(AXIS##_ENABLE_PIN) == false) { \
SBI(axis_plug_backward, BIT); \
stepper_driver_backward_error(PSTR(STRINGIFY(AXIS))); \
} \
}while(0)
#if HAS_X_ENABLE
TEST_BACKWARD(X, 0);
#endif
#if HAS_X2_ENABLE
TEST_BACKWARD(X2, 1);
#endif
#if HAS_Y_ENABLE
TEST_BACKWARD(Y, 2);
#endif
#if HAS_Y2_ENABLE
TEST_BACKWARD(Y2, 3);
#endif
#if HAS_Z_ENABLE
TEST_BACKWARD(Z, 4);
#endif
#if HAS_Z2_ENABLE
TEST_BACKWARD(Z2, 5);
#endif
#if HAS_Z3_ENABLE
TEST_BACKWARD(Z3, 6);
#endif
#if HAS_Z4_ENABLE
TEST_BACKWARD(Z4, 7);
#endif
#if HAS_E0_ENABLE
TEST_BACKWARD(E0, 8);
#endif
#if HAS_E1_ENABLE
TEST_BACKWARD(E1, 9);
#endif
#if HAS_E2_ENABLE
TEST_BACKWARD(E2, 10);
#endif
#if HAS_E3_ENABLE
TEST_BACKWARD(E3, 11);
#endif
#if HAS_E4_ENABLE
TEST_BACKWARD(E4, 12);
#endif
#if HAS_E5_ENABLE
TEST_BACKWARD(E5, 13);
#endif
#if HAS_E6_ENABLE
TEST_BACKWARD(E6, 14);
#endif
#if HAS_E7_ENABLE
TEST_BACKWARD(E7, 15);
#endif
if (!axis_plug_backward)
WRITE(SAFE_POWER_PIN, HIGH);
}
void stepper_driver_backward_report() {
if (!axis_plug_backward) return;
auto _report_if_backward = [](PGM_P axis, uint8_t bit) {
if (TEST(axis_plug_backward, bit))
stepper_driver_backward_error(axis);
};
#define REPORT_BACKWARD(axis, bit) _report_if_backward(PSTR(STRINGIFY(axis)), bit)
#if HAS_X_ENABLE
REPORT_BACKWARD(X, 0);
#endif
#if HAS_X2_ENABLE
REPORT_BACKWARD(X2, 1);
#endif
#if HAS_Y_ENABLE
REPORT_BACKWARD(Y, 2);
#endif
#if HAS_Y2_ENABLE
REPORT_BACKWARD(Y2, 3);
#endif
#if HAS_Z_ENABLE
REPORT_BACKWARD(Z, 4);
#endif
#if HAS_Z2_ENABLE
REPORT_BACKWARD(Z2, 5);
#endif
#if HAS_Z3_ENABLE
REPORT_BACKWARD(Z3, 6);
#endif
#if HAS_Z4_ENABLE
REPORT_BACKWARD(Z4, 7);
#endif
#if HAS_E0_ENABLE
REPORT_BACKWARD(E0, 8);
#endif
#if HAS_E1_ENABLE
REPORT_BACKWARD(E1, 9);
#endif
#if HAS_E2_ENABLE
REPORT_BACKWARD(E2, 10);
#endif
#if HAS_E3_ENABLE
REPORT_BACKWARD(E3, 11);
#endif
#if HAS_E4_ENABLE
REPORT_BACKWARD(E4, 12);
#endif
#if HAS_E5_ENABLE
REPORT_BACKWARD(E5, 13);
#endif
#if HAS_E6_ENABLE
REPORT_BACKWARD(E6, 14);
#endif
#if HAS_E7_ENABLE
REPORT_BACKWARD(E7, 15);
#endif
}
#endif // HAS_DRIVER_SAFE_POWER_PROTECT
@@ -0,0 +1,28 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../inc/MarlinConfigPre.h"
void stepper_driver_backward_check();
void stepper_driver_backward_report();
+8 -8
View File
@@ -97,6 +97,14 @@ public:
int abl_probe_index;
#endif
#if ENABLED(AUTO_BED_LEVELING_LINEAR)
int abl_points;
#elif ENABLED(AUTO_BED_LEVELING_3POINT)
static constexpr int abl_points = 3;
#elif ABL_USES_GRID
static constexpr int abl_points = GRID_MAX_POINTS;
#endif
#if ABL_USES_GRID
xy_int8_t meshCount;
@@ -113,14 +121,6 @@ public:
static constexpr xy_uint8_t grid_points = { GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y };
#endif
#if ENABLED(AUTO_BED_LEVELING_LINEAR)
int abl_points;
#elif ENABLED(AUTO_BED_LEVELING_3POINT)
static constexpr int abl_points = 3;
#else
static constexpr int abl_points = GRID_MAX_POINTS;
#endif
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
float Z_offset;
#endif
+13 -3
View File
@@ -100,7 +100,11 @@ void GcodeSuite::G29() {
// For each G29 S2...
if (mbl_probe_index == 0) {
// Move close to the bed before the first point
do_blocking_move_to_z(MANUAL_PROBE_START_Z);
do_blocking_move_to_z(0.4f
#ifdef MANUAL_PROBE_START_Z
+ (MANUAL_PROBE_START_Z) - 0.4f
#endif
);
}
else {
// Save Z for the previous mesh position
@@ -116,8 +120,14 @@ void GcodeSuite::G29() {
_manual_goto_xy({ mbl.index_to_xpos[ix], mbl.index_to_ypos[iy] });
}
else {
// One last "return to the bed" (as originally coded) at completion
current_position.z = MANUAL_PROBE_HEIGHT;
// Move to the after probing position
current_position.z = (
#ifdef Z_AFTER_PROBING
Z_AFTER_PROBING
#else
Z_CLEARANCE_BETWEEN_MANUAL_PROBES
#endif
);
line_to_current_position();
planner.synchronize();
+12 -12
View File
@@ -103,14 +103,14 @@ void GcodeSuite::G76() {
return (timeout && ELAPSED(ms, timeout));
};
auto wait_for_temps = [&](const float tb, const float tp, millis_t &ntr, const millis_t timeout=0) {
auto wait_for_temps = [&](const celsius_t tb, const celsius_t tp, millis_t &ntr, const millis_t timeout=0) {
say_waiting_for(); SERIAL_ECHOLNPGM("bed and probe temperature.");
while (fabs(thermalManager.degBed() - tb) > 0.1f || thermalManager.degProbe() > tp)
while (thermalManager.wholeDegBed() != tb || thermalManager.wholeDegProbe() > tp)
if (report_temps(ntr, timeout)) return true;
return false;
};
auto g76_probe = [](const TempSensorID sid, uint16_t &targ, const xy_pos_t &nozpos) {
auto g76_probe = [](const TempSensorID sid, celsius_t &targ, const xy_pos_t &nozpos) {
do_z_clearance(5.0); // Raise nozzle before probing
const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_STOW, 0, false); // verbose=0, probe_relative=false
if (isnan(measured_z))
@@ -170,17 +170,17 @@ 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) {
auto report_targets = [&](const celsius_t tb, const celsius_t tp) {
SERIAL_ECHOLNPAIR("Target Bed:", tb, " Probe:", tp);
};
if (do_bed_cal) {
uint16_t target_bed = cali_info_init[TSI_BED].start_temp,
target_probe = temp_comp.bed_calib_probe_temp;
celsius_t target_bed = cali_info_init[TSI_BED].start_temp,
target_probe = temp_comp.bed_calib_probe_temp;
say_waiting_for(); SERIAL_ECHOLNPGM(" cooling.");
while (thermalManager.degBed() > target_bed || thermalManager.degProbe() > target_probe)
while (thermalManager.wholeDegBed() > target_bed || thermalManager.wholeDegProbe() > target_probe)
report_temps(next_temp_report);
// Disable leveling so it won't mess with us
@@ -204,11 +204,11 @@ void GcodeSuite::G76() {
do_blocking_move_to(noz_pos_xyz);
say_waiting_for_probe_heating();
SERIAL_EOL();
while (thermalManager.degProbe() < target_probe)
while (thermalManager.wholeDegProbe() < target_probe)
report_temps(next_temp_report);
const float measured_z = g76_probe(TSI_BED, target_bed, noz_pos_xyz);
if (isnan(measured_z) || target_bed > BED_MAX_TARGET) break;
if (isnan(measured_z) || target_bed > (BED_MAX_TARGET)) break;
}
SERIAL_ECHOLNPAIR("Retrieved measurements: ", temp_comp.get_index());
@@ -236,10 +236,10 @@ void GcodeSuite::G76() {
do_blocking_move_to(parkpos);
// Initialize temperatures
const uint16_t target_bed = temp_comp.probe_calib_bed_temp;
const celsius_t target_bed = temp_comp.probe_calib_bed_temp;
thermalManager.setTargetBed(target_bed);
uint16_t target_probe = cali_info_init[TSI_PROBE].start_temp;
celsius_t target_probe = cali_info_init[TSI_PROBE].start_temp;
report_targets(target_bed, target_probe);
@@ -350,7 +350,7 @@ void GcodeSuite::M192() {
return;
}
const float target_temp = parser.value_celsius();
const celsius_t target_temp = parser.value_celsius();
ui.set_status_P(thermalManager.isProbeBelowTemp(target_temp) ? GET_TEXT(MSG_PROBE_HEATING) : GET_TEXT(MSG_PROBE_COOLING));
thermalManager.wait_for_probe(target_temp, no_wait_for_cooling);
}
+44
View File
@@ -0,0 +1,44 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../../inc/MarlinConfig.h"
#if ENABLED(AIR_EVACUATION)
#include "../gcode.h"
#include "../../feature/spindle_laser.h"
/**
* M10: Vacuum or Blower On
*/
void GcodeSuite::M10() {
cutter.air_evac_enable(); // Turn on Vacuum or Blower motor
}
/**
* M11: Vacuum or Blower OFF
*/
void GcodeSuite::M11() {
cutter.air_evac_disable(); // Turn off Vacuum or Blower motor
}
#endif // AIR_EVACUATION
+24
View File
@@ -61,3 +61,27 @@ void GcodeSuite::M9() {
}
#endif // COOLANT_CONTROL
#if ENABLED(AIR_ASSIST)
#include "../gcode.h"
#include "../../module/planner.h"
#include "../../feature/spindle_laser.h"
/**
* M8: Air Assist On
*/
void GcodeSuite::M8() {
planner.synchronize();
cutter.air_assist_enable(); // Turn on Air Assist pin
}
/**
* M9: Air Assist Off
*/
void GcodeSuite::M9() {
planner.synchronize();
cutter.air_assist_disable(); // Turn off Air Assist pin
}
#endif // AIR_ASSIST
+3 -2
View File
@@ -78,8 +78,9 @@ void GcodeSuite::M125() {
// If possible, show an LCD prompt with the 'P' flag
const bool show_lcd = TERN0(HAS_LCD_MENU, parser.boolval('P'));
if (pause_print(retract, park_point, 0, show_lcd)) {
TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true));
TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true));
if (pause_print(retract, park_point, show_lcd, 0)) {
if (ENABLED(EXTENSIBLE_UI) || !sd_printing || show_lcd) {
wait_for_confirmation(false, 0);
resume_print(0, 0, -retract, 0);
+1 -1
View File
@@ -149,7 +149,7 @@ void GcodeSuite::M600() {
#endif
);
if (pause_print(retract, park_point, unload_length, true DXC_PASS)) {
if (pause_print(retract, park_point, true, unload_length DXC_PASS)) {
#if ENABLED(MMU2_MENUS)
mmu2_M600();
resume_print(slow_load_length, fast_load_length, 0, beep_count DXC_PASS);
+1 -1
View File
@@ -97,7 +97,7 @@ void GcodeSuite::M701() {
};
// Raise the Z axis (with max limit)
const float park_raise = _MIN(0, park_point.z, (Z_MAX_POS) - current_position.z);
const float park_raise = _MIN(park_point.z, (Z_MAX_POS) - current_position.z);
move_z_by(park_raise);
// Load filament
+8
View File
@@ -432,6 +432,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 3: M3_M4(false); break; // M3: Turn ON Laser | Spindle (clockwise), set Power | Speed
case 4: M3_M4(true ); break; // M4: Turn ON Laser | Spindle (counter-clockwise), set Power | Speed
case 5: M5(); break; // M5: Turn OFF Laser | Spindle
#if ENABLED(AIR_EVACUATION)
case 10: M10(); break; // M10: Vacuum or Blower motor ON
case 11: M11(); break; // M11: Vacuum or Blower motor OFF
#endif
#endif
#if ENABLED(COOLANT_CONTROL)
@@ -983,6 +987,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 1002: M1002(); break; // M1002: [INTERNAL] Tool-change and Relative E Move
#endif
#if ENABLED(UBL_MESH_WIZARD)
case 1004: M1004(); break; // M1004: UBL Mesh Wizard
#endif
#if ENABLED(MAX7219_GCODE)
case 7219: M7219(); break; // M7219: Set LEDs, columns, and rows
#endif
+10
View File
@@ -86,6 +86,8 @@
* M7 - Turn mist coolant ON. (Requires COOLANT_CONTROL)
* M8 - Turn flood coolant ON. (Requires COOLANT_CONTROL)
* M9 - Turn coolant OFF. (Requires COOLANT_CONTROL)
* M10 - Turn Vacuum or Blower motor ON (Requires AIR_EVACUATION)
* M11 - Turn Vacuum or Blower motor OFF (Requires AIR_EVACUATION)
* M12 - Set up closed loop control system. (Requires EXTERNAL_CLOSED_LOOP_CONTROLLER)
* M16 - Expected printer check. (Requires EXPECTED_PRINTER_CHECK)
* M17 - Enable/Power all stepper motors
@@ -548,6 +550,10 @@ private:
#if HAS_CUTTER
static void M3_M4(const bool is_M4);
static void M5();
#if ENABLED(AIR_EVACUATION)
static void M10();
static void M11();
#endif
#endif
#if ENABLED(COOLANT_CONTROL)
@@ -1073,6 +1079,10 @@ private:
static void M1002();
#endif
#if ENABLED(UBL_MESH_WIZARD)
static void M1004();
#endif
#if ENABLED(MAX7219_GCODE)
static void M7219();
#endif
+8 -2
View File
@@ -30,6 +30,7 @@
#include "../HAL/shared/eeprom_if.h"
#include "../HAL/shared/Delay.h"
#include "../sd/cardreader.h"
#include "../MarlinCore.h" // for kill
extern void dump_delay_accuracy_check();
@@ -44,12 +45,16 @@
switch (dcode) {
case -1:
for (;;); // forever
for (;;) { /* loop forever (watchdog reset) */ }
case 0:
HAL_reboot();
break;
case 10:
kill(PSTR("D10"), PSTR("KILL TEST"), parser.seen('P'));
break;
case 1: {
// Zero or pattern-fill the EEPROM data
#if ENABLED(EEPROM_SETTINGS)
@@ -211,7 +216,8 @@
} break;
case 102: { // D102 Test SD Read
card.openFileRead("test.gco");
char testfile[] = "test.gco";
card.openFileRead(testfile);
if (!card.isFileOpen()) {
SERIAL_ECHOLNPAIR("Failed to open test.gco to read.");
return;
+1 -1
View File
@@ -217,7 +217,7 @@ void GCodeParser::parse(char *p) {
#if ENABLED(GCODE_MOTION_MODES)
#if ENABLED(ARC_SUPPORT)
case 'I' ... 'J':
case 'I' ... 'J':
if (motion_mode_codenum != 2 && motion_mode_codenum != 3) return;
#endif
case 'Q':
+2 -2
View File
@@ -371,7 +371,7 @@ public:
case TEMPUNIT_K: f -= 273.15f;
case TEMPUNIT_F: f = (f - 32) * 0.5555555556f;
}
return LROUND(f + 0.5f);
return LROUND(f);
}
static inline celsius_t value_celsius_diff() {
@@ -382,7 +382,7 @@ public:
case TEMPUNIT_K: break;
case TEMPUNIT_F: f *= 0.5555555556f;
}
return LROUND(f + 0.5f);
return LROUND(f);
}
#else // !TEMPERATURE_UNITS_SUPPORT
+1
View File
@@ -270,6 +270,7 @@ void GCodeQueue::flush_and_request_resend(const serial_index_t serial_ind) {
SERIAL_FLUSH();
SERIAL_ECHOPGM(STR_RESEND);
SERIAL_ECHOLN(serial_state[serial_ind.index].last_N + 1);
SERIAL_ECHOLNPGM(STR_OK);
}
static bool serial_data_available(serial_index_t index) {
+2 -2
View File
@@ -57,7 +57,7 @@ void GcodeSuite::M303() {
#endif
const heater_id_t hid = (heater_id_t)parser.intval('E');
int16_t default_temp;
celsius_t default_temp;
switch (hid) {
#if ENABLED(PIDTEMP)
case 0 ... HOTENDS - 1: default_temp = PREHEAT_1_TEMP_HOTEND; break;
@@ -74,7 +74,7 @@ void GcodeSuite::M303() {
return;
}
const int16_t temp = parser.celsiusval('S', default_temp);
const celsius_t temp = parser.celsiusval('S', default_temp);
const int c = parser.intval('C', 5);
const bool u = parser.boolval('U');
+17 -13
View File
@@ -640,6 +640,16 @@
#endif
#endif
/**
* Disable unused SINGLENOZZLE sub-options
*/
#if DISABLED(SINGLENOZZLE)
#undef SINGLENOZZLE_STANDBY_TEMP
#endif
#if !BOTH(HAS_FAN, SINGLENOZZLE)
#undef SINGLENOZZLE_STANDBY_FAN
#endif
/**
* DISTINCT_E_FACTORS affects how some E factors are accessed
*/
@@ -788,14 +798,6 @@
#endif
#endif // FILAMENT_RUNOUT_SENSOR
#if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
#undef PROBE_MANUALLY
#endif
#if ANY(HAS_BED_PROBE, PROBE_MANUALLY, MESH_BED_LEVELING)
#define PROBE_SELECTED 1
#endif
#if HAS_BED_PROBE
#if DISABLED(NOZZLE_AS_PROBE)
#define HAS_PROBE_XY_OFFSET 1
@@ -865,14 +867,16 @@
#define PLANNER_LEVELING 1
#endif
#endif
#if EITHER(HAS_ABL_OR_UBL, Z_MIN_PROBE_REPEATABILITY_TEST)
#define HAS_PROBING_PROCEDURE 1
#endif
#if !HAS_LEVELING
#undef PROBE_MANUALLY
#undef RESTORE_LEVELING_AFTER_G28
#undef ENABLE_LEVELING_AFTER_G28
#endif
#if !HAS_LEVELING || EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
#undef PROBE_MANUALLY
#endif
#if ANY(HAS_BED_PROBE, PROBE_MANUALLY, MESH_BED_LEVELING)
#define PROBE_SELECTED 1
#endif
#ifdef GRID_MAX_POINTS_X
#define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y))
@@ -921,7 +925,7 @@
#define NORMAL_AXIS Z_AXIS
#endif
#if EITHER(MORGAN_SCARA, AXEL_TPARA)
#if ANY(MORGAN_SCARA, MP_SCARA, AXEL_TPARA)
#define IS_SCARA 1
#define IS_KINEMATIC 1
#elif ENABLED(DELTA)
-5
View File
@@ -370,11 +370,6 @@
#endif
#endif
// If platform requires early initialization of watchdog to properly boot
#if ENABLED(USE_WATCHDOG) && defined(ARDUINO_ARCH_SAM)
#define EARLY_WATCHDOG 1
#endif
// Full Touch Screen needs 'tft/xpt2046'
#if EITHER(TOUCH_SCREEN, HAS_TFT_LVGL_UI)
#define HAS_TFT_XPT2046 1
+27 -7
View File
@@ -2539,7 +2539,9 @@
#endif
#if HAS_TEMPERATURE && EITHER(HAS_LCD_MENU, DWIN_CREALITY_LCD)
#ifdef PREHEAT_5_LABEL
#ifdef PREHEAT_6_LABEL
#define PREHEAT_COUNT 6
#elif defined(PREHEAT_5_LABEL)
#define PREHEAT_COUNT 5
#elif defined(PREHEAT_4_LABEL)
#define PREHEAT_COUNT 4
@@ -2714,8 +2716,16 @@
#define HEATER_IDLE_HANDLER 1
#endif
#if ENABLED(ADVANCED_PAUSE_FEATURE) && !defined(FILAMENT_CHANGE_SLOW_LOAD_LENGTH)
#define FILAMENT_CHANGE_SLOW_LOAD_LENGTH 0
/**
* Advanced Pause - Filament Change
*/
#if ENABLED(ADVANCED_PAUSE_FEATURE)
#if HAS_LCD_MENU || BOTH(EMERGENCY_PARSER, HOST_PROMPT_SUPPORT)
#define M600_PURGE_MORE_RESUMABLE 1
#endif
#ifndef FILAMENT_CHANGE_SLOW_LOAD_LENGTH
#define FILAMENT_CHANGE_SLOW_LOAD_LENGTH 0
#endif
#endif
#if HAS_MULTI_EXTRUDER && !defined(TOOLCHANGE_FS_EXTRA_PRIME)
@@ -2900,9 +2910,9 @@
#define Z_CLEARANCE_BETWEEN_PROBES Z_HOMING_HEIGHT
#endif
#if Z_CLEARANCE_BETWEEN_PROBES > Z_HOMING_HEIGHT
#define MANUAL_PROBE_HEIGHT Z_CLEARANCE_BETWEEN_PROBES
#define Z_CLEARANCE_BETWEEN_MANUAL_PROBES Z_CLEARANCE_BETWEEN_PROBES
#else
#define MANUAL_PROBE_HEIGHT Z_HOMING_HEIGHT
#define Z_CLEARANCE_BETWEEN_MANUAL_PROBES Z_HOMING_HEIGHT
#endif
#ifndef Z_CLEARANCE_MULTI_PROBE
#define Z_CLEARANCE_MULTI_PROBE Z_CLEARANCE_BETWEEN_PROBES
@@ -2912,8 +2922,14 @@
#endif
#endif
#if !defined(MANUAL_PROBE_START_Z) && defined(Z_CLEARANCE_BETWEEN_PROBES)
#define MANUAL_PROBE_START_Z Z_CLEARANCE_BETWEEN_PROBES
// Define a starting height for measuring manual probe points
#ifndef MANUAL_PROBE_START_Z
#if EITHER(MESH_BED_LEVELING, PROBE_MANUALLY)
// Leave MANUAL_PROBE_START_Z undefined so the prior Z height will be used.
// Note: If Z_CLEARANCE_BETWEEN_MANUAL_PROBES is 0 there will be no raise between points
#elif ENABLED(AUTO_BED_LEVELING_UBL) && defined(Z_CLEARANCE_BETWEEN_PROBES)
#define MANUAL_PROBE_START_Z Z_CLEARANCE_BETWEEN_PROBES
#endif
#endif
#ifndef __SAM3X8E__ //todo: hal: broken hal encapsulation
@@ -3026,3 +3042,7 @@
#if BUTTONS_EXIST(EN1, EN2, ENC)
#define HAS_ROTARY_ENCODER 1
#endif
#if PIN_EXISTS(SAFE_POWER) && DISABLED(DISABLE_DRIVER_SAFE_POWER_PROTECT)
#define HAS_DRIVER_SAFE_POWER_PROTECT 1
#endif
+27 -4
View File
@@ -1251,7 +1251,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
/**
* Allow only one kinematic type to be defined
*/
#if MANY(DELTA, MORGAN_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY)
#if MANY(DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY)
#error "Please enable only one of DELTA, MORGAN_SCARA, AXEL_TPARA, COREXY, COREYX, COREXZ, COREZX, COREYZ, COREZY, or MARKFORGED_XY."
#endif
@@ -2208,12 +2208,22 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
#endif
/**
* emergency-command parser
* Emergency Command Parser
*/
#if ENABLED(EMERGENCY_PARSER) && defined(__AVR__) && defined(USBCON)
#error "EMERGENCY_PARSER does not work on boards with AT90USB processors (USBCON)."
#endif
/**
* Software Reset options
*/
#if ENABLED(SOFT_RESET_VIA_SERIAL) && DISABLED(EMERGENCY_PARSER)
#error "EMERGENCY_PARSER is required to activate SOFT_RESET_VIA_SERIAL."
#endif
#if ENABLED(SOFT_RESET_ON_KILL) && !BUTTON_EXISTS(ENC)
#error "An encoder button is required or SOFT_RESET_ON_KILL will reset the printer without notice!"
#endif
/**
* I2C bus
*/
@@ -2443,6 +2453,10 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
#error "GRAPHICAL_TFT_UPSCALE must be 2, 3, or 4."
#endif
#if BOTH(CHIRON_TFT_STANDARD, CHIRON_TFT_NEW)
#error "Please select only one of CHIRON_TFT_STANDARD or CHIRON_TFT_NEW."
#endif
/**
* Some boards forbid the use of -1 Native USB
*/
@@ -2842,7 +2856,7 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
#if HAS_MOTOR_CURRENT_I2C
#if BOTH(DIGIPOT_MCP4018, DIGIPOT_MCP4451)
#error "Enable only one of DIGIPOT_MCP4018 or DIGIPOT_MCP4451."
#elif !MB(MKS_SBASE) \
#elif !MB(MKS_SBASE, AZTEEG_X5_GT, AZTEEG_X5_MINI, AZTEEG_X5_MINI_WIFI) \
&& (!defined(DIGIPOTS_I2C_SDA_X) || !defined(DIGIPOTS_I2C_SDA_Y) || !defined(DIGIPOTS_I2C_SDA_Z) || !defined(DIGIPOTS_I2C_SDA_E0) || !defined(DIGIPOTS_I2C_SDA_E1))
#error "DIGIPOT_MCP4018/4451 requires DIGIPOTS_I2C_SDA_* pins to be defined."
#endif
@@ -3023,8 +3037,10 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
"BACKLASH_COMPENSATION can only apply to " STRINGIFY(NORMAL_AXIS) " on a MarkForged system.");
#elif IS_CORE
constexpr float backlash_arr[] = BACKLASH_DISTANCE_MM;
static_assert(!backlash_arr[CORE_AXIS_1] && !backlash_arr[CORE_AXIS_2],
#ifndef CORE_BACKLASH
static_assert(!backlash_arr[CORE_AXIS_1] && !backlash_arr[CORE_AXIS_2],
"BACKLASH_COMPENSATION can only apply to " STRINGIFY(NORMAL_AXIS) " with your CORE system.");
#endif
#endif
#endif
@@ -3287,6 +3303,13 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
#undef _CLEAN_ASSERT
#endif
/**
* Sanity check for MIXING_EXTRUDER & DISTINCT_E_FACTORS these are not compatible
*/
#if ENABLED(MIXING_EXTRUDER) && ENABLED(DISTINCT_E_FACTORS)
#error "MIXING_EXTRUDER can't be used with DISTINCT_E_FACTORS. But you may use SINGLENOZZLE with DISTINCT_E_FACTORS."
#endif
/**
* Sanity check for valid stepper driver types
*/
+1 -1
View File
@@ -42,7 +42,7 @@
* version was tagged.
*/
#ifndef STRING_DISTRIBUTION_DATE
#define STRING_DISTRIBUTION_DATE "2021-04-18"
#define STRING_DISTRIBUTION_DATE "2021-05-04"
#endif
/**
+8 -6
View File
@@ -486,7 +486,9 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
CENTER_OR_SCROLL(STRING_SPLASH_LINE3, 1500);
#endif
}
}
void MarlinUI::bootscreen_completion(const millis_t) {
lcd.clear();
safe_delay(100);
set_custom_characters(CHARSET_INFO);
@@ -525,15 +527,15 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char prefix, const bool blink) {
#if HAS_HEATED_BED
const bool isBed = TERN(HAS_HEATED_CHAMBER, heater_id == H_BED, heater_id < 0);
const celsius_t t1 = (isBed ? thermalManager.degBed() : thermalManager.degHotend(heater_id)),
const celsius_t t1 = (isBed ? thermalManager.wholeDegBed() : thermalManager.wholeDegHotend(heater_id)),
t2 = (isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater_id));
#else
const celsius_t t1 = thermalManager.degHotend(heater_id), t2 = thermalManager.degTargetHotend(heater_id);
const celsius_t t1 = thermalManager.wholeDegHotend(heater_id), t2 = thermalManager.degTargetHotend(heater_id);
#endif
if (prefix >= 0) lcd_put_wchar(prefix);
lcd_put_u8str(i16tostr3rj(t1));
lcd_put_u8str(t1 < 0 ? "err" : i16tostr3rj(t1));
lcd_put_wchar('/');
#if !HEATER_IDLE_HANDLER
@@ -557,11 +559,11 @@ FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char pr
#if HAS_COOLER
FORCE_INLINE void _draw_cooler_status(const char prefix, const bool blink) {
const float t1 = thermalManager.degCooler(), t2 = thermalManager.degTargetCooler();
const celsius_t t2 = thermalManager.degTargetCooler();
if (prefix >= 0) lcd_put_wchar(prefix);
lcd_put_u8str(i16tostr3rj(t1 + 0.5));
lcd_put_u8str(i16tostr3rj(thermalManager.wholeDegCooler()));
lcd_put_wchar('/');
#if !HEATER_IDLE_HANDLER
@@ -574,7 +576,7 @@ FORCE_INLINE void _draw_cooler_status(const char prefix, const bool blink) {
}
else
#endif
lcd_put_u8str(i16tostr3left(t2 + 0.5));
lcd_put_u8str(i16tostr3left(t2));
if (prefix >= 0) {
lcd_put_wchar(LCD_STR_DEGREE[0]);
+7 -4
View File
@@ -397,7 +397,10 @@ static void center_text_P(PGM_P pstart, uint8_t y) {
center_text_P(PSTR(MARLIN_WEBSITE_URL), 4);
picBits = ICON_LOGO;
lcd.print_screen();
safe_delay(1500);
}
void MarlinUI::bootscreen_completion(const millis_t sofar) {
if ((BOOTSCREEN_TIMEOUT) > sofar) safe_delay((BOOTSCREEN_TIMEOUT) - sofar);
}
#endif // SHOW_BOOTSCREEN
@@ -434,10 +437,10 @@ FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char *p
uint8_t pic_hot_bits;
#if HAS_HEATED_BED
const bool isBed = heater_id < 0;
const celsius_t t1 = (isBed ? thermalManager.degBed() : thermalManager.degHotend(heater_id)),
const celsius_t t1 = (isBed ? thermalManager.wholeDegBed() : thermalManager.wholeDegHotend(heater_id)),
t2 = (isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater_id));
#else
const celsius_t t1 = thermalManager.degHotend(heater_id), t2 = thermalManager.degTargetHotend(heater_id);
const celsius_t t1 = thermalManager.wholeDegHotend(heater_id), t2 = thermalManager.degTargetHotend(heater_id);
#endif
#if HOTENDS < 2
@@ -803,7 +806,7 @@ void MarlinUI::draw_status_screen() {
if (!PanelDetected) return;
lcd.setCursor((LCD_WIDTH - 14) / 2, row + 1);
lcd.write(LCD_STR_THERMOMETER[0]); lcd_put_u8str_P(PSTR(" E")); lcd.write('1' + extruder); lcd.write(' ');
lcd.print(i16tostr3rj(thermalManager.degHotend(extruder))); lcd.write(LCD_STR_DEGREE[0]); lcd.write('/');
lcd.print(i16tostr3rj(thermalManager.wholeDegHotend(extruder))); lcd.write(LCD_STR_DEGREE[0]); lcd.write('/');
lcd.print(i16tostr3rj(thermalManager.degTargetHotend(extruder))); lcd.write(LCD_STR_DEGREE[0]);
lcd.print_line();
}
+8 -4
View File
@@ -281,7 +281,9 @@
#define STATUS_HOTEND8_WIDTH STATUS_HOTEND7_WIDTH
#endif
constexpr uint8_t status_hotend_width[HOTENDS] = ARRAY_N(HOTENDS, STATUS_HOTEND1_WIDTH, STATUS_HOTEND2_WIDTH, STATUS_HOTEND3_WIDTH, STATUS_HOTEND4_WIDTH, STATUS_HOTEND5_WIDTH, STATUS_HOTEND6_WIDTH, STATUS_HOTEND7_WIDTH, STATUS_HOTEND8_WIDTH);
#define _SHNAME(N,T) STATUS_HOTEND##N##_##T,
constexpr uint8_t status_hotend_width[HOTENDS] = { REPEAT2_S(1, INCREMENT(HOTENDS), _SHNAME, WIDTH) };
#define STATUS_HOTEND_WIDTH(N) status_hotend_width[N]
#ifndef STATUS_HOTEND1_BYTEWIDTH
@@ -309,7 +311,7 @@
#define STATUS_HOTEND8_BYTEWIDTH BW(STATUS_HOTEND8_WIDTH)
#endif
constexpr uint8_t status_hotend_bytewidth[HOTENDS] = ARRAY_N(HOTENDS, STATUS_HOTEND1_BYTEWIDTH, STATUS_HOTEND2_BYTEWIDTH, STATUS_HOTEND3_BYTEWIDTH, STATUS_HOTEND4_BYTEWIDTH, STATUS_HOTEND5_BYTEWIDTH, STATUS_HOTEND6_BYTEWIDTH, STATUS_HOTEND7_BYTEWIDTH, STATUS_HOTEND8_BYTEWIDTH);
constexpr uint8_t status_hotend_bytewidth[HOTENDS] = { REPEAT2_S(1, INCREMENT(HOTENDS), _SHNAME, BYTEWIDTH) };
#define STATUS_HOTEND_BYTEWIDTH(N) status_hotend_bytewidth[N]
#ifndef STATUS_HOTEND1_X
@@ -339,7 +341,7 @@
#define STATUS_HOTEND8_X STATUS_HOTEND7_X + STATUS_HEATERS_XSPACE
#endif
constexpr uint8_t status_hotend_x[HOTENDS] = ARRAY_N(HOTENDS, STATUS_HOTEND1_X, STATUS_HOTEND2_X, STATUS_HOTEND3_X, STATUS_HOTEND4_X, STATUS_HOTEND5_X, STATUS_HOTEND6_X, STATUS_HOTEND7_X, STATUS_HOTEND8_X);
constexpr uint8_t status_hotend_x[HOTENDS] = { REPEAT2_S(1, INCREMENT(HOTENDS), _SHNAME, X) };
#define STATUS_HOTEND_X(N) status_hotend_x[N]
#elif HAS_MULTI_HOTEND
#define STATUS_HOTEND_X(N) ((N) ? STATUS_HOTEND2_X : STATUS_HOTEND1_X)
@@ -370,13 +372,15 @@
#ifndef STATUS_HOTEND8_TEXT_X
#define STATUS_HOTEND8_TEXT_X STATUS_HOTEND7_TEXT_X + STATUS_HEATERS_XSPACE
#endif
constexpr uint8_t status_hotend_text_x[] = ARRAY_N(HOTENDS, STATUS_HOTEND1_TEXT_X, STATUS_HOTEND2_TEXT_X, STATUS_HOTEND3_TEXT_X, STATUS_HOTEND4_TEXT_X, STATUS_HOTEND5_TEXT_X, STATUS_HOTEND6_TEXT_X, STATUS_HOTEND7_TEXT_X, STATUS_HOTEND8_TEXT_X);
constexpr uint8_t status_hotend_text_x[HOTENDS] = { REPEAT2_S(1, INCREMENT(HOTENDS), _SHNAME, TEXT_X) };
#define STATUS_HOTEND_TEXT_X(N) status_hotend_text_x[N]
#else
#define STATUS_HOTEND_TEXT_X(N) (STATUS_HOTEND1_X + 6 + (N) * (STATUS_HEATERS_XSPACE))
#endif
#endif
#undef _SHNAME
#if STATUS_HOTEND_BITMAPS > 1 && DISABLED(STATUS_HOTEND_NUMBERLESS)
#define TEST_BITMAP_OFF status_hotend1_a_bmp
#define TEST_BITMAP_ON status_hotend1_b_bmp
+8 -4
View File
@@ -174,6 +174,7 @@ bool MarlinUI::detected() { return true; }
// Two-part needed to display all info
constexpr bool two_part = ((LCD_PIXEL_HEIGHT) - (START_BMPHEIGHT)) < ((MENU_FONT_ASCENT) * 2);
constexpr uint8_t bootscreen_pages = 1 + two_part;
// Draw the static Marlin bootscreen from a u8g loop
// or the animated boot screen within its own u8g loop
@@ -232,10 +233,9 @@ bool MarlinUI::detected() { return true; }
// Show the Marlin bootscreen, with the u8g loop and delays
void MarlinUI::show_marlin_bootscreen() {
constexpr uint8_t pages = two_part ? 2 : 1;
for (uint8_t q = pages; q--;) {
for (uint8_t q = bootscreen_pages; q--;) {
draw_marlin_bootscreen(q == 0);
safe_delay((BOOTSCREEN_TIMEOUT) / pages);
if (q) safe_delay((BOOTSCREEN_TIMEOUT) / bootscreen_pages);
}
}
@@ -244,6 +244,10 @@ bool MarlinUI::detected() { return true; }
show_marlin_bootscreen();
}
void MarlinUI::bootscreen_completion(const millis_t sofar) {
if ((BOOTSCREEN_TIMEOUT) / bootscreen_pages > sofar) safe_delay((BOOTSCREEN_TIMEOUT) / bootscreen_pages - sofar);
}
#endif // SHOW_BOOTSCREEN
#if ENABLED(LIGHTWEIGHT_UI)
@@ -324,7 +328,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
lcd_put_wchar(LCD_PIXEL_WIDTH - 11 * (MENU_FONT_WIDTH), row_y2, 'E');
lcd_put_wchar((char)('1' + extruder));
lcd_put_wchar(' ');
lcd_put_u8str(i16tostr3rj(thermalManager.degHotend(extruder)));
lcd_put_u8str(i16tostr3rj(thermalManager.wholeDegHotend(extruder)));
lcd_put_wchar('/');
if (get_blink() || !thermalManager.heater_idle[extruder].timed_out)
+12 -8
View File
@@ -186,10 +186,14 @@
#define PROGRESS_BAR_WIDTH (LCD_PIXEL_WIDTH - PROGRESS_BAR_X)
FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, const uint8_t ty) {
const char *str = i16tostr3rj(temp);
const uint8_t len = str[0] != ' ' ? 3 : str[1] != ' ' ? 2 : 1;
lcd_put_u8str(tx - len * (INFO_FONT_WIDTH) / 2 + 1, ty, &str[3-len]);
lcd_put_wchar(LCD_STR_DEGREE[0]);
if (temp < 0)
lcd_put_u8str(tx - 3 * (INFO_FONT_WIDTH) / 2 + 1, ty, "err");
else {
const char *str = i16tostr3rj(temp);
const uint8_t len = str[0] != ' ' ? 3 : str[1] != ' ' ? 2 : 1;
lcd_put_u8str(tx - len * (INFO_FONT_WIDTH) / 2 + 1, ty, &str[3-len]);
lcd_put_wchar(LCD_STR_DEGREE[0]);
}
}
#if DO_DRAW_FLOWMETER
@@ -213,7 +217,7 @@ FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, co
const uint8_t tx = STATUS_HOTEND_TEXT_X(heater_id);
const celsius_t temp = thermalManager.degHotend(heater_id),
const celsius_t temp = thermalManager.wholeDegHotend(heater_id),
target = thermalManager.degTargetHotend(heater_id);
#if DISABLED(STATUS_HOTEND_ANIM)
@@ -310,7 +314,7 @@ FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, co
const uint8_t tx = STATUS_BED_TEXT_X;
const celsius_t temp = thermalManager.degBed(),
const celsius_t temp = thermalManager.wholeDegBed(),
target = thermalManager.degTargetBed();
#if ENABLED(STATUS_HEAT_PERCENT) || DISABLED(STATUS_BED_ANIM)
@@ -380,14 +384,14 @@ FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, co
_draw_centered_temp(thermalManager.degTargetChamber(), STATUS_CHAMBER_TEXT_X, 7);
#endif
if (PAGE_CONTAINS(28 - INFO_FONT_ASCENT, 28 - 1))
_draw_centered_temp(thermalManager.degChamber(), STATUS_CHAMBER_TEXT_X, 28);
_draw_centered_temp(thermalManager.wholeDegChamber(), STATUS_CHAMBER_TEXT_X, 28);
}
#endif
#if DO_DRAW_COOLER
FORCE_INLINE void _draw_cooler_status() {
if (PAGE_CONTAINS(28 - INFO_FONT_ASCENT, 28 - 1))
_draw_centered_temp(thermalManager.degCooler(), STATUS_COOLER_TEXT_X, 28);
_draw_centered_temp(thermalManager.wholeDegCooler(), STATUS_COOLER_TEXT_X, 28);
}
#endif
@@ -721,14 +721,14 @@ void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) {
const duration_t elapsed = print_job_timer.duration();
duration_t remaining = TERN0(USE_M73_REMAINING_TIME, ui.get_remaining_time());
const uint16_t feedrate_perc = feedrate_percentage;
const celsius_t extruder_1_temp = thermalManager.degHotend(0),
const celsius_t extruder_1_temp = thermalManager.wholeDegHotend(0),
extruder_1_target = thermalManager.degTargetHotend(0);
#if HAS_MULTI_HOTEND
const celsius_t extruder_2_temp = thermalManager.degHotend(1),
const celsius_t extruder_2_temp = thermalManager.wholeDegHotend(1),
extruder_2_target = thermalManager.degTargetHotend(1);
#endif
#if HAS_HEATED_BED
const celsius_t bed_temp = thermalManager.degBed(),
const celsius_t bed_temp = thermalManager.wholeDegBed(),
bed_target = thermalManager.degTargetBed();
#endif
@@ -83,7 +83,8 @@ TFT_IO tftio;
#define X_HI (UPSCALE(TFT_PIXEL_OFFSET_X, WIDTH) - 1)
#define Y_HI (UPSCALE(TFT_PIXEL_OFFSET_Y, HEIGHT) - 1)
// see https://ee-programming-notepad.blogspot.com/2016/10/16-bit-color-generator-picker.html
// 16 bit color generator: https://ee-programming-notepad.blogspot.com/2016/10/16-bit-color-generator-picker.html
// RGB565 color picker: https://trolsoft.ru/en/articles/rgb565-color-picker
#define COLOR_BLACK 0x0000 // #000000
#define COLOR_WHITE 0xFFFF // #FFFFFF
@@ -91,7 +92,7 @@ TFT_IO tftio;
#define COLOR_GREY 0x7BEF // #808080
#define COLOR_DARKGREY 0x4208 // #404040
#define COLOR_DARKGREY2 0x39E7 // #303030
#define COLOR_DARK 0x0003 // Some dark color
#define COLOR_DARK 0x0003 // #000019
#define COLOR_RED 0xF800 // #FF0000
#define COLOR_LIME 0x7E00 // #00FF00
+366 -37
View File
@@ -154,18 +154,20 @@ typedef struct {
select_t select_page{0}, select_file{0}, select_print{0}, select_prepare{0}
, select_control{0}, select_axis{0}, select_temp{0}, select_motion{0}, select_tune{0}
, select_PLA{0}, select_ABS{0}
, select_advset{0}, select_PLA{0}, select_ABS{0}
, select_speed{0}
, select_acc{0}
, select_jerk{0}
, select_step{0}
, select_item{0}
;
uint8_t index_file = MROWS,
index_prepare = MROWS,
index_control = MROWS,
index_leveling = MROWS,
index_tune = MROWS;
index_tune = MROWS,
index_advset = MROWS;
bool dwin_abort_flag = false; // Flag to reset feedrate, return to Home
@@ -462,12 +464,21 @@ void Erase_Menu_Text(const uint8_t line) {
DWIN_Draw_Rectangle(1, Color_Bg_Black, LBLX, MBASE(line) - 14, 271, MBASE(line) + 28);
}
void Draw_Menu_Line(const uint8_t line, const uint8_t icon=0, const char * const label=nullptr) {
void Draw_Menu_Item(const uint8_t line, const uint8_t icon=0, const char * const label=nullptr, bool more=false) {
if (label) DWIN_Draw_String(false, false, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(line) - 1, (char*)label);
if (icon) Draw_Menu_Icon(line, icon);
if (more) Draw_More_Icon(line);
}
void Draw_Menu_Line(const uint8_t line, const uint8_t icon=0, const char * const label=nullptr, bool more=false) {
Draw_Menu_Item(line, icon, label, more);
DWIN_Draw_Line(Line_Color, 16, MBASE(line) + 33, 256, MBASE(line) + 34);
}
void Draw_Chkb_Line(const uint8_t line, const bool mode) {
DWIN_Draw_Checkbox(Color_White, Color_Bg_Black, 225, MBASE(line) - 1, mode);
}
// The "Back" label is always on the first line
void Draw_Back_Label() {
if (HMI_IsChinese())
@@ -516,7 +527,8 @@ inline bool Apply_Encoder(const ENCODER_DiffState &encoder_diffState, auto &valr
#define CONTROL_CASE_SAVE (CONTROL_CASE_MOVE + ENABLED(EEPROM_SETTINGS))
#define CONTROL_CASE_LOAD (CONTROL_CASE_SAVE + ENABLED(EEPROM_SETTINGS))
#define CONTROL_CASE_RESET (CONTROL_CASE_LOAD + ENABLED(EEPROM_SETTINGS))
#define CONTROL_CASE_INFO (CONTROL_CASE_RESET + 1)
#define CONTROL_CASE_ADVSET (CONTROL_CASE_RESET + 1)
#define CONTROL_CASE_INFO (CONTROL_CASE_ADVSET + 1)
#define CONTROL_CASE_TOTAL CONTROL_CASE_INFO
#define TUNE_CASE_SPEED 1
@@ -539,6 +551,13 @@ inline bool Apply_Encoder(const ENCODER_DiffState &encoder_diffState, auto &valr
#define PREHEAT_CASE_SAVE (PREHEAT_CASE_FAN + ENABLED(EEPROM_SETTINGS))
#define PREHEAT_CASE_TOTAL PREHEAT_CASE_SAVE
#define ADVSET_CASE_HOMEOFF 1
#define ADVSET_CASE_PROBEOFF (ADVSET_CASE_HOMEOFF + ENABLED(HAS_ONESTEP_LEVELING))
#define ADVSET_CASE_HEPID (ADVSET_CASE_PROBEOFF + ENABLED(HAS_HOTEND))
#define ADVSET_CASE_BEDPID (ADVSET_CASE_HEPID + ENABLED(HAS_HEATED_BED))
#define ADVSET_CASE_PWRLOSSR (ADVSET_CASE_BEDPID + ENABLED(POWER_LOSS_RECOVERY))
#define ADVSET_CASE_TOTAL ADVSET_CASE_PWRLOSSR
//
// Draw Menus
//
@@ -770,26 +789,36 @@ void Draw_Control_Menu() {
DWIN_Frame_TitleCopy(1, 128, 2, 176, 12); // "Control"
#endif
#ifdef USE_STRING_TITLES
DWIN_Draw_Label(CLINE(CONTROL_CASE_TEMP), GET_TEXT_F(MSG_TEMPERATURE));
DWIN_Draw_Label(CLINE(CONTROL_CASE_MOVE), GET_TEXT_F(MSG_MOTION));
if (CVISI(CONTROL_CASE_TEMP)) DWIN_Draw_Label(CLINE(CONTROL_CASE_TEMP), GET_TEXT_F(MSG_TEMPERATURE));
if (CVISI(CONTROL_CASE_MOVE)) DWIN_Draw_Label(CLINE(CONTROL_CASE_MOVE), GET_TEXT_F(MSG_MOTION));
#if ENABLED(EEPROM_SETTINGS)
DWIN_Draw_Label(CLINE(CONTROL_CASE_SAVE), GET_TEXT_F(MSG_STORE_EEPROM));
DWIN_Draw_Label(CLINE(CONTROL_CASE_LOAD), GET_TEXT_F(MSG_LOAD_EEPROM));
DWIN_Draw_Label(CLINE(CONTROL_CASE_RESET), GET_TEXT_F(MSG_RESTORE_DEFAULTS));
if (CVISI(CONTROL_CASE_SAVE)) DWIN_Draw_Label(CLINE(CONTROL_CASE_SAVE), GET_TEXT_F(MSG_STORE_EEPROM));
if (CVISI(CONTROL_CASE_LOAD)) DWIN_Draw_Label(CLINE(CONTROL_CASE_LOAD), GET_TEXT_F(MSG_LOAD_EEPROM));
if (CVISI(CONTROL_CASE_RESET)) DWIN_Draw_Label(CLINE(CONTROL_CASE_RESET), GET_TEXT_F(MSG_RESTORE_DEFAULTS));
#endif
#else
DWIN_Frame_AreaCopy(1, 1, 89, 83, 101, LBLX, CLINE(CONTROL_CASE_TEMP)); // Temperature >
DWIN_Frame_AreaCopy(1, 84, 89, 128, 99, LBLX, CLINE(CONTROL_CASE_MOVE)); // Motion >
if (CVISI(CONTROL_CASE_TEMP)) DWIN_Frame_AreaCopy(1, 1, 89, 83, 101, LBLX, CLINE(CONTROL_CASE_TEMP)); // Temperature >
if (CVISI(CONTROL_CASE_MOVE)) DWIN_Frame_AreaCopy(1, 84, 89, 128, 99, LBLX, CLINE(CONTROL_CASE_MOVE)); // Motion >
#if ENABLED(EEPROM_SETTINGS)
DWIN_Frame_AreaCopy(1, 148, 89, 268, 101, LBLX , CLINE(CONTROL_CASE_SAVE)); // "Store Configuration"
DWIN_Frame_AreaCopy(1, 26, 104, 57, 114, LBLX , CLINE(CONTROL_CASE_LOAD)); // "Read"
DWIN_Frame_AreaCopy(1, 182, 89, 268, 101, LBLX + 34, CLINE(CONTROL_CASE_LOAD)); // "Configuration"
DWIN_Frame_AreaCopy(1, 59, 104, 93, 114, LBLX , CLINE(CONTROL_CASE_RESET)); // "Reset"
DWIN_Frame_AreaCopy(1, 182, 89, 268, 101, LBLX + 37, CLINE(CONTROL_CASE_RESET)); // "Configuration"
if (CVISI(CONTROL_CASE_SAVE)) DWIN_Frame_AreaCopy(1, 148, 89, 268, 101, LBLX , CLINE(CONTROL_CASE_SAVE)); // "Store Configuration"
if (CVISI(CONTROL_CASE_LOAD)) {
DWIN_Frame_AreaCopy(1, 26, 104, 57, 114, LBLX , CLINE(CONTROL_CASE_LOAD)); // "Read"
DWIN_Frame_AreaCopy(1, 182, 89, 268, 101, LBLX + 34, CLINE(CONTROL_CASE_LOAD)); // "Configuration"
}
if (CVISI(CONTROL_CASE_RESET)) {
DWIN_Frame_AreaCopy(1, 59, 104, 93, 114, LBLX , CLINE(CONTROL_CASE_RESET)); // "Reset"
DWIN_Frame_AreaCopy(1, 182, 89, 268, 101, LBLX + 37, CLINE(CONTROL_CASE_RESET)); // "Configuration"
}
#endif
#endif
}
if (CVISI(CONTROL_CASE_ADVSET)) {
DWIN_Draw_Label(CLINE(CONTROL_CASE_ADVSET), GET_TEXT_F(MSG_ADVANCED_SETTINGS)); // Advanced Settings
Draw_More_Icon(CSCROL(CONTROL_CASE_ADVSET));
Draw_Menu_Line(CSCROL(CONTROL_CASE_ADVSET), ICON_AdvSet);
}
if (CVISI(CONTROL_CASE_INFO)) Item_Control_Info(CLINE(CONTROL_CASE_INFO));
if (select_control.now && CVISI(select_control.now))
@@ -1583,7 +1612,7 @@ void _draw_xyz_position(const bool force) {
void update_variable() {
#if HAS_HOTEND
static celsius_t _hotendtemp = 0, _hotendtarget = 0;
const celsius_t hc = thermalManager.degHotend(0),
const celsius_t hc = thermalManager.wholeDegHotend(0),
ht = thermalManager.degTargetHotend(0);
const bool _new_hotend_temp = _hotendtemp != hc,
_new_hotend_target = _hotendtarget != ht;
@@ -1592,7 +1621,7 @@ void update_variable() {
#endif
#if HAS_HEATED_BED
static celsius_t _bedtemp = 0, _bedtarget = 0;
const celsius_t bc = thermalManager.degBed(),
const celsius_t bc = thermalManager.wholeDegBed(),
bt = thermalManager.degTargetBed();
const bool _new_bed_temp = _bedtemp != bc,
_new_bed_target = _bedtarget != bt;
@@ -1785,7 +1814,7 @@ void Draw_SDItem(const uint16_t item, int16_t row=-1) {
#if ENABLED(SCROLL_LONG_FILENAMES)
void Draw_SDItem_Shifted(int8_t &shift) {
void Draw_SDItem_Shifted(uint8_t &shift) {
// Limit to the number of chars past the cutoff
const size_t len = strlen(shift_name);
NOMORE(shift, _MAX(len - MENU_CHAR_LIMIT, 0U));
@@ -1880,7 +1909,7 @@ void Draw_Status_Area(const bool with_update) {
#if HAS_HOTEND
DWIN_ICON_Show(ICON, ICON_HotendTemp, 10, 383);
DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 28, 384, thermalManager.degHotend(0));
DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 28, 384, thermalManager.wholeDegHotend(0));
DWIN_Draw_String(false, false, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 25 + 3 * STAT_CHR_W + 5, 384, F("/"));
DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 25 + 4 * STAT_CHR_W + 6, 384, thermalManager.degTargetHotend(0));
@@ -1891,7 +1920,7 @@ void Draw_Status_Area(const bool with_update) {
#if HAS_HEATED_BED
DWIN_ICON_Show(ICON, ICON_BedTemp, 10, 416);
DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 28, 417, thermalManager.degBed());
DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 28, 417, thermalManager.wholeDegBed());
DWIN_Draw_String(false, false, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 25 + 3 * STAT_CHR_W + 5, 417, F("/"));
DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, Color_White, Color_Bg_Black, 3, 25 + 4 * STAT_CHR_W + 6, 417, thermalManager.degTargetBed());
#endif
@@ -2060,7 +2089,7 @@ void HMI_SelectFile() {
if (ELAPSED(ms, shift_ms)) {
const bool was_reset = shift_amt < 0;
shift_ms = ms + 375UL + was_reset * 250UL; // ms per character
int8_t shift_new = shift_amt + 1; // Try to shift by...
uint8_t shift_new = shift_amt + 1; // Try to shift by...
Draw_SDItem_Shifted(shift_new); // Draw the item
if (!was_reset && shift_new == 0) // Was it limited to 0?
shift_ms = 0; // No scrolling needed
@@ -2269,9 +2298,6 @@ void HMI_PauseOrStop() {
if (HMI_flag.select_flag) {
HMI_flag.pause_action = true;
ICON_Continue();
#if ENABLED(POWER_LOSS_RECOVERY)
if (recovery.enabled) recovery.save(true);
#endif
queue.inject_P(PSTR("M25"));
}
else {
@@ -2331,6 +2357,62 @@ void Draw_Move_Menu() {
LOOP_L_N(i, 3 + ENABLED(HAS_HOTEND)) Draw_Menu_Line(i + 1, ICON_MoveX + i);
}
void Draw_AdvSet_Menu() {
Clear_Main_Window();
#if ADVSET_CASE_TOTAL >= 6
const int16_t scroll = MROWS - index_advset; // Scrolled-up lines
#define ASCROL(L) (scroll + (L))
#else
#define ASCROL(L) (L)
#endif
#define AVISI(L) WITHIN(ASCROL(L), 0, MROWS)
Draw_Title(GET_TEXT_F(MSG_ADVANCED_SETTINGS));
if (AVISI(0)) Draw_Back_First(select_advset.now == 0);
if (AVISI(ADVSET_CASE_HOMEOFF)) Draw_Menu_Line(ASCROL(ADVSET_CASE_HOMEOFF), ICON_HomeOff, GET_TEXT(MSG_SET_HOME_OFFSETS),true); // Home Offset >
#if HAS_ONESTEP_LEVELING
if (AVISI(ADVSET_CASE_PROBEOFF)) Draw_Menu_Line(ASCROL(ADVSET_CASE_PROBEOFF), ICON_ProbeOff, GET_TEXT(MSG_ZPROBE_OFFSETS),true); // Probe Offset >
#endif
if (AVISI(ADVSET_CASE_HEPID)) Draw_Menu_Line(ASCROL(ADVSET_CASE_HEPID), ICON_PIDNozzle, "Hotend PID", false); // Nozzle PID
if (AVISI(ADVSET_CASE_BEDPID)) Draw_Menu_Line(ASCROL(ADVSET_CASE_BEDPID), ICON_PIDbed, "Bed PID", false); // Bed PID
#if ENABLED(POWER_LOSS_RECOVERY)
if (AVISI(ADVSET_CASE_PWRLOSSR)) {
Draw_Menu_Line(ASCROL(ADVSET_CASE_PWRLOSSR), ICON_Motion, "Power-loss recovery", false); // Power-loss recovery
Draw_Chkb_Line(ASCROL(ADVSET_CASE_PWRLOSSR), recovery.enabled);
}
#endif
if (select_advset.now) Draw_Menu_Cursor(ASCROL(select_advset.now));
}
void Draw_HomeOff_Menu() {
Clear_Main_Window();
Draw_Title(GET_TEXT_F(MSG_SET_HOME_OFFSETS)); // Home Offsets
Draw_Back_First(select_item.now == 0);
Draw_Menu_Line(1, ICON_HomeOffX, GET_TEXT(MSG_HOME_OFFSET_X)); // Home X Offset
DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 3, 1, 216, MBASE(1), HMI_ValueStruct.Home_OffX_scaled);
Draw_Menu_Line(2, ICON_HomeOffY, GET_TEXT(MSG_HOME_OFFSET_Y)); // Home Y Offset
DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 3, 1, 216, MBASE(2), HMI_ValueStruct.Home_OffY_scaled);
Draw_Menu_Line(3, ICON_HomeOffZ, GET_TEXT(MSG_HOME_OFFSET_Z)); // Home Y Offset
DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 3, 1, 216, MBASE(3), HMI_ValueStruct.Home_OffZ_scaled);
if (select_item.now) Draw_Menu_Cursor(select_item.now);
}
#if HAS_ONESTEP_LEVELING
void Draw_ProbeOff_Menu() {
Clear_Main_Window();
Draw_Title(GET_TEXT_F(MSG_ZPROBE_OFFSETS)); // Probe Offsets
Draw_Back_First(select_item.now == 0);
Draw_Menu_Line(1, ICON_ProbeOffX, GET_TEXT(MSG_ZPROBE_XOFFSET)); // Probe X Offset
DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 3, 1, 216, MBASE(1), HMI_ValueStruct.Probe_OffX_scaled);
Draw_Menu_Line(2, ICON_ProbeOffY, GET_TEXT(MSG_ZPROBE_YOFFSET)); // Probe Y Offset
DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 3, 1, 216, MBASE(2), HMI_ValueStruct.Probe_OffY_scaled);
if (select_item.now) Draw_Menu_Cursor(select_item.now);
}
#endif
#include "../../../libs/buzzer.h"
void HMI_AudioFeedback(const bool success=true) {
@@ -2568,14 +2650,20 @@ void HMI_Control() {
if (select_control.inc(1 + CONTROL_CASE_TOTAL)) {
if (select_control.now > MROWS && select_control.now > index_control) {
index_control = select_control.now;
// Scroll up and draw a blank bottom line
Scroll_Menu(DWIN_SCROLL_UP);
Draw_Menu_Icon(MROWS, ICON_Temperature + index_control - 1);
Draw_More_Icon(CONTROL_CASE_TEMP + MROWS - index_control); // Temperature >
Draw_More_Icon(CONTROL_CASE_MOVE + MROWS - index_control); // Motion >
if (index_control > MROWS) {
Draw_More_Icon(CONTROL_CASE_INFO + MROWS - index_control); // Info >
Item_Control_Info(MBASE(CONTROL_CASE_INFO - 1));
switch (index_control) { // Last menu items
case CONTROL_CASE_ADVSET: // Advance Settings >
Draw_Menu_Item(MROWS, ICON_AdvSet, GET_TEXT(MSG_ADVANCED_SETTINGS), true);
break;
case CONTROL_CASE_INFO: // Info >
Draw_Menu_Item(MROWS, ICON_Info, GET_TEXT(MSG_INFO_SCREEN), true);
break;
default: break;
}
}
else {
Move_Highlight(1, select_control.now + MROWS - index_control);
@@ -2587,12 +2675,17 @@ void HMI_Control() {
if (select_control.now < index_control - MROWS) {
index_control--;
Scroll_Menu(DWIN_SCROLL_DOWN);
if (index_control == MROWS)
switch (index_control) { // First menu items
case MROWS :
Draw_Back_First();
else
Draw_Menu_Line(0, ICON_Temperature + select_control.now - 1);
Draw_More_Icon(0 + MROWS - index_control + 1); // Temperature >
Draw_More_Icon(1 + MROWS - index_control + 1); // Motion >
break;
case MROWS + 1: // Temperature >
Draw_Menu_Line(0, ICON_Temperature, GET_TEXT(MSG_TEMPERATURE), true);
break;
case MROWS + 2: // Move >
Draw_Menu_Line(0, ICON_Motion, GET_TEXT(MSG_MOTION), true);
default: break;
}
}
else {
Move_Highlight(-1, select_control.now + MROWS - index_control);
@@ -2630,6 +2723,11 @@ void HMI_Control() {
HMI_AudioFeedback();
break;
#endif
case CONTROL_CASE_ADVSET: // Advance Settings
checkkey = AdvSet;
select_advset.reset();
Draw_AdvSet_Menu();
break;
case CONTROL_CASE_INFO: // Info
checkkey = Info;
Draw_Info_Menu();
@@ -2715,7 +2813,7 @@ void HMI_AxisMove() {
case 4: // Extruder
// window tips
#ifdef PREVENT_COLD_EXTRUSION
if (thermalManager.degHotend(0) < EXTRUDE_MINTEMP) {
if (thermalManager.tooColdToExtrude(0)) {
HMI_flag.ETempTooLow_flag = true;
Popup_Window_ETempTooLow();
DWIN_UpdateLCD();
@@ -3233,6 +3331,219 @@ void HMI_Motion() {
DWIN_UpdateLCD();
}
/* Advanced Settings */
void HMI_AdvSet() {
ENCODER_DiffState encoder_diffState = get_encoder_state();
if (encoder_diffState == ENCODER_DIFF_NO) return;
// Avoid flicker by updating only the previous menu
if (encoder_diffState == ENCODER_DIFF_CW) {
if (select_advset.inc(1 + ADVSET_CASE_TOTAL)) {
if (select_advset.now > MROWS && select_advset.now > index_advset) {
index_advset = select_advset.now;
// Scroll up and draw a blank bottom line
Scroll_Menu(DWIN_SCROLL_UP);
//switch (index_advset) { // Redraw last menu items
// default: break;
//}
}
else {
Move_Highlight(1, select_advset.now + MROWS - index_advset);
}
}
}
else if (encoder_diffState == ENCODER_DIFF_CCW) {
if (select_advset.dec()) {
if (select_advset.now < index_advset - MROWS) {
index_advset--;
Scroll_Menu(DWIN_SCROLL_DOWN);
//switch (index_advset) { // Redraw first menu items
// default: break;
//}
}
else {
Move_Highlight(-1, select_advset.now + MROWS - index_advset);
}
}
}
else if (encoder_diffState == ENCODER_DIFF_ENTER) {
switch (select_advset.now) {
case 0: // Back
checkkey = Control;
select_control.set(CONTROL_CASE_ADVSET);
index_control = CONTROL_CASE_ADVSET;
Draw_Control_Menu();
break;
#if HAS_HOME_OFFSET
case ADVSET_CASE_HOMEOFF: // Home Offsets
checkkey = HomeOff;
select_item.reset();
HMI_ValueStruct.Home_OffX_scaled = home_offset[X_AXIS] * 10;
HMI_ValueStruct.Home_OffY_scaled = home_offset[Y_AXIS] * 10;
HMI_ValueStruct.Home_OffZ_scaled = home_offset[Z_AXIS] * 10;
Draw_HomeOff_Menu();
break;
#endif
#if HAS_ONESTEP_LEVELING
case ADVSET_CASE_PROBEOFF: // Probe Offsets
checkkey = ProbeOff;
select_item.reset();
HMI_ValueStruct.Probe_OffX_scaled = probe.offset.x * 10;
HMI_ValueStruct.Probe_OffY_scaled = probe.offset.y * 10;
Draw_ProbeOff_Menu();
break;
#endif
#if HAS_HOTEND
case ADVSET_CASE_HEPID: // Nozzle PID Autotune
thermalManager.setTargetHotend(ui.material_preset[0].hotend_temp, 0);
thermalManager.PID_autotune(ui.material_preset[0].hotend_temp, H_E0, 10, true);
break;
#endif
#if HAS_HEATED_BED
case ADVSET_CASE_BEDPID: // Bed PID Autotune
thermalManager.setTargetBed(ui.material_preset[0].bed_temp);
thermalManager.PID_autotune(ui.material_preset[0].bed_temp, H_BED, 10, true);
break;
#endif
#if ENABLED(POWER_LOSS_RECOVERY)
case ADVSET_CASE_PWRLOSSR: // Power-loss recovery
recovery.enable(!recovery.enabled);
Draw_Chkb_Line(ADVSET_CASE_PWRLOSSR + MROWS - index_advset, recovery.enabled);
break;
#endif
default: break;
}
}
DWIN_UpdateLCD();
}
#if HAS_HOME_OFFSET
/* Home Offset */
void HMI_HomeOff() {
ENCODER_DiffState encoder_diffState = get_encoder_state();
if (encoder_diffState == ENCODER_DIFF_NO) return;
// Avoid flicker by updating only the previous menu
if (encoder_diffState == ENCODER_DIFF_CW) {
if (select_item.inc(1 + 3)) Move_Highlight(1, select_item.now);
}
else if (encoder_diffState == ENCODER_DIFF_CCW) {
if (select_item.dec()) Move_Highlight(-1, select_item.now);
}
else if (encoder_diffState == ENCODER_DIFF_ENTER) {
switch (select_item.now) {
case 0: // Back
checkkey = AdvSet;
select_advset.set(ADVSET_CASE_HOMEOFF);
Draw_AdvSet_Menu();
break;
case 1: // Home Offset X
checkkey = HomeOffX;
DWIN_Draw_Signed_Float(font8x16, Select_Color, 3, 1, 216, MBASE(1), HMI_ValueStruct.Home_OffX_scaled);
EncoderRate.enabled = true;
break;
case 2: // Home Offset Y
checkkey = HomeOffY;
DWIN_Draw_Signed_Float(font8x16, Select_Color, 3, 1, 216, MBASE(2), HMI_ValueStruct.Home_OffY_scaled);
EncoderRate.enabled = true;
break;
case 3: // Home Offset Z
checkkey = HomeOffZ;
DWIN_Draw_Signed_Float(font8x16, Select_Color, 3, 1, 216, MBASE(3), HMI_ValueStruct.Home_OffZ_scaled);
EncoderRate.enabled = true;
break;
default: break;
}
}
DWIN_UpdateLCD();
}
void HMI_HomeOffN(const AxisEnum axis, float &posScaled, const_float_t lo, const_float_t hi) {
ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze();
if (encoder_diffState != ENCODER_DIFF_NO) {
if (Apply_Encoder(encoder_diffState, posScaled)) {
checkkey = HomeOff;
EncoderRate.enabled = false;
set_home_offset(axis, posScaled / 10);
DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 3, 1, 216, MBASE(select_item.now), posScaled);
return;
}
LIMIT(posScaled, lo, hi);
DWIN_Draw_Signed_Float(font8x16, Select_Color, 3, UNITFDIGITS, 216, MBASE(select_item.now), posScaled);
}
}
void HMI_HomeOffX() { HMI_HomeOffN(X_AXIS, HMI_ValueStruct.Home_OffX_scaled, -500, 500); }
void HMI_HomeOffY() { HMI_HomeOffN(Y_AXIS, HMI_ValueStruct.Home_OffY_scaled, -500, 500); }
void HMI_HomeOffZ() { HMI_HomeOffN(Z_AXIS, HMI_ValueStruct.Home_OffZ_scaled, -20, 20); }
#endif // HAS_HOME_OFFSET
#if HAS_ONESTEP_LEVELING
/*Probe Offset */
void HMI_ProbeOff() {
ENCODER_DiffState encoder_diffState = get_encoder_state();
if (encoder_diffState == ENCODER_DIFF_NO) return;
// Avoid flicker by updating only the previous menu
if (encoder_diffState == ENCODER_DIFF_CW) {
if (select_item.inc(1 + 2)) Move_Highlight(1, select_item.now);
}
else if (encoder_diffState == ENCODER_DIFF_CCW) {
if (select_item.dec()) Move_Highlight(-1, select_item.now);
}
else if (encoder_diffState == ENCODER_DIFF_ENTER) {
switch (select_item.now) {
case 0: // Back
checkkey = AdvSet;
select_advset.set(ADVSET_CASE_PROBEOFF);
Draw_AdvSet_Menu();
break;
case 1: // Probe Offset X
checkkey = ProbeOffX;
DWIN_Draw_Signed_Float(font8x16, Select_Color, 3, 1, 216, MBASE(1), HMI_ValueStruct.Probe_OffX_scaled);
EncoderRate.enabled = true;
break;
case 2: // Probe Offset X
checkkey = ProbeOffY;
DWIN_Draw_Signed_Float(font8x16, Select_Color, 3, 1, 216, MBASE(2), HMI_ValueStruct.Probe_OffY_scaled);
EncoderRate.enabled = true;
break;
}
}
DWIN_UpdateLCD();
}
void HMI_ProbeOffN(float &posScaled, float &offset_ref) {
ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze();
if (encoder_diffState != ENCODER_DIFF_NO) {
if (Apply_Encoder(encoder_diffState, posScaled)) {
checkkey = ProbeOff;
EncoderRate.enabled = false;
offset_ref = posScaled / 10;
DWIN_Draw_Signed_Float(font8x16, Color_Bg_Black, 3, 1, 216, MBASE(select_item.now), posScaled);
return;
}
LIMIT(posScaled, -500, 500);
DWIN_Draw_Signed_Float(font8x16, Select_Color, 3, UNITFDIGITS, 216, MBASE(select_item.now), posScaled);
}
}
void HMI_ProbeOffX() { HMI_ProbeOffN(HMI_ValueStruct.Probe_OffX_scaled, probe.offset.x); }
void HMI_ProbeOffY() { HMI_ProbeOffN(HMI_ValueStruct.Probe_OffY_scaled, probe.offset.y); }
#endif // HAS_ONESTEP_LEVELING
/* Info */
void HMI_Info() {
ENCODER_DiffState encoder_diffState = get_encoder_state();
@@ -3741,6 +4052,18 @@ void DWIN_HandleScreen() {
case AxisMove: HMI_AxisMove(); break;
case TemperatureID: HMI_Temperature(); break;
case Motion: HMI_Motion(); break;
case AdvSet: HMI_AdvSet(); break;
#if HAS_HOME_OFFSET
case HomeOff: HMI_HomeOff(); break;
case HomeOffX: HMI_HomeOffX(); break;
case HomeOffY: HMI_HomeOffY(); break;
case HomeOffZ: HMI_HomeOffZ(); break;
#endif
#if HAS_ONESTEP_LEVELING
case ProbeOff: HMI_ProbeOff(); break;
case ProbeOffX: HMI_ProbeOffX(); break;
case ProbeOffY: HMI_ProbeOffY(); break;
#endif
case Info: HMI_Info(); break;
case Tune: HMI_Tune(); break;
#if HAS_PREHEAT
@@ -3807,4 +4130,10 @@ void DWIN_StatusChanged(const char *text) {
DWIN_UpdateLCD();
}
// GUI extension
void DWIN_Draw_Checkbox(uint16_t color, uint16_t bcolor, uint16_t x, uint16_t y, bool mode=false) {
DWIN_Draw_String(false,true,font8x16,Select_Color,bcolor,x+4,y,F(mode ? "x" : " "));
DWIN_Draw_Rectangle(0,color,x+2,y+2,x+17,y+17);
}
#endif // DWIN_CREALITY_LCD
+27
View File
@@ -63,10 +63,20 @@ enum processID : uint8_t {
MaxJerk_value,
Step,
Step_value,
HomeOff,
HomeOffX,
HomeOffY,
HomeOffZ,
// Last Process ID
Last_Prepare,
// Advance Settings
AdvSet,
ProbeOff,
ProbeOffX,
ProbeOffY,
// Back Process ID
Back_Main,
Back_Print,
@@ -197,6 +207,17 @@ enum processID : uint8_t {
#define ICON_Info_0 90
#define ICON_Info_1 91
#define ICON_AdvSet ICON_Language
#define ICON_HomeOff ICON_AdvSet
#define ICON_HomeOffX ICON_StepX
#define ICON_HomeOffY ICON_StepY
#define ICON_HomeOffZ ICON_StepZ
#define ICON_ProbeOff ICON_AdvSet
#define ICON_ProbeOffX ICON_StepX
#define ICON_ProbeOffY ICON_StepY
#define ICON_PIDNozzle ICON_SetEndTemp
#define ICON_PIDbed ICON_SetBedTemp
/**
* 3-.0The font size, 0x00-0x09, corresponds to the font size below:
* 0x00=6*12 0x01=8*16 0x02=10*20 0x03=12*24 0x04=14*28
@@ -256,6 +277,11 @@ typedef struct {
#endif
float offset_value = 0;
int8_t show_mode = 0; // -1: Temperature control 0: Printing temperature
float Home_OffX_scaled = 0;
float Home_OffY_scaled = 0;
float Home_OffZ_scaled = 0;
float Probe_OffX_scaled = 0;
float Probe_OffY_scaled = 0;
} HMI_value_t;
#define DWIN_CHINESE 123
@@ -378,6 +404,7 @@ void DWIN_Update();
void EachMomentUpdate();
void DWIN_HandleScreen();
void DWIN_StatusChanged(const char *text);
void DWIN_Draw_Checkbox(uint16_t color, uint16_t bcolor, uint16_t x, uint16_t y, bool mode /* = false*/);
inline void DWIN_StartHoming() { HMI_flag.home_flag = true; }
@@ -88,6 +88,10 @@ namespace ExtUI {
// memcpy(&myDataStruct, buff, sizeof(myDataStruct));
}
void onPostprocessSettings() {
// Called after loading or resetting stored settings
}
void onConfigurationStoreWritten(bool success) {
// Called after the entire EEPROM has been written,
// whether successful or not.
@@ -79,6 +79,10 @@ namespace ExtUI {
// memcpy(&myDataStruct, buff, sizeof(myDataStruct));
}
void onPostprocessSettings() {
// Called after loading or resetting stored settings
}
void onConfigurationStoreWritten(bool success) {
// Called after the entire EEPROM has been written,
// whether successful or not.
@@ -96,6 +100,10 @@ namespace ExtUI {
void onMeshUpdate(const int8_t xpos, const int8_t ypos, const_float_t zval) {
// Called when any mesh points are updated
}
void onMeshUpdate(const int8_t xpos, const int8_t ypos, probe_state_t state) {
// Called when any mesh points are updated
}
#endif
#if ENABLED(POWER_LOSS_RECOVERY)
+4
View File
@@ -98,6 +98,10 @@ namespace ExtUI {
// memcpy(&myDataStruct, buff, sizeof(myDataStruct));
}
void onPostprocessSettings() {
// Called after loading or resetting stored settings
}
void onConfigurationStoreWritten(bool success) {
// Called after the entire EEPROM has been written,
// whether successful or not.
+4
View File
@@ -84,6 +84,10 @@ namespace ExtUI {
// memcpy(&myDataStruct, buff, sizeof(myDataStruct));
}
void onPostprocessSettings() {
// Called after loading or resetting stored settings
}
void onConfigurationStoreWritten(bool success) {
// Called after the entire EEPROM has been written,
// whether successful or not.
@@ -26,139 +26,233 @@
* Extensible_UI implementation for Anycubic Chiron
* Written By Nick Wells, 2020 [https://github.com/SwiftNick]
* (not affiliated with Anycubic, Ltd.)
*
* The AC panel wants files in block of 4 and can only display a flat list
* This library allows full folder traversal or flat file display and supports both standerd and new style panels.
*
* ## Old Style TFT panel
* Supported chars {}[]-+=_"$%^&*()~<>|
* Max display length 22 chars
* Max path len 29 chars
* (DOS 8.3 filepath max 29chars)
* (long filepath Max 22)
*
* ## New TFT Panel Format file display format
* Supported chars {}[]-+=_!"$%^&*()~<>\|
* Max display length 26 chars
* Max path len 29 chars
* (DOS 8.3 filepath must end '.GCO')
* (long filepath must end '.gcode')
*
*/
/***************************************************************************
* The AC panel wants files in block of 4 and can only display a flat list *
* This library allows full folder traversal. *
***************************************************************************/
#include "../../../../inc/MarlinConfigPre.h"
#if ENABLED(ANYCUBIC_LCD_CHIRON)
#include "FileNavigator.h"
#include "chiron_tft.h"
using namespace ExtUI;
#define DEBUG_OUT ACDEBUG(AC_FILE)
#include "../../../../core/debug_out.h"
namespace Anycubic {
FileNavigator filenavigator;
FileNavigator filenavigator;
FileList FileNavigator::filelist; // Instance of the Marlin file API
uint16_t FileNavigator::lastpanelindex;
uint16_t FileNavigator::currentindex; // override the panel request
uint8_t FileNavigator::currentfolderdepth;
uint16_t FileNavigator::currentfolderindex[MAX_FOLDER_DEPTH]; // track folder pos for iteration
char FileNavigator::currentfoldername[MAX_PATH_LEN + 1]; // Current folder path
FileList FileNavigator::filelist; // Instance of the Marlin file API
char FileNavigator::currentfoldername[MAX_PATH_LEN]; // Current folder path
uint16_t FileNavigator::lastindex;
uint8_t FileNavigator::folderdepth;
uint16_t FileNavigator::currentindex; // override the panel request
FileNavigator::FileNavigator() { reset(); }
FileNavigator::FileNavigator() { reset(); }
void FileNavigator::reset() {
DEBUG_ECHOLNPGM("reset()");
currentfoldername[0] = '\0';
currentfolderdepth = 0;
currentindex = 0;
lastpanelindex = 0;
ZERO(currentfolderindex);
void FileNavigator::reset() {
currentfoldername[0] = '\0';
folderdepth = 0;
currentindex = 0;
lastindex = 0;
// Start at root folder
while (!filelist.isAtRootDir()) filelist.upDir();
refresh();
// Start at root folder
while (!filelist.isAtRootDir()) filelist.upDir();
refresh();
}
void FileNavigator::refresh() { filelist.refresh(); }
void FileNavigator::changeDIR(const char *folder) {
if (currentfolderdepth >= MAX_FOLDER_DEPTH) return; // limit the folder depth
DEBUG_ECHOLNPAIR("FD:" , folderdepth, " FP:",currentindex, " currentfolder:", currentfoldername, " enter:", folder);
currentfolderindex[currentfolderdepth] = currentindex;
strcat(currentfoldername, folder);
strcat(currentfoldername, "/");
filelist.changeDir(folder);
currentfolderdepth++;
currentindex = 0;
}
void FileNavigator::upDIR() {
DEBUG_ECHOLNPAIR("upDIR() from D:", currentfolderdepth, " N:", currentfoldername);
if (!filelist.isAtRootDir()) {
filelist.upDir();
currentfolderdepth--;
currentindex = currentfolderindex[currentfolderdepth]; // restore last position in the folder
filelist.seek(currentindex); // restore file information
}
void FileNavigator::refresh() { filelist.refresh(); }
// Remove the child folder from the stored path
if (currentfolderdepth == 0)
currentfoldername[0] = '\0';
else {
char * const pos = strchr(currentfoldername, '/');
*(pos + 1) = '\0';
}
}
void FileNavigator::getFiles(uint16_t index) {
uint8_t files = 4;
if (index == 0) currentindex = 0;
// Each time we change folder we reset the file index to 0 and keep track
// of the current position as the TFT panel isnt aware of folders trees.
if (index > 0) {
--currentindex; // go back a file to take account of the .. added to the root.
if (index > lastindex)
currentindex += files;
void FileNavigator::skiptofileindex(uint16_t skip) {
if (skip == 0) return;
while (skip > 0) {
if (filelist.seek(currentindex)) {
DEBUG_ECHOLNPAIR("CI:", currentindex, " FD:", currentfolderdepth, " N:", skip, " ", filelist.longFilename());
if (!filelist.isDir()) {
skip--;
currentindex++;
}
else
currentindex = currentindex < 4 ? 0 : currentindex - files;
changeDIR(filelist.shortFilename());
} // valid file
if (currentindex == filelist.count()) {
if (currentfolderdepth > 0) {
upDIR();
currentindex++;
}
else break; // end of root folder
} // end of folder
} // files needed
// No more files available.
}
#if ENABLED(AC_SD_FOLDER_VIEW) // SD Folder navigation
void FileNavigator::getFiles(uint16_t index, panel_type_t paneltype, uint8_t filesneeded) {
if (index == 0) currentindex = 0;
// Each time we change folder we reset the file index to 0 and keep track
// of the current position, since the TFT panel isn't aware of folder trees.
if (index > 0) {
--currentindex; // go back a file to take account of the .. we added to the root.
if (index > lastpanelindex)
currentindex += filesneeded;
else
currentindex = currentindex < 4 ? 0 : currentindex - filesneeded;
}
lastindex = index;
lastpanelindex = index;
#if ACDEBUG(AC_FILE)
SERIAL_ECHOLNPAIR("index=", index, " currentindex=", currentindex);
#endif
DEBUG_ECHOLNPAIR("index=", index, " currentindex=", currentindex);
if (currentindex == 0 && folderdepth > 0) { // Add a link to go up a folder
TFTSer.println("<<");
TFTSer.println("..");
files--;
if (currentindex == 0 && currentfolderdepth > 0) { // Add a link to go up a folder
// The new panel ignores entries that don't end in .GCO or .gcode so add and pad them.
if (paneltype == AC_panel_new) {
TFTSer.println("<<.GCO");
Chiron.SendtoTFTLN(PSTR(".. .gcode"));
}
else {
TFTSer.println("<<");
TFTSer.println("..");
}
filesneeded--;
}
for (uint16_t seek = currentindex; seek < currentindex + files; seek++) {
for (uint16_t seek = currentindex; seek < currentindex + filesneeded; seek++) {
if (filelist.seek(seek)) {
sendFile();
#if ACDEBUG(AC_FILE)
SERIAL_ECHOLNPAIR("-", seek, " '", filelist.longFilename(), "' '", currentfoldername, "", filelist.shortFilename(), "'\n");
#endif
sendFile(paneltype);
DEBUG_ECHOLNPAIR("-", seek, " '", filelist.longFilename(), "' '", currentfoldername, "", filelist.shortFilename(), "'");
}
}
}
void FileNavigator::sendFile() {
// send the file and folder info to the panel
// this info will be returned when the file is selected
// Permitted special characters in file name -_*#~
// Panel can display 22 characters per line
void FileNavigator::sendFile(panel_type_t paneltype) {
if (filelist.isDir()) {
//TFTSer.print(currentfoldername);
TFTSer.println(filelist.shortFilename());
TFTSer.print(filelist.shortFilename());
TFTSer.println("/");
// Add mandatory tags for new panel otherwise lines are ignored.
if (paneltype == AC_panel_new) {
TFTSer.print(filelist.shortFilename());
TFTSer.println(".GCO");
TFTSer.print(filelist.shortFilename());
TFTSer.write('/');
// Make sure we fill all 29 chars of the display line to clear the text buffer otherwise the last line is still visible
for (int8_t i = strlen(filelist.shortFilename()); i < 19; i++)
TFTSer.write(' ');
TFTSer.println(".gcode");
}
else {
TFTSer.println(filelist.shortFilename());
TFTSer.print(filelist.shortFilename());
TFTSer.write('/');
TFTSer.println();
}
}
else {
// Logical Name
else { // Not DIR
TFTSer.write('/');
if (folderdepth > 0) TFTSer.print(currentfoldername);
if (currentfolderdepth > 0) TFTSer.print(currentfoldername);
TFTSer.println(filelist.shortFilename());
TFTSer.print(filelist.longFilename());
// Display Name
TFTSer.println(filelist.longFilename());
// Make sure we fill all 29 chars of the display line to clear the text buffer otherwise the last line is still visible
if (paneltype == AC_panel_new)
for (int8_t i = strlen(filelist.longFilename()); i < 26; i++)
TFTSer.write(' ');
TFTSer.println();
}
}
void FileNavigator::changeDIR(char *folder) {
#if ACDEBUG(AC_FILE)
SERIAL_ECHOLNPAIR("currentfolder: ", currentfoldername, " New: ", folder);
#endif
if (folderdepth >= MAX_FOLDER_DEPTH) return; // limit the folder depth
strcat(currentfoldername, folder);
strcat(currentfoldername, "/");
filelist.changeDir(folder);
refresh();
folderdepth++;
currentindex = 0;
}
} // AC_SD_FOLDER_VIEW
void FileNavigator::upDIR() {
filelist.upDir();
refresh();
folderdepth--;
currentindex = 0;
// Remove the last child folder from the stored path
if (folderdepth == 0) {
currentfoldername[0] = '\0';
#else // Flat file list
void FileNavigator::getFiles(uint16_t index, panel_type_t paneltype, uint8_t filesneeded) {
DEBUG_ECHOLNPAIR("getFiles() I:", index," L:", lastpanelindex);
// if we're searching backwards, jump back to start and search forward
if (index < lastpanelindex) {
reset();
skiptofileindex(index);
}
else {
char *pos = nullptr;
for (uint8_t f = 0; f < folderdepth; f++)
pos = strchr(currentfoldername, '/');
lastpanelindex = index;
*(pos + 1) = '\0';
}
#if ACDEBUG(AC_FILE)
SERIAL_ECHOLNPAIR("depth: ", folderdepth, " currentfoldername: ", currentfoldername);
#endif
while (filesneeded > 0) {
if (filelist.seek(currentindex)) {
if (!filelist.isDir()) {
sendFile(paneltype);
filesneeded--;
currentindex++;
}
else
changeDIR(filelist.shortFilename());
} // valid file
if (currentindex == filelist.count()) {
if (currentfolderdepth > 0) {
upDIR();
currentindex++;
}
else break; // end of root folder
} // end of folder
} // files needed
// No more files available.
}
char* FileNavigator::getCurrentFolderName() { return currentfoldername; }
}
void FileNavigator::sendFile(panel_type_t paneltype) {
TFTSer.write('/');
if (currentfolderdepth > 0) TFTSer.print(currentfoldername);
TFTSer.println(filelist.shortFilename());
if (currentfolderdepth > 0) TFTSer.print(currentfoldername);
TFTSer.println(filelist.longFilename());
DEBUG_ECHOLNPAIR("/", currentfoldername, "", filelist.shortFilename(), " ", filelist.longFilename());
}
#endif // Flat file list
} // Anycubic namespace
#endif // ANYCUBIC_LCD_CHIRON
@@ -39,13 +39,13 @@ namespace Anycubic {
class FileNavigator {
public:
FileNavigator();
void reset();
void getFiles(uint16_t, panel_type_t, uint8_t filesneeded=4);
void upDIR();
void changeDIR(const char *);
void sendFile(panel_type_t);
void refresh();
void skiptofileindex(uint16_t);
static void reset();
static void getFiles(uint16_t, panel_type_t, uint8_t filesneeded=4);
static void upDIR();
static void changeDIR(const char *);
static void sendFile(panel_type_t);
static void refresh();
static void skiptofileindex(uint16_t);
static FileList filelist;
private:
@@ -53,7 +53,7 @@ class FileNavigator {
static uint16_t currentindex;
static uint8_t currentfolderdepth;
static uint16_t currentfolderindex[MAX_FOLDER_DEPTH];
static char currentfoldername[MAX_PATH_LEN];
static char currentfoldername[MAX_PATH_LEN + 1];
};
extern FileNavigator filenavigator;
@@ -43,25 +43,27 @@
namespace Anycubic {
ChironTFT Chiron;
#if AUTO_DETECT_CHIRON_TFT
panel_type_t ChironTFT::panel_type = AC_panel_unknown;
#endif
last_error_t ChironTFT::last_error;
printer_state_t ChironTFT::printer_state;
paused_state_t ChironTFT::pause_state;
heater_state_t ChironTFT::hotend_state;
heater_state_t ChironTFT::hotbed_state;
xy_uint8_t ChironTFT::selectedmeshpoint;
char ChironTFT::selectedfile[MAX_PATH_LEN];
char ChironTFT::panel_command[MAX_CMND_LEN];
char ChironTFT::selectedfile[MAX_PATH_LEN + 1];
char ChironTFT::panel_command[MAX_CMND_LEN + 1];
uint8_t ChironTFT::command_len;
float ChironTFT::live_Zoffset;
file_menu_t ChironTFT::file_menu;
ChironTFT Chiron;
ChironTFT::ChironTFT(){}
void ChironTFT::Startup() {
selectedfile[0] = '\0';
panel_command[0] = '\0';
command_len = 0;
last_error = AC_error_none;
printer_state = AC_printer_idle;
pause_state = AC_paused_idle;
hotend_state = AC_heater_off;
@@ -80,27 +82,41 @@ void ChironTFT::Startup() {
// Filament runout is handled by Marlin settings in Configuration.h
// opt_set FIL_RUNOUT_STATE HIGH // Pin state indicating that filament is NOT present.
// opt_enable FIL_RUNOUT_PULLUP
TFTSer.begin(115200);
// wait for the TFT panel to initialise and finish the animation
delay_ms(250);
// There are different panels for the Chiron with slightly different commands
// So we need to know what we are working with.
// Panel type can be defined otherwise detect it automatically
if (panel_type == AC_panel_unknown) DetectPanelType();
// Signal Board has reset
SendtoTFTLN(AC_msg_main_board_has_reset);
safe_delay(200);
// Enable leveling and Disable end stops during print
// as Z home places nozzle above the bed so we need to allow it past the end stops
injectCommands_P(AC_cmnd_enable_leveling);
// Startup tunes are defined in Tunes.h
//PlayTune(BEEPER_PIN, Anycubic_PowerOn, 1);
PlayTune(BEEPER_PIN, GB_PowerOn, 1);
PlayTune(BEEPER_PIN, TERN(AC_DEFAULT_STARTUP_TUNE, Anycubic_PowerOn, GB_PowerOn), 1);
#if ACDEBUGLEVEL
SERIAL_ECHOLNPAIR("AC Debug Level ", ACDEBUGLEVEL);
#endif
SendtoTFTLN(AC_msg_ready);
}
void ChironTFT::DetectPanelType() {
#if AUTO_DETECT_CHIRON_TFT
// Send a query to the TFT
SendtoTFTLN(AC_Test_for_OldPanel); // The panel will respond with 'SXY 480 320'
SendtoTFTLN(AC_Test_for_NewPanel); // the panel will respond with '[0]=0 ' to '[19]=0 '
#endif
}
void ChironTFT::IdleLoop() {
if (ReadTFTCommand()) {
ProcessPanelRequest();
@@ -123,15 +139,16 @@ void ChironTFT::MediaEvent(media_event_t event) {
switch (event) {
case AC_media_inserted:
SendtoTFTLN(AC_msg_sd_card_inserted);
break;
break;
case AC_media_removed:
SendtoTFTLN(AC_msg_sd_card_removed);
break;
break;
case AC_media_error:
last_error = AC_error_noSD;
SendtoTFTLN(AC_msg_no_sd_card);
break;
break;
}
}
@@ -170,8 +187,8 @@ void ChironTFT::FilamentRunout() {
SERIAL_ECHOLNPAIR("FilamentRunout() printer_state ", printer_state);
#endif
// 1 Signal filament out
last_error = AC_error_filament_runout;
SendtoTFTLN(isPrintingFromMedia() ? AC_msg_filament_out_alert : AC_msg_filament_out_block);
//printer_state = AC_printer_filament_out;
PlayTune(BEEPER_PIN, FilamentOut, 1);
}
@@ -278,14 +295,23 @@ void ChironTFT::StatusChange(const char * const msg) {
SendtoTFTLN(AC_msg_bed_heating);
hotbed_state = AC_heater_temp_set;
}
else if (strcmp_P(msg, MARLIN_msg_EEPROM_version) == 0) {
last_error = AC_error_EEPROM;
}
}
}
void ChironTFT::PowerLossRecovery() {
printer_state = AC_printer_resuming_from_power_outage; // Play tune to notify user we can recover.
last_error = AC_error_powerloss;
PlayTune(BEEPER_PIN, SOS, 1);
SERIAL_ECHOLNPGM("Resuming from power outage...");
SERIAL_ECHOLNPGM("Select SD file then press resume");
SERIAL_ECHOLNPGM_P(AC_msg_powerloss_recovery);
}
void ChironTFT::PrintComplete() {
SendtoTFT(AC_msg_print_complete);
printer_state = AC_printer_idle;
setSoftEndstopState(true); // enable endstops
}
void ChironTFT::SendtoTFT(PGM_P str) { // A helper to print PROGMEM string to the panel
@@ -319,39 +345,42 @@ bool ChironTFT::ReadTFTCommand() {
command_len++;
}
if (command_ready) {
panel_command[command_len] = 0x00;
if (command_ready || command_len == MAX_CMND_LEN) {
panel_command[command_len] = '\0';
#if ACDEBUG(AC_ALL)
SERIAL_ECHOLNPAIR("< ", panel_command);
#endif
#if ACDEBUG(AC_SOME)
// Ignore status request commands
uint8_t req = atoi(&panel_command[1]);
if (req > 7 && req != 20) {
SERIAL_ECHOLNPAIR("> ", panel_command);
SERIAL_ECHOLNPAIR("printer_state:", printer_state);
}
SERIAL_ECHOLNPAIR("len(",command_len,") < ", panel_command);
#endif
command_ready = true;
}
return command_ready;
}
int8_t ChironTFT::Findcmndpos(const char * buff, char q) {
int8_t ChironTFT::FindToken(char c) {
int8_t pos = 0;
do { if (buff[pos] == q) return pos; } while (++pos < MAX_CMND_LEN);
do {
if (panel_command[pos] == c) {
#if ACDEBUG(AC_INFO)
SERIAL_ECHOLNPAIR("Tpos:", pos, " ", c);
#endif
return pos;
}
} while(++pos < command_len);
#if ACDEBUG(AC_INFO)
SERIAL_ECHOLNPAIR("Not found: ", c);
#endif
return -1;
}
void ChironTFT::CheckHeaters() {
uint8_t faultDuration = 0;
float temp = 0;
// if the hotend temp is abnormal, confirm state before signalling panel
temp = getActualTemp_celsius(E0);
celsius_float_t temp = getActualTemp_celsius(E0);
while (!WITHIN(temp, HEATER_0_MINTEMP, HEATER_0_MAXTEMP)) {
faultDuration++;
if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) {
SendtoTFTLN(AC_msg_nozzle_temp_abnormal);
last_error = AC_error_abnormal_temp_t0;
SERIAL_ECHOLNPAIR("Extruder temp abnormal! : ", temp);
break;
}
@@ -366,6 +395,7 @@ void ChironTFT::CheckHeaters() {
faultDuration++;
if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) {
SendtoTFTLN(AC_msg_nozzle_temp_abnormal);
last_error = AC_error_abnormal_temp_bed;
SERIAL_ECHOLNPAIR("Bed temp abnormal! : ", temp);
break;
}
@@ -375,7 +405,7 @@ void ChironTFT::CheckHeaters() {
// Update panel with hotend heater status
if (hotend_state != AC_heater_temp_reached) {
if (WITHIN(getActualTemp_celsius(E0) - getTargetTemp_celsius(E0), -1, 1)) {
if (WITHIN(getActualTemp_celsius(E0) - getTargetTemp_celsius(E0), -(TEMP_WINDOW), TEMP_WINDOW)) {
SendtoTFTLN(AC_msg_nozzle_heating_done);
hotend_state = AC_heater_temp_reached;
}
@@ -383,7 +413,7 @@ void ChironTFT::CheckHeaters() {
// Update panel with bed heater status
if (hotbed_state != AC_heater_temp_reached) {
if (WITHIN(getActualTemp_celsius(BED) - getTargetTemp_celsius(BED), -0.5, 0.5)) {
if (WITHIN(getActualTemp_celsius(BED) - getTargetTemp_celsius(BED), -(TEMP_BED_WINDOW), TEMP_BED_WINDOW)) {
SendtoTFTLN(AC_msg_bed_heating_done);
hotbed_state = AC_heater_temp_reached;
}
@@ -396,15 +426,21 @@ void ChironTFT::SendFileList(int8_t startindex) {
SERIAL_ECHOLNPAIR("## SendFileList ## ", startindex);
#endif
SendtoTFTLN(PSTR("FN "));
filenavigator.getFiles(startindex);
filenavigator.getFiles(startindex, panel_type, 4);
SendtoTFTLN(PSTR("END"));
}
void ChironTFT::SelectFile() {
strncpy(selectedfile, panel_command + 4, command_len - 4);
selectedfile[command_len - 5] = '\0';
if (panel_type == AC_panel_new) {
strncpy(selectedfile, panel_command + 4, command_len - 3);
selectedfile[command_len - 4] = '\0';
}
else {
strncpy(selectedfile, panel_command + 4, command_len - 4);
selectedfile[command_len - 5] = '\0';
}
#if ACDEBUG(AC_FILE)
SERIAL_ECHOLNPAIR_F(" Selected File: ",selectedfile);
SERIAL_ECHOLNPAIR(" Selected File: ",selectedfile);
#endif
switch (selectedfile[0]) {
case '/': // Valid file selected
@@ -417,6 +453,9 @@ void ChironTFT::SelectFile() {
SendFileList( 0 );
break;
default: // enter sub folder
// for new panel remove the '.GCO' tag that was added to the end of the path
if (panel_type == AC_panel_new)
selectedfile[strlen(selectedfile) - 4] = '\0';
filenavigator.changeDIR(selectedfile);
SendtoTFTLN(AC_msg_sd_file_open_failed);
SendFileList( 0 );
@@ -424,25 +463,48 @@ void ChironTFT::SelectFile() {
}
}
void ChironTFT::InjectCommandandWait(PGM_P cmd) {
//injectCommands_P(cmnd); queue.enqueue_now_P(cmd);
//SERIAL_ECHOLN(PSTR("Inject>"));
}
void ChironTFT::ProcessPanelRequest() {
// Break these up into logical blocks // as its easier to navigate than one huge switch case!
int8_t req = atoi(&panel_command[1]);
int8_t tpos = FindToken('A');
// Panel request are 'A0' - 'A36'
if (tpos != -1) {
const int8_t req = atoi(&panel_command[tpos+1]);
// Information requests A0 - A8 and A33
if (req <= 8 || req == 33) PanelInfo(req);
// Information requests A0 - A8 and A33
if (req <= 8 || req == 33) PanelInfo(req);
// Simple Actions A9 - A28
else if ( req <= 28) PanelAction(req);
// Simple Actions A9 - A28
else if (req <= 28) PanelAction(req);
// Process Initiation
else if (req <= 34) PanelProcess(req);
// Process Initiation
else if (req <= 36) PanelProcess(req);
}
else {
#if AUTO_DETECT_CHIRON_TFT
// This may be a response to a panel type detection query
if (panel_type == AC_panel_unknown) {
tpos = FindToken('S'); // old panel will respond to 'SIZE' with 'SXY 480 320'
if (tpos != -1) {
if (panel_command[tpos+1]== 'X' && panel_command[tpos+2]=='Y') {
panel_type = AC_panel_standard;
SERIAL_ECHOLNPGM_P(AC_msg_old_panel_detected);
}
}
else {
tpos = FindToken('['); // new panel will respond to 'J200' with '[0]=0'
if (tpos != -1) {
if (panel_command[tpos+1]== '0' && panel_command[tpos+2]==']') {
panel_type = AC_panel_new;
SERIAL_ECHOLNPGM_P(AC_msg_new_panel_detected);
}
}
}
return;
}
#endif
else SendtoTFTLN();
SendtoTFTLN(); // Ignore unknown requests
}
}
void ChironTFT::PanelInfo(uint8_t req) {
@@ -513,7 +575,8 @@ void ChironTFT::PanelInfo(uint8_t req) {
case 33: // A33 Get firmware info
SendtoTFT(PSTR("J33 "));
SendtoTFTLN(PSTR(SHORT_BUILD_VERSION));
// If there is an error recorded, show that instead of the FW version
if (!GetLastError()) SendtoTFTLN(PSTR(SHORT_BUILD_VERSION));
break;
}
}
@@ -567,11 +630,7 @@ void ChironTFT::PanelAction(uint8_t req) {
#if ACDebugLevel >= 1
SERIAL_ECHOLNPAIR_F("Print: ", selectedfile);
#endif
// the card library needs a path starting // but the File api doesn't...
char file[MAX_PATH_LEN];
file[0] = '/';
strcpy(file + 1, selectedfile);
printFile(file);
printFile(selectedfile);
SendtoTFTLN(AC_msg_print_from_sd_card);
} break;
@@ -631,29 +690,24 @@ void ChironTFT::PanelAction(uint8_t req) {
}
break;
case 22: // A22 Move Axis A22 Y +10F3000
// Ignore request if printing
if (!isPrinting()) {
// setAxisPosition_mm() uses pre defined manual feedrates so ignore the feedrate from the panel
setSoftEndstopState(true); // enable endstops
float newposition = atof(&panel_command[6]);
case 22: { // A22 Move Axis
// The commands have changed on the new panel
// Old TFT A22 X -1F1500 A22 X +1F1500
// New TFT A22 X-1.0 F1500 A22 X1.0 F1500
// lets just wrap this in a gcode relative nonprint move and let the controller deal with it
// G91 G0 <panel command> G90
if (!isPrinting()) { // Ignore request if printing
char MoveCmnd[30];
sprintf_P(MoveCmnd, PSTR("G91\nG0%s\nG90"), panel_command + 3);
#if ACDEBUG(AC_ACTION)
SERIAL_ECHOLNPAIR("Nudge ", AS_CHAR(panel_command[4]), " axis ", newposition);
SERIAL_ECHOLNPAIR("Move: ", MoveCmnd);
#endif
switch (panel_command[4]) {
case 'X': setAxisPosition_mm(getAxisPosition_mm(X) + newposition, X); break;
case 'Y': setAxisPosition_mm(getAxisPosition_mm(Y) + newposition, Y); break;
case 'Z': setAxisPosition_mm(getAxisPosition_mm(Z) + newposition, Z); break;
case 'E': // The only time we get this command is from the filament load/unload menu
// the standard movement is too slow so we will use the load unlod GCode to speed it up a bit
if (canMove(E0) && !commandsInQueue())
injectCommands_P(newposition > 0 ? AC_cmnd_manual_load_filament : AC_cmnd_manual_unload_filament);
break;
}
setSoftEndstopState(true); // enable endstops
injectCommands(MoveCmnd);
}
break;
} break;
case 23: // A23 Preheat PLA
// Ignore request if printing
@@ -690,7 +744,9 @@ void ChironTFT::PanelAction(uint8_t req) {
break;
case 26: // A26 Refresh SD
// M22 M21 maybe needed here to reset sd card
if (card.isMounted())card.release();
card.mount();
safe_delay(500);
filenavigator.reset();
break;
@@ -710,8 +766,8 @@ void ChironTFT::PanelProcess(uint8_t req) {
case 29: { // A29 Read Mesh Point A29 X1 Y1
xy_uint8_t pos;
float pos_z;
pos.x = atoi(&panel_command[5]);
pos.y = atoi(&panel_command[8]);
pos.x = atoi(&panel_command[FindToken('X')+1]);
pos.y = atoi(&panel_command[FindToken('Y')+1]);
pos_z = getMeshPoint(pos);
SendtoTFT(PSTR("A29V "));
@@ -743,48 +799,60 @@ void ChironTFT::PanelProcess(uint8_t req) {
}
} break;
case 30: { // A30 Auto leveling
if (panel_command[3] == 'S') { // Start probing
case 30: { // A30 Auto leveling
if (FindToken('S') != -1) { // Start probing New panel adds spaces..
// Ignore request if printing
if (isPrinting())
SendtoTFTLN(AC_msg_probing_not_allowed); // forbid auto leveling
else {
injectCommands_P(PSTR("G28O\nG29"));
printer_state = AC_printer_probing;
SendtoTFTLN(AC_msg_start_probing);
injectCommands_P(PSTR("G28\nG29"));
printer_state = AC_printer_probing;
}
}
else SendtoTFTLN(AC_msg_start_probing);
} break;
else {
SendtoTFTLN(AC_msg_start_probing); // Just enter levelling menu
}
} break;
case 31: { // A31 Adjust all Probe Points
switch (panel_command[3]) {
case 'C': // Restore and apply original offsets
if (!isPrinting()) {
injectCommands_P(PSTR("M501\nM420 S1"));
selectedmeshpoint.x = selectedmeshpoint.y = 99;
}
break;
case 'D': // Save Z Offset tables and restore leveling state
if (!isPrinting()) {
setAxisPosition_mm(1.0,Z);
injectCommands_P(PSTR("M500"));
selectedmeshpoint.x = selectedmeshpoint.y = 99;
}
break;
case 'G': // Get current offset
SendtoTFT(PSTR("A31V "));
// When printing use the live z Offset position
// we will use babystepping to move the print head
if (isPrinting())
TFTSer.println(live_Zoffset);
else {
TFTSer.println(getZOffset_mm());
selectedmeshpoint.x = selectedmeshpoint.y = 99;
}
break;
case 'S': { // Set offset (adjusts all points by value)
float Zshift = atof(&panel_command[4]);
// The tokens can occur in different places on the new panel so we need to find it.
if (FindToken('C') != -1) { // Restore and apply original offsets
if (!isPrinting()) {
injectCommands_P(PSTR("M501\nM420 S1"));
selectedmeshpoint.x = selectedmeshpoint.y = 99;
SERIAL_ECHOLNPGM_P(AC_msg_mesh_changes_abandoned);
}
}
else if (FindToken('D') != -1) { // Save Z Offset tables and restore leveling state
if (!isPrinting()) {
setAxisPosition_mm(1.0,Z); // Lift nozzle before any further movements are made
injectCommands_P(PSTR("M500"));
SERIAL_ECHOLNPGM_P(AC_msg_mesh_changes_saved);
selectedmeshpoint.x = selectedmeshpoint.y = 99;
}
}
else if (FindToken('G') != -1) { // Get current offset
SendtoTFT(PSTR("A31V "));
// When printing use the live z Offset position
// we will use babystepping to move the print head
if (isPrinting())
TFTSer.println(live_Zoffset);
else {
TFTSer.println(getZOffset_mm());
selectedmeshpoint.x = selectedmeshpoint.y = 99;
}
}
else {
int8_t tokenpos = FindToken('S');
if (tokenpos != -1) { // Set offset (adjusts all points by value)
float Zshift = atof(&panel_command[tokenpos+1]);
setSoftEndstopState(false); // disable endstops
// Allow temporary Z position nudging during print
// From the leveling panel use the all points UI to adjust the print pos.
@@ -813,6 +881,9 @@ void ChironTFT::PanelProcess(uint8_t req) {
const xy_uint8_t pos { x, y };
const float currval = getMeshPoint(pos);
setMeshPoint(pos, constrain(currval + Zshift, AC_LOWEST_MESHPOINT_VAL, 2));
#if ACDEBUG(AC_INFO)
SERIAL_ECHOLNPAIR("Change mesh point X", x," Y",y ," from ", currval, " to ", getMeshPoint(pos) );
#endif
}
const float currZOffset = getZOffset_mm();
#if ACDEBUG(AC_INFO)
@@ -878,9 +949,27 @@ void ChironTFT::PanelProcess(uint8_t req) {
}
}
} break;
case 36: // A36 Auto leveling for new TFT bet that was a typo in the panel code!
SendtoTFTLN(AC_msg_start_probing);
break;
}
}
} // Anycubic
bool ChironTFT::GetLastError() {
switch (last_error) {
case AC_error_abnormal_temp_bed: SendtoTFTLN(AC_msg_error_bed_temp); break;
case AC_error_abnormal_temp_t0: SendtoTFTLN(AC_msg_error_hotend_temp); break;
case AC_error_noSD: SendtoTFTLN(AC_msg_error_sd_card); break;
case AC_error_powerloss: SendtoTFTLN(AC_msg_power_loss); break;
case AC_error_EEPROM: SendtoTFTLN(AC_msg_eeprom_version); break;
case AC_error_filament_runout: SendtoTFTLN(AC_msg_filament_out); break;
default: return false;
}
last_error = AC_error_none;
return true;
}
} // Anycubic namespace
#endif // ANYCUBIC_LCD_CHIRON
@@ -33,23 +33,30 @@
#include "../../../../inc/MarlinConfigPre.h"
#include "../../ui_api.h"
#if NONE(CHIRON_TFT_STANDARD, CHIRON_TFT_NEW)
#define AUTO_DETECT_CHIRON_TFT 1
#endif
namespace Anycubic {
class ChironTFT {
private:
static printer_state_t printer_state;
static paused_state_t pause_state;
static heater_state_t hotend_state;
static heater_state_t hotbed_state;
static xy_uint8_t selectedmeshpoint;
static char panel_command[MAX_CMND_LEN];
static uint8_t command_len;
static char selectedfile[MAX_PATH_LEN];
static float live_Zoffset;
static file_menu_t file_menu;
#if AUTO_DETECT_CHIRON_TFT
static panel_type_t panel_type;
#else
static constexpr panel_type_t panel_type = TERN(CHIRON_TFT_NEW, AC_panel_new, AC_panel_standard);
#endif
static last_error_t last_error;
static printer_state_t printer_state;
static paused_state_t pause_state;
static heater_state_t hotend_state;
static heater_state_t hotbed_state;
static xy_uint8_t selectedmeshpoint;
static char panel_command[MAX_CMND_LEN + 1];
static uint8_t command_len;
static char selectedfile[MAX_PATH_LEN + 1];
static float live_Zoffset;
static file_menu_t file_menu;
public:
ChironTFT();
static void Startup();
static void IdleLoop();
static void PrinterKilled(PGM_P,PGM_P);
@@ -59,12 +66,13 @@ class ChironTFT {
static void ConfirmationRequest(const char * const );
static void StatusChange(const char * const );
static void PowerLossRecovery();
private:
static void PrintComplete();
static void SendtoTFT(PGM_P);
static void SendtoTFTLN(PGM_P);
private:
static void DetectPanelType();
static bool ReadTFTCommand();
static int8_t Findcmndpos(const char *, char);
static int8_t FindToken(char);
static void CheckHeaters();
static void SendFileList(int8_t);
static void SelectFile();
@@ -73,8 +81,9 @@ class ChironTFT {
static void PanelInfo(uint8_t);
static void PanelAction(uint8_t);
static void PanelProcess(uint8_t);
static bool GetLastError();
};
extern ChironTFT Chiron;
} // Anycubic
} // Anycubic namespace
@@ -30,7 +30,7 @@
#pragma once
#include "../../../../inc/MarlinConfigPre.h"
//#define ACDEBUGLEVEL 255
//#define ACDEBUGLEVEL 4
#if ACDEBUGLEVEL
// Bit-masks for selective debug:
@@ -54,7 +54,7 @@
#define MAX_PATH_LEN 16 * MAX_FOLDER_DEPTH // Maximum number of characters in a SD file path
#define AC_HEATER_FAULT_VALIDATION_TIME 5 // number of 1/2 second loops before signalling a heater fault
#define AC_LOWEST_MESHPOINT_VAL Z_PROBE_LOW_POINT // The lowest value you can set for a single mesh point offset
#define AC_LOWEST_MESHPOINT_VAL -10 // The lowest value you can set for a single mesh point offset
// TFT panel commands
#define AC_msg_sd_card_inserted PSTR("J00")
@@ -85,6 +85,18 @@
#define AC_msg_probing_complete PSTR("J25")
#define AC_msg_start_probing PSTR("J26")
#define AC_msg_version PSTR("J27")
#define AC_msg_mesh_changes_abandoned PSTR("Mesh changes abandoned, previous mesh restored.")
#define AC_msg_mesh_changes_saved PSTR("Mesh changes saved.")
#define AC_msg_old_panel_detected PSTR("Standard TFT panel detected!")
#define AC_msg_new_panel_detected PSTR("New TFT panel detected!")
#define AC_msg_powerloss_recovery PSTR("Resuming from power outage! select the same SD file then press resume")
// Error messages must not contain spaces
#define AC_msg_error_bed_temp PSTR("Abnormal_bed_temp")
#define AC_msg_error_hotend_temp PSTR("Abnormal_hotend_temp")
#define AC_msg_error_sd_card PSTR("SD_card_error")
#define AC_msg_filament_out PSTR("Filament_runout")
#define AC_msg_power_loss PSTR("Power_failure")
#define AC_msg_eeprom_version PSTR("EEPROM_ver_wrong")
#define MARLIN_msg_start_probing PSTR("Probing Point 1/25")
#define MARLIN_msg_probing_failed PSTR("Probing Failed")
@@ -93,13 +105,14 @@
#define MARLIN_msg_print_aborted PSTR("Print Aborted")
#define MARLIN_msg_extruder_heating PSTR("E Heating...")
#define MARLIN_msg_bed_heating PSTR("Bed Heating...")
#define MARLIN_msg_EEPROM_version PSTR("EEPROM Version Error")
#define MARLIN_msg_nozzle_parked PSTR("Nozzle Parked")
#define MARLIN_msg_heater_timeout PSTR("Heater Timeout")
#define MARLIN_msg_reheating PSTR("Reheating...")
#define MARLIN_msg_reheat_done PSTR("Reheat finished.")
#define MARLIN_msg_filament_purging PSTR("Filament Purging...")
#define MARLIN_msg_special_pause PSTR("PB")
#define AC_cmnd_auto_unload_filament PSTR("M701") // Use Marlin unload routine
#define AC_cmnd_auto_load_filament PSTR("M702 M0 PB") // Use Marlin load routing then pause for user to clean nozzle
@@ -108,6 +121,9 @@
#define AC_cmnd_enable_leveling PSTR("M420SV")
#define AC_cmnd_power_loss_recovery PSTR("G28XYR5\nG28Z") // Lift, home X and Y then home Z when in 'safe' position
#define AC_Test_for_OldPanel PSTR("SIZE") // An old panel will respond with 'SXY 480 320' a new panel wont respond.
#define AC_Test_for_NewPanel PSTR("J200") // A new panel will respond with '[0]=0 [1]=0' to '[19]=0 ' an old panel wont respond
namespace Anycubic {
enum heater_state_t : uint8_t {
AC_heater_off,
@@ -120,6 +136,7 @@ namespace Anycubic {
AC_paused_idle
};
enum printer_state_t : uint8_t {
AC_printer_booting,
AC_printer_idle,
AC_printer_probing,
AC_printer_printing,
@@ -144,4 +161,18 @@ namespace Anycubic {
AC_menu_change_to_file,
AC_menu_change_to_command
};
} // Anycubic
enum panel_type_t : uint8_t {
AC_panel_unknown,
AC_panel_standard,
AC_panel_new
};
enum last_error_t : uint8_t {
AC_error_none,
AC_error_abnormal_temp_t0,
AC_error_abnormal_temp_bed,
AC_error_noSD,
AC_error_powerloss,
AC_error_filament_runout,
AC_error_EEPROM
};
} // Anycubic namespace

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