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

This commit is contained in:
InsanityAutomation
2021-03-20 11:16:35 -04:00
67 changed files with 1911 additions and 259 deletions
+21 -3
View File
@@ -2181,6 +2181,11 @@
//
//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
//
// K.3D Full Graphic Smart Controller
//
//#define K3D_FULL_GRAPHIC_SMART_CONTROLLER
//
// ReprapWorld Graphical LCD
// https://reprapworld.com/?products_details&products_id/1218
@@ -2318,7 +2323,7 @@
//#define OLED_PANEL_TINYBOY2
//
// MKS OLED 1.3" 128×64 FULL GRAPHICS CONTROLLER
// MKS OLED 1.3" 128×64 Full Graphics Controller
// https://reprap.org/wiki/MKS_12864OLED
//
// Tiny, but very sharp OLED display
@@ -2327,7 +2332,7 @@
//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller
//
// Zonestar OLED 128×64 FULL GRAPHICS CONTROLLER
// Zonestar OLED 128×64 Full Graphics Controller
//
//#define ZONESTAR_12864LCD // Graphical (DOGM) with ST7920 controller
//#define ZONESTAR_12864OLED // 1.3" OLED with SH1106 controller (default)
@@ -2344,10 +2349,15 @@
//#define OVERLORD_OLED
//
// FYSETC OLED 2.42" 128×64 FULL GRAPHICS CONTROLLER with WS2812 RGB
// FYSETC OLED 2.42" 128×64 Full Graphics Controller with WS2812 RGB
// Where to find : https://www.aliexpress.com/item/4000345255731.html
//#define FYSETC_242_OLED_12864 // Uses the SSD1309 controller
//
// K.3D SSD1309 OLED 2.42" 128×64 Full Graphics Controller
//
//#define K3D_242_OLED_CONTROLLER // Software SPI
//=============================================================================
//========================== Extensible UI Displays ===========================
//=============================================================================
@@ -2386,6 +2396,14 @@
//#define ANYCUBIC_LCD_DEBUG
#endif
//
// 320x240 Nextion 2.8" serial TFT Resistive Touch Screen NX3224T028
//
//#define NEXTION_TFT
#if ENABLED(NEXTION_TFT)
#define LCD_SERIAL_PORT 1 // Default is 1 for Nextion
#endif
//
// Third-party or vendor-customized controller interfaces.
// Sources should be installed in 'src/lcd/extui'.
+7 -1
View File
@@ -3455,22 +3455,28 @@
//#define CUSTOM_USER_MENU_TITLE "Custom Commands"
#define USER_SCRIPT_DONE "M117 User Script Done"
#define USER_SCRIPT_AUDIBLE_FEEDBACK
//#define USER_SCRIPT_RETURN // Return to status screen after a script
//#define USER_SCRIPT_RETURN // Return to status screen after a script
#define CUSTOM_MENU_ONLY_IDLE // Only show custom menu when the machine is idle
#define USER_DESC_1 "Home & UBL Info"
#define USER_GCODE_1 "G28\nG29W"
//#define USER_CONFIRM_1 // Show a confirmation dialog before this action
#define USER_DESC_2 "Preheat for " PREHEAT_1_LABEL
#define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND)
//#define USER_CONFIRM_2
#define USER_DESC_3 "Preheat for " PREHEAT_2_LABEL
#define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND)
//#define USER_CONFIRM_3
#define USER_DESC_4 "Heat Bed/Home/Level"
#define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29"
//#define USER_CONFIRM_4
#define USER_DESC_5 "Home & Info"
#define USER_GCODE_5 "G28\nM503"
//#define USER_CONFIRM_5
#endif
/**
-6
View File
@@ -29,12 +29,6 @@
#include HAL_PATH(.,HAL.h)
#ifdef SERIAL_PORT_2
#define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
#ifndef I2C_ADDRESS
+1 -1
View File
@@ -40,7 +40,7 @@ void eeprom_init() { BL24CXX::init(); }
// Public functions
// ------------------------
void eeprom_write_byte(uint8_t *pos, unsigned char value) {
void eeprom_write_byte(uint8_t *pos, uint8_t value) {
const unsigned eeprom_address = (unsigned)pos;
return BL24CXX::writeOneByte(eeprom_address, value);
}
+5 -1
View File
@@ -31,7 +31,11 @@
#include <Wire.h>
DefaultSerial1 MSerial0(false);
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X)
#if WITHIN(SERIAL_PORT, 0, 3)
IMPLEMENT_SERIAL(SERIAL_PORT);
#endif
USBSerialType USBSerial(false, SerialUSB);
uint16_t HAL_adc_result;
+8 -2
View File
@@ -51,8 +51,13 @@
#endif
#include "../../core/serial_hook.h"
typedef Serial1Class<decltype(Serial)> DefaultSerial1;
extern DefaultSerial1 MSerial0;
#define Serial0 Serial
#define _DECLARE_SERIAL(X) \
typedef ForwardSerial1Class<decltype(Serial##X)> DefaultSerial##X; \
extern DefaultSerial##X MSerial##X
#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X)
typedef ForwardSerial1Class<decltype(SerialUSB)> USBSerialType;
extern USBSerialType USBSerial;
@@ -62,6 +67,7 @@ extern USBSerialType USBSerial;
#if SERIAL_PORT == -1
#define MYSERIAL1 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
DECLARE_SERIAL(SERIAL_PORT);
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#endif
+1 -1
View File
@@ -31,7 +31,7 @@
#include <Wire.h>
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false)
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X)
#if WITHIN(SERIAL_PORT, 0, 3)
IMPLEMENT_SERIAL(SERIAL_PORT);
+1 -1
View File
@@ -57,7 +57,7 @@
#define Serial0 Serial
#define _DECLARE_SERIAL(X) \
typedef Serial1Class<decltype(Serial##X)> DefaultSerial##X; \
typedef ForwardSerial1Class<decltype(Serial##X)> DefaultSerial##X; \
extern DefaultSerial##X MSerial##X
#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X)
+5 -1
View File
@@ -32,7 +32,11 @@
#include <Wire.h>
DefaultSerial1 MSerial0(false);
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X)
#if WITHIN(SERIAL_PORT, 0, 3)
IMPLEMENT_SERIAL(SERIAL_PORT);
#endif
USBSerialType USBSerial(false, SerialUSB);
uint16_t HAL_adc_result, HAL_adc_select;
+7 -2
View File
@@ -56,8 +56,12 @@
#endif
#include "../../core/serial_hook.h"
typedef Serial1Class<decltype(Serial)> DefaultSerial1;
extern DefaultSerial1 MSerial0;
#define Serial0 Serial
#define _DECLARE_SERIAL(X) \
typedef ForwardSerial1Class<decltype(Serial##X)> DefaultSerial##X; \
extern DefaultSerial##X MSerial##X
#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X)
typedef ForwardSerial1Class<decltype(SerialUSB)> USBSerialType;
extern USBSerialType USBSerial;
@@ -67,6 +71,7 @@ extern USBSerialType USBSerial;
#if SERIAL_PORT == -1
#define MYSERIAL1 SerialUSB
#elif WITHIN(SERIAL_PORT, 0, 8)
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."
+1 -1
View File
@@ -25,5 +25,5 @@
// EEPROM
//
void eeprom_init();
void eeprom_write_byte(uint8_t *pos, unsigned char value);
void eeprom_write_byte(uint8_t *pos, uint8_t value);
uint8_t eeprom_read_byte(uint8_t *pos);
+8 -9
View File
@@ -55,12 +55,15 @@ static constexpr uint8_t eeprom_device_address = I2C_ADDRESS(EEPROM_DEVICE_ADDRE
// Public functions
// ------------------------
void eeprom_write_byte(uint8_t *pos, unsigned char value) {
static void _eeprom_begin(uint8_t * const pos) {
const unsigned eeprom_address = (unsigned)pos;
Wire.beginTransmission(eeprom_device_address);
Wire.write(int(eeprom_address >> 8)); // MSB
Wire.write(int(eeprom_address & 0xFF)); // LSB
Wire.write(int(eeprom_address >> 8)); // Address High
Wire.write(int(eeprom_address & 0xFF)); // Address Low
}
void eeprom_write_byte(uint8_t *pos, uint8_t value) {
_eeprom_begin(pos);
Wire.write(value);
Wire.endTransmission();
@@ -70,11 +73,7 @@ void eeprom_write_byte(uint8_t *pos, unsigned char value) {
}
uint8_t eeprom_read_byte(uint8_t *pos) {
const unsigned eeprom_address = (unsigned)pos;
Wire.beginTransmission(eeprom_device_address);
Wire.write(int(eeprom_address >> 8)); // MSB
Wire.write(int(eeprom_address & 0xFF)); // LSB
_eeprom_begin(pos);
Wire.endTransmission();
Wire.requestFrom(eeprom_device_address, (byte)1);
return Wire.available() ? Wire.read() : 0xFF;
+27 -30
View File
@@ -43,44 +43,41 @@ void eeprom_init() {}
#define EEPROM_WRITE_DELAY 7
#endif
uint8_t eeprom_read_byte(uint8_t* pos) {
uint8_t v;
uint8_t eeprom_temp[3];
// set read location
// begin transmission from device
eeprom_temp[0] = CMD_READ;
eeprom_temp[1] = ((unsigned)pos>>8) & 0xFF; // addr High
eeprom_temp[2] = (unsigned)pos& 0xFF; // addr Low
WRITE(SPI_EEPROM1_CS, HIGH);
WRITE(SPI_EEPROM1_CS, LOW);
static void _eeprom_begin(uint8_t * const pos, const uint8_t cmd) {
const uint8_t eeprom_temp[3] = {
cmd,
(unsigned(pos) >> 8) & 0xFF, // Address High
unsigned(pos) & 0xFF // Address Low
};
WRITE(SPI_EEPROM1_CS, HIGH); // Usually free already
WRITE(SPI_EEPROM1_CS, LOW); // Activate the Bus
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3);
// Leave the Bus in-use
}
uint8_t eeprom_read_byte(uint8_t* pos) {
_eeprom_begin(pos, CMD_READ); // Set read location and begin transmission
const uint8_t v = spiRec(SPI_CHAN_EEPROM1); // After READ a value sits on the Bus
WRITE(SPI_EEPROM1_CS, HIGH); // Done with device
v = spiRec(SPI_CHAN_EEPROM1);
WRITE(SPI_EEPROM1_CS, HIGH);
return v;
}
void eeprom_write_byte(uint8_t* pos, uint8_t value) {
uint8_t eeprom_temp[3];
/*write enable*/
eeprom_temp[0] = CMD_WREN;
void eeprom_write_byte(uint8_t *pos, uint8_t value) {
const uint8_t eeprom_temp = CMD_WREN;
WRITE(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 1);
WRITE(SPI_EEPROM1_CS, HIGH);
delay(1);
spiSend(SPI_CHAN_EEPROM1, &eeprom_temp, 1); // Write Enable
/*write addr*/
eeprom_temp[0] = CMD_WRITE;
eeprom_temp[1] = ((unsigned)pos>>8) & 0xFF; //addr High
eeprom_temp[2] = (unsigned)pos & 0xFF; //addr Low
WRITE(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3);
WRITE(SPI_EEPROM1_CS, HIGH); // Done with the Bus
delay(1); // For a small amount of time
spiSend(SPI_CHAN_EEPROM1, value);
WRITE(SPI_EEPROM1_CS, HIGH);
delay(EEPROM_WRITE_DELAY); // wait for page write to complete
_eeprom_begin(pos, CMD_WRITE); // Set write address and begin transmission
spiSend(SPI_CHAN_EEPROM1, value); // Send the value to be written
WRITE(SPI_EEPROM1_CS, HIGH); // Done with the Bus
delay(EEPROM_WRITE_DELAY); // Give page write time to complete
}
#endif // USE_SHARED_EEPROM
+91 -29
View File
@@ -889,8 +889,8 @@ void stop() {
print_job_timer.stop();
#if ENABLED(PROBING_FANS_OFF)
if (thermalManager.fans_paused) thermalManager.set_fans_paused(false); // put things back the way they were
#if EITHER(PROBING_FANS_OFF, ADVANCED_PAUSE_FANS_PAUSE)
thermalManager.set_fans_paused(false); // Un-pause fans for safety
#endif
if (IsRunning()) {
@@ -953,23 +953,92 @@ inline void tmc_standby_setup() {
}
/**
* Marlin entry-point: Set up before the program loop
* - Set up the kill pin, filament runout, power hold, custom user buttons
* - Start the serial port
* Marlin Firmware entry-point. Abandon Hope All Ye Who Enter Here.
* Setup before the program loop:
*
* - Call any special pre-init set for the board
* - Put TMC drivers into Low Power Standby mode
* - Init the serial ports (so setup can be debugged)
* - Set up the kill and suicide pins
* - Prepare (disable) board JTAG and Debug ports
* - Init serial for a connected MKS TFT with WiFi
* - Install Marlin custom Exception Handlers, if set.
* - Init Marlin's HAL interfaces (for SPI, i2c, etc.)
* - Init some optional hardware and features:
* • MAX Thermocouple pins
* • Duet Smart Effector
* • Filament Runout Sensor
* • TMC220x Stepper Drivers (Serial)
* • PSU control
* • Power-loss Recovery
* • L64XX Stepper Drivers (SPI)
* • Stepper Driver Reset: DISABLE
* • TMC Stepper Drivers (SPI)
* • Run BOARD_INIT if defined
* • ESP WiFi
* - Get the Reset Reason and report it
* - Print startup messages and diagnostics
* - Get EEPROM or default settings
* - Initialize managers for:
* • temperature
* • planner
* • watchdog
* • stepper
* • photo pin
* • servos
* • LCD controller
* • Digipot I2C
* • Z probe sled
* • status LEDs
* • Max7219
* - Calibrate the HAL DELAY for precise timing
* - Init the buzzer, possibly a custom timer
* - Init more optional hardware:
* • Color LED illumination
* • Neopixel illumination
* • Controller Fan
* • Creality DWIN LCD (show boot image)
* • Tare the Probe if possible
* - Mount the (most likely external) SD Card
* - Load settings from EEPROM (or use defaults)
* - Init the Ethernet Port
* - Init Touch Buttons (for emulated DOGLCD)
* - Adjust the (certainly wrong) current position by the home offset
* - Init the Planner::position (steps) based on current (native) position
* - Initialize more managers and peripherals:
* • Temperatures
* • Print Job Timer
* • Endstops and Endstop Interrupts
* • Stepper ISR - Kind of Important!
* • Servos
* • Servo-based Probe
* • Photograph Pin
* • Laser/Spindle tool Power / PWM
* • Coolant Control
* • Bed Probe
* • Stepper Driver Reset: ENABLE
* • Digipot I2C - Stepper driver current control
* • Stepper DAC - Stepper driver current control
* • Solenoid (probe, or for other use)
* • Home Pin
* • Custom User Buttons
* • Red/Blue Status LEDs
* • Case Light
* • Prusa MMU filament changer
* • Fan Multiplexer
* • Mixing Extruder
* • BLTouch Probe
* • I2C Position Encoders
* • Custom I2C Bus handlers
* • Enhanced tools or extruders:
* • Switching Extruder
* • Switching Nozzle
* • Parking Extruder
* • Magnetic Parking Extruder
* • Switching Toolhead
* • Electromagnetic Switching Toolhead
* • Watchdog Timer - Also Kind of Important!
* • Closed Loop Controller
* - Run Startup Commands, if defined
* - Tell host to close Host Prompts
* - Test Trinamic driver connections
* - Init Prusa MMU2 filament changer
* - Init and test BL24Cxx EEPROM
* - Init Creality DWIN encoder, show faux progress bar
* - Reset Status Message / Show Service Messages
* - Init MAX7219 LED Matrix
* - Init Direct Stepping (Klipper-style motion control)
* - Init TFT LVGL UI (with 3D Graphics)
* - Apply Password Lock - Hold for Authentication
* - Open Touch Screen Calibration screen, if not calibrated
* - Set Marlin to RUNNING State
*/
void setup() {
#ifdef BOARD_PREINIT
@@ -1311,7 +1380,6 @@ void setup() {
#if PIN_EXISTS(STAT_LED_RED)
OUT_WRITE(STAT_LED_RED_PIN, LOW); // OFF
#endif
#if PIN_EXISTS(STAT_LED_BLUE)
OUT_WRITE(STAT_LED_BLUE_PIN, LOW); // OFF
#endif
@@ -1364,19 +1432,13 @@ void setup() {
#endif
#endif
#if ENABLED(MAGNETIC_PARKING_EXTRUDER)
SETUP_RUN(mpe_settings_init());
#endif
#if ENABLED(PARKING_EXTRUDER)
SETUP_RUN(pe_solenoid_init());
#endif
#if ENABLED(SWITCHING_TOOLHEAD)
#elif ENABLED(MAGNETIC_PARKING_EXTRUDER)
SETUP_RUN(mpe_settings_init());
#elif ENABLED(SWITCHING_TOOLHEAD)
SETUP_RUN(swt_init());
#endif
#if ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD)
#elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD)
SETUP_RUN(est_init());
#endif
+1
View File
@@ -279,6 +279,7 @@
#define BOARD_ARCHIM2 3024 // UltiMachine Archim2 (with TMC2130 drivers)
#define BOARD_ALLIGATOR 3025 // Alligator Board R2
#define BOARD_CNCONTROLS_15D 3026 // Cartesio CN Controls V15 on DUE
#define BOARD_KRATOS32 3027 // K.3D Kratos32 (Arduino Due Shield)
//
// SAM3X8C ARM Cortex M3
+2 -3
View File
@@ -47,7 +47,7 @@ void I2CPositionEncoder::init(const uint8_t address, const AxisEnum axis) {
encoderAxis = axis;
i2cAddress = address;
initialized++;
initialized = true;
SERIAL_ECHOLNPAIR("Setting up encoder on ", AS_CHAR(axis_codes[encoderAxis]), " axis, addr = ", address);
@@ -209,8 +209,7 @@ void I2CPositionEncoder::set_homed() {
delay(10);
zeroOffset = get_raw_count();
homed++;
trusted++;
homed = trusted = true;
#ifdef I2CPE_DEBUG
SERIAL_CHAR(axis_codes[encoderAxis]);
-1
View File
@@ -42,7 +42,6 @@
#if HAS_MEATPACK
#include "meatpack.h"
MeatPack meatpack;
#define MeatPack_ProtocolVersion "PV01"
//#define MP_DEBUG
+26 -10
View File
@@ -229,14 +229,18 @@
#define BOARD_ST7920_DELAY_2 DELAY_NS(125)
#define BOARD_ST7920_DELAY_3 DELAY_NS(125)
#elif ANY(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER, ANET_FULL_GRAPHICS_LCD, ANET_FULL_GRAPHICS_LCD_ALT_WIRING, BQ_LCD_SMART_CONTROLLER)
#elif ANY(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER, ANET_FULL_GRAPHICS_LCD, ANET_FULL_GRAPHICS_LCD_ALT_WIRING, BQ_LCD_SMART_CONTROLLER, K3D_FULL_GRAPHIC_SMART_CONTROLLER)
#define IS_RRD_FG_SC 1
#elif ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER)
// RepRapDiscount LCD or Graphical LCD with rotary click encoder
#define IS_RRD_SC 1 // RepRapDiscount LCD or Graphical LCD with rotary click encoder
#elif ENABLED(K3D_242_OLED_CONTROLLER)
#define IS_RRD_SC 1
#define U8GLIB_SSD1309
#endif
@@ -456,7 +460,7 @@
#endif
// Extensible UI serial touch screens. (See src/lcd/extui)
#if ANY(HAS_DGUS_LCD, MALYAN_LCD, TOUCH_UI_FTDI_EVE, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
#if ANY(HAS_DGUS_LCD, MALYAN_LCD, TOUCH_UI_FTDI_EVE, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, NEXTION_TFT)
#define IS_EXTUI 1
#define EXTENSIBLE_UI
#endif
@@ -654,13 +658,6 @@
#define UNUSED_E(E) UNUSED(E)
#endif
#if ENABLED(DWIN_CREALITY_LCD)
#define SERIAL_CATCHALL 0
#ifndef LCD_SERIAL_PORT
#define LCD_SERIAL_PORT 3 // Creality 4.x board
#endif
#endif
/**
* The BLTouch Probe emulates a servo probe
* and uses "special" angles for its state.
@@ -950,6 +947,18 @@
#define HAS_CLASSIC_E_JERK 1
#endif
//
// Serial Port Info
//
#ifdef SERIAL_PORT_2
#define NUM_SERIAL 2
#define HAS_MULTI_SERIAL 1
#elif defined(SERIAL_PORT)
#define NUM_SERIAL 1
#else
#define NUM_SERIAL 0
#undef BAUD_RATE_GCODE
#endif
#if SERIAL_PORT == -1 || SERIAL_PORT_2 == -1
#define HAS_USB_SERIAL 1
#endif
@@ -957,6 +966,13 @@
#define HAS_ETHERNET 1
#endif
#if ENABLED(DWIN_CREALITY_LCD)
#define SERIAL_CATCHALL 0
#ifndef LCD_SERIAL_PORT
#define LCD_SERIAL_PORT 3 // Creality 4.x board
#endif
#endif
// Fallback Stepper Driver types that don't depend on Configuration_adv.h
#ifndef X_DRIVER_TYPE
#define X_DRIVER_TYPE A4988
+7
View File
@@ -542,3 +542,10 @@
#else
#define HAS_USER_ITEM(N) 0
#endif
#if !HAS_MULTI_SERIAL
#undef MEATPACK_ON_SERIAL_PORT_2
#endif
#if EITHER(MEATPACK_ON_SERIAL_PORT_1, MEATPACK_ON_SERIAL_PORT_2)
#define HAS_MEATPACK 1
#endif
-13
View File
@@ -2906,16 +2906,3 @@
#if BUTTONS_EXIST(EN1, EN2, ENC)
#define HAS_ROTARY_ENCODER 1
#endif
#if !NUM_SERIAL
#undef BAUD_RATE_GCODE
#elif NUM_SERIAL > 1
#define HAS_MULTI_SERIAL 1
#endif
#if !HAS_MULTI_SERIAL
#undef MEATPACK_ON_SERIAL_PORT_2
#endif
#if EITHER(MEATPACK_ON_SERIAL_PORT_1, MEATPACK_ON_SERIAL_PORT_2)
#define HAS_MEATPACK 1
#endif
+4 -1
View File
@@ -2353,6 +2353,7 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
+ ENABLED(MAKEBOARD_MINI_2_LINE_DISPLAY_1602) \
+ ENABLED(MAKRPANEL) \
+ ENABLED(MALYAN_LCD) \
+ ENABLED(NEXTION_TFT) \
+ ENABLED(MKS_LCD12864) \
+ ENABLED(OLED_PANEL_TINYBOY2) \
+ ENABLED(OVERLORD_OLED) \
@@ -2372,7 +2373,9 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
+ ENABLED(ULTIPANEL) \
+ ENABLED(ULTRA_LCD) \
+ ENABLED(YHCB2004) \
+ ENABLED(ZONESTAR_LCD)
+ ENABLED(ZONESTAR_LCD) \
+ ENABLED(K3D_FULL_GRAPHIC_SMART_CONTROLLER) \
+ ENABLED(K3D_242_OLED_CONTROLLER)
#error "Please select only one LCD controller option."
#endif
+1 -1
View File
@@ -42,7 +42,7 @@
* version was tagged.
*/
#ifndef STRING_DISTRIBUTION_DATE
#define STRING_DISTRIBUTION_DATE "2021-03-12"
#define STRING_DISTRIBUTION_DATE "2021-03-20"
#endif
/**
+1 -1
View File
@@ -256,7 +256,7 @@ void MarlinUI::init_lcd() {
OUT_WRITE(LCD_BACKLIGHT_PIN, DISABLED(DELAYED_BACKLIGHT_INIT)); // Illuminate after reset or right away
#endif
#if ANY(MKS_12864OLED, MKS_12864OLED_SSD1306, FYSETC_242_OLED_12864, ZONESTAR_12864OLED)
#if ANY(MKS_12864OLED, MKS_12864OLED_SSD1306, FYSETC_242_OLED_12864, ZONESTAR_12864OLED, K3D_242_OLED_CONTROLLER)
SET_OUTPUT(LCD_PINS_DC);
#ifndef LCD_RESET_PIN
#define LCD_RESET_PIN LCD_PINS_RS
+3 -2
View File
@@ -123,9 +123,10 @@
#define U8G_CLASS U8GLIB_SSD1306_128X64 // 8 stripes
#endif
#elif ENABLED(FYSETC_242_OLED_12864)
#elif EITHER(FYSETC_242_OLED_12864, K3D_242_OLED_CONTROLLER)
// FYSETC OLED 2.42" 128 × 64 FULL GRAPHICS CONTROLLER
// FYSETC OLED 2.42" 128 × 64 Full Graphics Controller
// or K3D OLED 2.42" 128 × 64 Full Graphics Controller
#define FORCE_SOFT_SPI // SW-SPI
+11 -13
View File
@@ -1469,19 +1469,21 @@ void HMI_PrintSpeed() {
}
}
#define LAST_AXIS TERN(HAS_HOTEND, E_AXIS, Z_AXIS)
void HMI_MaxFeedspeedXYZE() {
ENCODER_DiffState encoder_diffState = Encoder_ReceiveAnalyze();
if (encoder_diffState != ENCODER_DIFF_NO) {
if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Max_Feedspeed)) {
checkkey = MaxSpeed;
EncoderRate.enabled = false;
if (WITHIN(HMI_flag.feedspeed_axis, X_AXIS, E_AXIS))
if (WITHIN(HMI_flag.feedspeed_axis, X_AXIS, LAST_AXIS))
planner.set_max_feedrate(HMI_flag.feedspeed_axis, HMI_ValueStruct.Max_Feedspeed);
DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(select_speed.now), HMI_ValueStruct.Max_Feedspeed);
return;
}
// MaxFeedspeed limit
if (WITHIN(HMI_flag.feedspeed_axis, X_AXIS, E_AXIS))
if (WITHIN(HMI_flag.feedspeed_axis, X_AXIS, LAST_AXIS))
NOMORE(HMI_ValueStruct.Max_Feedspeed, default_max_feedrate[HMI_flag.feedspeed_axis] * 2);
if (HMI_ValueStruct.Max_Feedspeed < MIN_MAXFEEDSPEED) HMI_ValueStruct.Max_Feedspeed = MIN_MAXFEEDSPEED;
// MaxFeedspeed value
@@ -1495,17 +1497,13 @@ void HMI_MaxAccelerationXYZE() {
if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Max_Acceleration)) {
checkkey = MaxAcceleration;
EncoderRate.enabled = false;
if (HMI_flag.acc_axis == X_AXIS) planner.set_max_acceleration(X_AXIS, HMI_ValueStruct.Max_Acceleration);
else if (HMI_flag.acc_axis == Y_AXIS) planner.set_max_acceleration(Y_AXIS, HMI_ValueStruct.Max_Acceleration);
else if (HMI_flag.acc_axis == Z_AXIS) planner.set_max_acceleration(Z_AXIS, HMI_ValueStruct.Max_Acceleration);
#if HAS_HOTEND
else if (HMI_flag.acc_axis == E_AXIS) planner.set_max_acceleration(E_AXIS, HMI_ValueStruct.Max_Acceleration);
#endif
if (WITHIN(HMI_flag.acc_axis, X_AXIS, LAST_AXIS))
planner.set_max_acceleration(HMI_flag.acc_axis, HMI_ValueStruct.Max_Acceleration);
DWIN_Draw_IntValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 4, 210, MBASE(select_acc.now), HMI_ValueStruct.Max_Acceleration);
return;
}
// MaxAcceleration limit
if (WITHIN(HMI_flag.acc_axis, X_AXIS, E_AXIS))
if (WITHIN(HMI_flag.acc_axis, X_AXIS, LAST_AXIS))
NOMORE(HMI_ValueStruct.Max_Acceleration, default_max_acceleration[HMI_flag.acc_axis] * 2);
if (HMI_ValueStruct.Max_Acceleration < MIN_MAXACCELERATION) HMI_ValueStruct.Max_Acceleration = MIN_MAXACCELERATION;
// MaxAcceleration value
@@ -1521,13 +1519,13 @@ void HMI_MaxAccelerationXYZE() {
if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Max_Jerk_scaled)) {
checkkey = MaxJerk;
EncoderRate.enabled = false;
if (WITHIN(HMI_flag.jerk_axis, X_AXIS, E_AXIS))
if (WITHIN(HMI_flag.jerk_axis, X_AXIS, LAST_AXIS))
planner.set_max_jerk(HMI_flag.jerk_axis, HMI_ValueStruct.Max_Jerk_scaled / 10);
DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(select_jerk.now), HMI_ValueStruct.Max_Jerk_scaled);
return;
}
// MaxJerk limit
if (WITHIN(HMI_flag.jerk_axis, X_AXIS, E_AXIS))
if (WITHIN(HMI_flag.jerk_axis, X_AXIS, LAST_AXIS))
NOMORE(HMI_ValueStruct.Max_Jerk_scaled, default_max_jerk[HMI_flag.jerk_axis] * 2 * MINUNITMULT);
NOLESS(HMI_ValueStruct.Max_Jerk_scaled, (MIN_MAXJERK) * MINUNITMULT);
// MaxJerk value
@@ -1543,13 +1541,13 @@ void HMI_StepXYZE() {
if (Apply_Encoder(encoder_diffState, HMI_ValueStruct.Max_Step_scaled)) {
checkkey = Step;
EncoderRate.enabled = false;
if (WITHIN(HMI_flag.step_axis, X_AXIS, E_AXIS))
if (WITHIN(HMI_flag.step_axis, X_AXIS, LAST_AXIS))
planner.settings.axis_steps_per_mm[HMI_flag.step_axis] = HMI_ValueStruct.Max_Step_scaled / 10;
DWIN_Draw_FloatValue(true, true, 0, font8x16, Color_White, Color_Bg_Black, 3, 1, 210, MBASE(select_step.now), HMI_ValueStruct.Max_Step_scaled);
return;
}
// Step limit
if (WITHIN(HMI_flag.step_axis, X_AXIS, E_AXIS))
if (WITHIN(HMI_flag.step_axis, X_AXIS, LAST_AXIS))
NOMORE(HMI_ValueStruct.Max_Step_scaled, 999.9 * MINUNITMULT);
NOLESS(HMI_ValueStruct.Max_Step_scaled, MIN_STEP);
// Step value
@@ -0,0 +1,174 @@
/**
* 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/>.
*
*/
/* ****************************************
* lcd/extui/lib/nextion/FileNavigator.cpp
* ****************************************
* Extensible_UI implementation for Nextion
* https://github.com/Skorpi08
* ***************************************/
#include "../../../../inc/MarlinConfigPre.h"
#if ENABLED(NEXTION_TFT)
#include "FileNavigator.h"
#include "nextion_tft.h"
using namespace ExtUI;
#define DEBUG_OUT NEXDEBUGLEVEL
#include "../../../../core/debug_out.h"
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;
FileNavigator::FileNavigator() { reset(); }
void FileNavigator::reset() {
currentfoldername[0] = '\0';
folderdepth = 0;
currentindex = 0;
lastindex = 0;
// Start at root folder
while (!filelist.isAtRootDir()) filelist.upDir();
refresh();
}
void FileNavigator::refresh() { filelist.refresh(); }
void FileNavigator::getFiles(uint16_t index) {
uint16_t files = 7, fseek = 0, fcnt = 0;
if (index == 0)
currentindex = 0;
else {
// Each time we change folder we reset the file index to 0 and keep track
// of the current position as the TFT panel isn't aware of folder trees.
--currentindex; // go back a file to take account of the .. added to the root.
if (index > lastindex)
currentindex += files + 1;
else if (currentindex >= files)
currentindex -= files - 1;
else
currentindex = 0;
}
lastindex = index;
#if NEXDEBUG(AC_FILE)
DEBUG_ECHOLNPAIR("index=", index, " currentindex=", currentindex);
#endif
if (currentindex == 0 && folderdepth > 0) { // Add a link to go up a folder
nextion.SendtoTFT(PSTR("vis p0,1"));
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF"));
SEND_VAL("tmpUP", "0");
files--;
}
else {
nextion.SendtoTFT(PSTR("vis p0,0"));
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF"));
}
for (uint16_t seek = currentindex; seek < currentindex + files; seek++) {
if (filelist.seek(seek)) {
nextion.SendtoTFT(PSTR("s"));
LCD_SERIAL.print(fcnt);
nextion.SendtoTFT(PSTR(".txt=\""));
if (filelist.isDir()) {
LCD_SERIAL.print(filelist.shortFilename());
nextion.SendtoTFT(PSTR("/\""));
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF"));
nextion.SendtoTFT(PSTR("l"));
LCD_SERIAL.print(fcnt);
nextion.SendtoTFT(PSTR(".txt=\""));
LCD_SERIAL.print(filelist.filename());
nextion.SendtoTFT(PSTR("\""));
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF"));
SEND_PCO2("l", fcnt, "1055");
}
else {
LCD_SERIAL.print(currentfoldername);
LCD_SERIAL.print(filelist.shortFilename());
nextion.SendtoTFT(PSTR("\""));
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF"));
nextion.SendtoTFT(PSTR("l"));
LCD_SERIAL.print(fcnt);
nextion.SendtoTFT(PSTR(".txt=\""));
LCD_SERIAL.print(filelist.longFilename());
nextion.SendtoTFT(PSTR("\""));
nextion.SendtoTFT(PSTR("\xFF\xFF\xFF"));
}
fcnt++;
fseek = seek;
#if NEXDEBUG(AC_FILE)
DEBUG_ECHOLNPAIR("-", seek, " '", filelist.longFilename(), "' '", currentfoldername, "", filelist.shortFilename(), "'\n");
#endif
}
}
SEND_VAL("n0", filelist.count());
SEND_VAL("n1", fseek + 1);
}
void FileNavigator::changeDIR(char *folder) {
#if NEXDEBUG(AC_FILE)
DEBUG_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;
}
void FileNavigator::upDIR() {
filelist.upDir();
refresh();
folderdepth--;
currentindex = 0;
// Remove the last child folder from the stored path
if (folderdepth == 0) {
currentfoldername[0] = '\0';
reset();
}
else {
char *pos = nullptr;
for (uint8_t f = 0; f < folderdepth; f++)
pos = strchr(currentfoldername, '/');
pos[1] = '\0';
}
#if NEXDEBUG(AC_FILE)
DEBUG_ECHOLNPAIR("depth: ", folderdepth, " currentfoldername: ", currentfoldername);
#endif
}
char* FileNavigator::getCurrentFolderName() { return currentfoldername; }
#endif // NEXTION_TFT
@@ -0,0 +1,53 @@
/**
* 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
/* ****************************************
* lcd/extui/lib/nextion/FileNavigator.cpp
* ****************************************
* Extensible_UI implementation for Nextion
* https://github.com/Skorpi08
* ***************************************/
#include "nextion_tft_defs.h" // for MAX_PATH_LEN
#include "../../ui_api.h"
using namespace ExtUI;
class FileNavigator {
public:
FileNavigator();
static void reset();
static void getFiles(uint16_t);
static void upDIR();
static void changeDIR(char *);
static void refresh();
static char* getCurrentFolderName();
private:
static FileList filelist;
static char currentfoldername[MAX_PATH_LEN];
static uint16_t lastindex;
static uint8_t folderdepth;
static uint16_t currentindex;
};
extern FileNavigator filenavigator;
@@ -0,0 +1,729 @@
/**
* 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/>.
*
*/
/* ****************************************
* lcd/extui/lib/nextion/nextion_tft.h
* ****************************************
* Extensible_UI implementation for Nextion
* https://github.com/Skorpi08
* ***************************************/
#include "../../../../inc/MarlinConfigPre.h"
#if ENABLED(NEXTION_TFT)
#include "../../../../MarlinCore.h"
#include "../../../../feature/pause.h"
#include "../../../../gcode/queue.h"
#include "../../../../libs/numtostr.h"
#include "../../../../sd/cardreader.h"
#include "FileNavigator.h"
#include "nextion_tft.h"
#define DEBUG_OUT NEXDEBUGLEVEL
#include "../../../../core/debug_out.h"
char NextionTFT::selectedfile[MAX_PATH_LEN];
char NextionTFT::nextion_command[MAX_CMND_LEN];
uint8_t NextionTFT::command_len;
bool last_homed = 0, last_homedX = 0, last_homedY = 0, last_homedZ = 0;
float last_degBed = 999, last_degHotend0 = 999, last_degHotend1 = 999, last_degTargetBed = 999, last_degTargetHotend0 = 999, last_degTargetHotend1 = 999;
float last_get_axis_position_mmX = 999, last_get_axis_position_mmY = 999, last_get_axis_position_mmZ = 999;
float last_extruder_advance_K = 999;
uint8_t last_active_extruder = 99, last_fan_speed = 99, last_print_speed = 99, last_flow_speed = 99, last_progress = 99;
uint8_t last_printer_state = 99, last_IDEX_Mode = 99;
uint32_t layer = 0, last_layer = 99;
NextionTFT nextion;
NextionTFT::NextionTFT() {}
void NextionTFT::Startup() {
selectedfile[0] = '\0';
nextion_command[0] = '\0';
command_len = 0;
LCD_SERIAL.begin(115200);
SEND_VAL("tmppage.connected", 0);
delay_ms(100);
SEND_VAL("tmppage.connected", 1);
SEND_VALasTXT("tmppage.marlin", SHORT_BUILD_VERSION);
SEND_VALasTXT("tmppage.compiled", __DATE__ " / " __TIME__);
SEND_VALasTXT("tmppage.extruder", EXTRUDERS);
SEND_VALasTXT("tmppage.printer", MACHINE_NAME);
SEND_VALasTXT("tmppage.author", STRING_CONFIG_H_AUTHOR);
SEND_VALasTXT("tmppage.released", STRING_DISTRIBUTION_DATE);
SEND_VALasTXT("tmppage.bedx", X_BED_SIZE);
SEND_VALasTXT("tmppage.bedy", Y_BED_SIZE);
SEND_VALasTXT("tmppage.bedz", Z_MAX_POS);
DEBUG_ECHOLNPAIR("Nextion Debug Level ", NEXDEBUGLEVEL);
}
void NextionTFT::IdleLoop() {
if (ReadTFTCommand()) {
ProcessPanelRequest();
command_len = 0;
}
UpdateOnChange();
}
void NextionTFT::PrinterKilled(PGM_P error, PGM_P component) {
SEND_TXT_END("page error");
SEND_TXT("t3", "Error");
SEND_TXT_P("t4", component);
SEND_TXT_P("t5", error);
SEND_TXT("t6", "Need reset");
}
void NextionTFT::PrintFinished() {
SEND_TXT_END("page printfinished");
}
void NextionTFT::ConfirmationRequest(const char *const msg) {
SEND_VALasTXT("tmppage.M117", msg);
#if NEXDEBUG(N_MARLIN)
DEBUG_ECHOLNPAIR("ConfirmationRequest() ", msg, " printer_state:", printer_state);
#endif
}
void NextionTFT::StatusChange(const char *const msg) {
#if NEXDEBUG(N_MARLIN)
DEBUG_ECHOLNPAIR("StatusChange() ", msg, "\nprinter_state:", printer_state);
#endif
SEND_VALasTXT("tmppage.M117", msg);
}
void NextionTFT::SendtoTFT(PGM_P str) { // A helper to print PROGMEM string to the panel
#if NEXDEBUG(N_SOME)
DEBUG_ECHOPGM_P(str);
#endif
while (const char c = pgm_read_byte(str++))
LCD_SERIAL.write(c);
}
bool NextionTFT::ReadTFTCommand() {
bool command_ready = false;
while ((LCD_SERIAL.available() > 0) && (command_len < MAX_CMND_LEN)) {
nextion_command[command_len] = LCD_SERIAL.read();
if (nextion_command[command_len] == 10) {
command_ready = true;
break;
}
command_len++;
}
if (command_ready) {
nextion_command[command_len] = 0x00;
if (nextion_command[0] == 'G' || nextion_command[0] == 'M' || nextion_command[0] == 'T')
injectCommands(nextion_command);
#if NEXDEBUG(N_ALL)
DEBUG_ECHOLNPAIR("< ", nextion_command);
#endif
#if NEXDEBUG(N_SOME)
uint8_t req = atoi(&nextion_command[1]);
if (req > 7 && req != 20)
DEBUG_ECHOLNPAIR( "> ", nextion_command[0],
"\n> ", nextion_command[1],
"\n> ", nextion_command[2],
"\n> ", nextion_command[3],
"\nprinter_state:", printer_state);
#endif
}
return command_ready;
}
void NextionTFT::SendFileList(int8_t startindex) {
// respond to panel request for 7 files starting at index
#if NEXDEBUG(N_INFO)
DEBUG_ECHOLNPAIR("## SendFileList ## ", startindex);
#endif
filenavigator.getFiles(startindex);
}
void NextionTFT::SelectFile() {
strncpy(selectedfile, nextion_command + 4, command_len - 4);
selectedfile[command_len - 5] = '\0';
#if NEXDEBUG(N_FILE)
DEBUG_ECHOLNPAIR_F(" Selected File: ", selectedfile);
#endif
switch (selectedfile[0]) {
case '/': // Valid file selected
//SEND_TXT("tmppage.M117", msg_sd_file_open_success);
break;
case '<': // .. (go up folder level)
filenavigator.upDIR();
SendFileList(0);
break;
default: // enter sub folder
filenavigator.changeDIR(selectedfile);
SendFileList(0);
break;
}
}
void NextionTFT::_format_time(char *outstr, uint32_t time) {
const uint8_t hrs = time / 3600,
min = (time / 60) % 60,
sec = time % 60;
if (hrs)
sprintf_P(outstr, PSTR("%02d:%02dm"), hrs, min);
else
sprintf_P(outstr, PSTR("%02d:%02ds"), min, sec);
}
void NextionTFT::ProcessPanelRequest() {
// Break these up into logical blocks as its easier to navigate than one huge switch case!
if (nextion_command[0] == 'X') {
int8_t req = atoi(&nextion_command[1]);
// Information requests
if (req <= 49)
PanelInfo(req);
// Simple Actions
else if (req >= 50)
PanelAction(req);
}
}
#define SEND_NA(A) SEND_TXT(A, "n/a")
void NextionTFT::PanelInfo(uint8_t req) {
switch (req) {
case 0: break;
case 1: // Get SD Card list
if (!isPrinting()) {
if (!isMediaInserted()) safe_delay(500);
if (!isMediaInserted()) { // Make sure the card is removed
//SEND_TXT("tmppage.M117", msg_no_sd_card);
}
else if (nextion_command[3] == 'S')
SendFileList(atoi(&nextion_command[4]));
}
break;
case 2: // Printer Info
if (!isPrinting()) {
SEND_VAL("tmppage.connected", 1);
SEND_VALasTXT("tmppage.marlin", SHORT_BUILD_VERSION);
SEND_VALasTXT("tmppage.compiled", __DATE__ " / " __TIME__);
SEND_VALasTXT("tmppage.extruder", EXTRUDERS);
SEND_VALasTXT("tmppage.printer", MACHINE_NAME);
SEND_VALasTXT("tmppage.author", STRING_CONFIG_H_AUTHOR);
SEND_VALasTXT("tmppage.released", STRING_DISTRIBUTION_DATE);
SEND_VALasTXT("tmppage.bedx", X_BED_SIZE);
SEND_VALasTXT("tmppage.bedy", Y_BED_SIZE);
SEND_VALasTXT("tmppage.bedz", Z_MAX_POS);
SEND_TEMP("tmppage.t0", ui8tostr3rj(getActualTemp_celsius(E0)), " / ", ui8tostr3rj(getTargetTemp_celsius(E0)));
SEND_TEMP("tmppage.t1", ui8tostr3rj(getActualTemp_celsius(E1)), " / ", ui8tostr3rj(getTargetTemp_celsius(E1)));
SEND_TEMP("tmppage.t2", ui8tostr3rj(getActualTemp_celsius(BED)), " / ", ui8tostr3rj(getTargetTemp_celsius(BED)));
SEND_VALasTXT("tmppage.tool", getActiveTool());
SEND_VALasTXT("tmppage.fan", ui8tostr3rj(getActualFan_percent(FAN0)));
SEND_VALasTXT("tmppage.speed", getFeedrate_percent());
SEND_VALasTXT("tmppage.flow", getFlowPercentage(getActiveTool()));
SEND_VALasTXT("tmppage.progress", ui8tostr3rj(getProgress_percent()));
SEND_VALasTXT("tmppage.layer", layer);
SEND_VALasTXT("tmppage.x", getAxisPosition_mm(X));
SEND_VALasTXT("tmppage.y", getAxisPosition_mm(Y));
SEND_VALasTXT("tmppage.z", getAxisPosition_mm(Z));
SEND_VAL("tmppage.homed", isPositionKnown());
SEND_VAL("tmppage.homedx", isAxisPositionKnown(X));
SEND_VAL("tmppage.homedy", isAxisPositionKnown(Y));
SEND_VAL("tmppage.homedz", isAxisPositionKnown(Z));
#if ENABLED(DUAL_X_CARRIAGE)
SEND_VAL("tmppage.idexmode", getIDEX_Mode());
#endif
SEND_TXT("tmppage.M117", msg_welcome);
}
break;
case 23: // Linear Advance
#if ENABLED(LIN_ADVANCE)
SEND_VALasTXT("linadvance", getLinearAdvance_mm_mm_s(getActiveTool()));
#else
SEND_NA("linadvance");
#endif
break;
case 24: // TMC Motor Current
#if HAS_TRINAMIC_CONFIG
#define SEND_TRINAMIC_CURR(A, B) SEND_VALasTXT(A, getAxisCurrent_mA(B))
#else
#define SEND_TRINAMIC_CURR(A, B) SEND_NA(A)
#endif
SEND_TRINAMIC_CURR("x", X);
SEND_TRINAMIC_CURR("x2", X2);
SEND_TRINAMIC_CURR("y", Y);
SEND_TRINAMIC_CURR("y2", Y2);
SEND_TRINAMIC_CURR("z", Z);
SEND_TRINAMIC_CURR("z2", Z2);
SEND_TRINAMIC_CURR("e", E0);
SEND_TRINAMIC_CURR("e1", E1);
break;
case 25: // TMC Bump Sensitivity
#if HAS_TRINAMIC_CONFIG
#define SEND_TRINAMIC_BUMP(A, B) SEND_VALasTXT(A, getTMCBumpSensitivity(B))
#else
#define SEND_TRINAMIC_BUMP(A, B) SEND_NA(A)
#endif
SEND_TRINAMIC_BUMP("x", X);
SEND_TRINAMIC_BUMP("x2", X2);
SEND_TRINAMIC_BUMP("y", Y);
SEND_TRINAMIC_BUMP("y2", Y2);
SEND_TRINAMIC_BUMP("z", Z);
SEND_TRINAMIC_BUMP("z2", Z2);
break;
case 26: // TMC Hybrid Threshold Speed
#if 0 && BOTH(HAS_TRINAMIC_CONFIG, HYBRID_THRESHOLD)
#define SEND_TRINAMIC_THRS(A, B) SEND_VALasTXT(A, getAxisPWMthrs(B))
#else
#define SEND_TRINAMIC_THRS(A, B) SEND_NA(A)
#endif
SEND_TRINAMIC_THRS("x", X);
SEND_TRINAMIC_THRS("x2", X2);
SEND_TRINAMIC_THRS("y", Y);
SEND_TRINAMIC_THRS("y2", Y2);
SEND_TRINAMIC_THRS("z", Z);
SEND_TRINAMIC_THRS("z2", Z2);
SEND_TRINAMIC_THRS("e", E0);
SEND_TRINAMIC_THRS("e1", E1);
break;
case 27: // Printcounter
#if ENABLED(PRINTCOUNTER)
char buffer[21];
#define SEND_PRINT_INFO(A, B) SEND_VALasTXT(A, B(buffer))
#else
#define SEND_PRINT_INFO(A, B) SEND_NA(A)
#endif
SEND_PRINT_INFO("t5", getTotalPrints_str);
SEND_PRINT_INFO("t3", getFinishedPrints_str);
SEND_PRINT_INFO("t4", getFailedPrints_str);
SEND_PRINT_INFO("t6", getTotalPrintTime_str);
SEND_PRINT_INFO("t7", getLongestPrint_str);
SEND_PRINT_INFO("t8", getFilamentUsed_str);
break;
case 28: // Filament laod/unload
#if ENABLED(ADVANCED_PAUSE_FEATURE)
#define SEND_PAUSE_INFO(A, B) SEND_VALasTXT(A, fc_settings[getActiveTool()].B)
#else
#define SEND_PAUSE_INFO(A, B) SEND_NA(A)
#endif
SEND_PAUSE_INFO("filamentin", load_length);
SEND_PAUSE_INFO("filamentout", unload_length);
break;
case 29: // Preheat
#if PREHEAT_COUNT
if (!isPrinting()) {
// Preheat PLA
if (nextion_command[4] == 'P') {
SEND_VALasTXT("pe", getMaterial_preset_E(0));
#if HAS_HEATED_BED
SEND_VALasTXT("pb", getMaterial_preset_B(0));
#endif
}
// Preheat ABS
if (nextion_command[4] == 'A') {
SEND_VALasTXT("ae", getMaterial_preset_E(1));
#if HAS_HEATED_BED
SEND_VALasTXT("ab", getMaterial_preset_B(1));
#endif
}
// Preheat PETG
if (nextion_command[4] == 'G') {
#ifdef PREHEAT_3_TEMP_HOTEND
SEND_VALasTXT("ge", getMaterial_preset_E(2));
#if HAS_HEATED_BED
SEND_VALasTXT("gb", getMaterial_preset_B(2));
#endif
#endif
}
}
#endif
break;
case 30: // Velocity
SEND_VALasTXT("x", getAxisMaxFeedrate_mm_s(X));
SEND_VALasTXT("y", getAxisMaxFeedrate_mm_s(Y));
SEND_VALasTXT("z", getAxisMaxFeedrate_mm_s(Z));
SEND_VALasTXT("e", getAxisMaxFeedrate_mm_s(getActiveTool()));
SEND_VALasTXT("min", getMinFeedrate_mm_s());
SEND_VALasTXT("tmin", getMinTravelFeedrate_mm_s());
break;
case 31: // Jerk
#if ENABLED(CLASSIC_JERK)
#define SEND_JERK_INFO(A, B) SEND_VALasTXT(A, getAxisMaxJerk_mm_s(B))
#else
#define SEND_JERK_INFO(A, B) SEND_NA(A)
//SEND_VALasTXT("x", getJunctionDeviation_mm());
SEND_TXT("tmppage.M117", "classic Jerk not enabled");
#endif
SEND_JERK_INFO("x", X);
SEND_JERK_INFO("y", Y);
SEND_JERK_INFO("z", Z);
SEND_JERK_INFO("e", getActiveTool());
break;
case 32: // Steps-per-mm
SEND_VALasTXT("x", getAxisSteps_per_mm(X));
SEND_VALasTXT("y", getAxisSteps_per_mm(Y));
SEND_VALasTXT("z", getAxisSteps_per_mm(Z));
SEND_VALasTXT("e0", getAxisSteps_per_mm(E0));
SEND_VALasTXT("e1", getAxisSteps_per_mm(E1));
break;
case 33: // Acceleration
SEND_VALasTXT("x", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(X)));
SEND_VALasTXT("y", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(Y)));
SEND_VALasTXT("z", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(Z)));
SEND_VALasTXT("e", ui16tostr5rj(getAxisMaxAcceleration_mm_s2(getActiveTool())));
SEND_VALasTXT("print", ui16tostr5rj(getPrintingAcceleration_mm_s2()));
SEND_VALasTXT("retract", ui16tostr5rj(getRetractAcceleration_mm_s2()));
SEND_VALasTXT("travel", ui16tostr5rj(getTravelAcceleration_mm_s2()));
break;
case 34: // Dual X carriage offset
#if ENABLED(DUAL_X_CARRIAGE)
#define SEND_IDEX_INFO(A, B) SEND_VALasTXT(A, getNozzleOffset_mm(B, getActiveTool()))
#else
#define SEND_IDEX_INFO(A, B) SEND_NA(A)
#endif
SEND_IDEX_INFO("x", X);
SEND_IDEX_INFO("y", Y);
SEND_IDEX_INFO("z", Z);
break;
case 35: // Probe offset
#if HAS_PROBE_XY_OFFSET
#define SEND_PROBE_INFO(A, B) SEND_VALasTXT(A, getProbeOffset_mm(B))
#else
#define SEND_PROBE_INFO(A, B) SEND_NA(A)
#endif
SEND_PROBE_INFO("x", X);
SEND_PROBE_INFO("y", Y);
SEND_VALasTXT("z", getZOffset_mm());
break;
case 36: // Endstop Info
#if HAS_X_MIN
SEND_VALasTXT("x1", READ(X_MIN_PIN) != X_MIN_ENDSTOP_INVERTING ? "triggered" : "open");
#endif
#if HAS_X_MAX
SEND_VALasTXT("x2", READ(X_MAX_PIN) != X_MAX_ENDSTOP_INVERTING ? "triggered" : "open");
#endif
#if HAS_Y_MIN
SEND_VALasTXT("y1", READ(Y_MIN_PIN) != Y_MIN_ENDSTOP_INVERTING ? "triggered" : "open");
#endif
#if HAS_Z_MIN
SEND_VALasTXT("z1", READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING ? "triggered" : "open");
#endif
#if HAS_Z_MAX
SEND_VALasTXT("z2", READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING ? "triggered" : "open");
#endif
#if HAS_Z2_MIN
SEND_VALasTXT("z2", READ(Z2_MIN_PIN) != Z2_MIN_ENDSTOP_INVERTING ? "triggered" : "open");
#endif
#if HAS_Z2_MAX
SEND_VALasTXT("z2", READ(Z2_MAX_PIN) != Z2_MAX_ENDSTOP_INVERTING ? "triggered" : "open");
#endif
#if HAS_BED_PROBE
//SEND_VALasTXT("bltouch", READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING ? "triggered" : "open");
#else
SEND_NA("bltouch");
#endif
break;
case 37: // PID
#if ENABLED(PIDTEMP)
#define SEND_PID_INFO_0(A, B) SEND_VALasTXT(A, getPIDValues_K##B(E0))
#else
#define SEND_PID_INFO_0(A, B) SEND_NA(A)
#endif
#if BOTH(PIDTEMP, HAS_MULTI_EXTRUDER)
#define SEND_PID_INFO_1(A, B) SEND_VALasTXT(A, getPIDValues_K##B(E1))
#else
#define SEND_PID_INFO_1(A, B) SEND_NA(A)
#endif
#if ENABLED(PIDTEMPBED)
#define SEND_PID_INFO_BED(A, B) SEND_VALasTXT(A, getBedPIDValues_K##B())
#else
#define SEND_PID_INFO_BED(A, B) SEND_NA(A)
#endif
SEND_PID_INFO_0("p0", p);
SEND_PID_INFO_0("i0", i);
SEND_PID_INFO_0("d0", d);
SEND_PID_INFO_1("p1", p);
SEND_PID_INFO_1("i1", i);
SEND_PID_INFO_1("d1", d);
SEND_PID_INFO_BED("hbp", p);
SEND_PID_INFO_BED("hbi", i);
SEND_PID_INFO_BED("hbd", d);
break;
}
}
void NextionTFT::PanelAction(uint8_t req) {
switch (req) {
case 50: // Pause SD print
//if (isPrintingFromMedia()) {
//SEND_TXT("tmppage.M117", "Paused");
pausePrint();
SEND_TXT_END("qpause.picc=29");
//}
break;
case 51: // Resume SD Print
resumePrint();
SEND_TXT_END("qpause.picc=28");
break;
case 52: // Stop SD print
//if (isPrintingFromMedia()) {
stopPrint();
SEND_TXT_END("page prepare");
//}
break;
case 54: // A13 Select file
SelectFile();
break;
case 65: // Cool Down
if (!isPrinting()) coolDown();
break;
case 66: // Refresh SD
if (!isPrinting()) {
injectCommands_P(PSTR("M21"));
filenavigator.reset();
}
break;
case 56: // Set Fan, Flow, Print Speed
switch (nextion_command[4]) {
case 'S': setTargetFan_percent(atof(&nextion_command[5]), FAN0); break;
case 'P': setFeedrate_percent(atoi(&nextion_command[5])); break;
case 'F': setFlow_percent(atoi(&nextion_command[5]), getActiveTool()); break;
}
break;
case 57: // Disable Motors
if (!isPrinting()) {
disable_all_steppers(); // from marlincore.h
SEND_TXT("tmppage.M117", "Motors disabled");
}
break;
case 58: // Load/Unload Filament
#if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)
if (canMove(getActiveTool())) {
switch (nextion_command[4]) {
case 'L': injectCommands_P(PSTR("M701")); break;
case 'U': injectCommands_P(PSTR("M702")); break;
}
}
else {
SEND_TXT("tmppage.M117", "Preheat first");
SEND_TXT_END("page preheat");
}
#else
SEND_TXT("tmppage.M117", "Filament loading disabled");
#endif
break;
case 63: // Preheat // Temps defined in configuration.h
#if PREHEAT_COUNT
if (!isPrinting()) switch (nextion_command[4]) {
// Preheat PLA
case 'P':
#if HAS_HEATED_BED
setTargetTemp_celsius(getMaterial_preset_B(0), BED);
#endif
setTargetTemp_celsius(getMaterial_preset_E(0), getActiveTool());
break;
// Preheat ABS
case 'A':
#if HAS_HEATED_BED
setTargetTemp_celsius(getMaterial_preset_B(1), BED);
#endif
setTargetTemp_celsius(getMaterial_preset_E(1), getActiveTool());
break;
// Preheat PETG
case 'G':
#if HAS_HEATED_BED
setTargetTemp_celsius(getMaterial_preset_B(2), BED);
#endif
setTargetTemp_celsius(getMaterial_preset_E(2), getActiveTool());
break;
}
#else
SEND_TXT("tmppage.M117", "Preheat disabled");
#endif
break;
}
}
void NextionTFT::UpdateOnChange() {
const millis_t ms = millis();
static millis_t next_event_ms = 0;
// tmppage Temperature
if (!WITHIN(last_degHotend0 - getActualTemp_celsius(E0), -0.2, 0.2) || !WITHIN(last_degTargetHotend0 - getTargetTemp_celsius(E0), -0.5, 0.5)) {
SEND_TEMP("tmppage.t0", ui8tostr3rj(getActualTemp_celsius(E0)), " / ", ui8tostr3rj(getTargetTemp_celsius(E0)));
last_degHotend0 = getActualTemp_celsius(E0);
last_degTargetHotend0 = getTargetTemp_celsius(E0);
}
if (!WITHIN(last_degHotend1 - getActualTemp_celsius(E1), -0.2, 0.2) || !WITHIN(last_degTargetHotend1 - getTargetTemp_celsius(E1), -0.5, 0.5)) {
SEND_TEMP("tmppage.t1", ui8tostr3rj(getActualTemp_celsius(E1)), " / ", ui8tostr3rj(getTargetTemp_celsius(E1)));
last_degHotend1 = getActualTemp_celsius(E1);
last_degTargetHotend1 = getTargetTemp_celsius(E1);
}
if (!WITHIN(last_degBed - getActualTemp_celsius(BED), -0.2, 0.2) || !WITHIN(last_degTargetBed - getTargetTemp_celsius(BED), -0.5, 0.5)) {
SEND_TEMP("tmppage.t2", ui8tostr3rj(getActualTemp_celsius(BED)), " / ", ui8tostr3rj(getTargetTemp_celsius(BED)));
last_degBed = getActualTemp_celsius(BED);
last_degTargetBed = getTargetTemp_celsius(BED);
}
// tmppage Tool
if (last_active_extruder != getActiveTool()) {
SEND_VALasTXT("tmppage.tool", getActiveTool());
last_active_extruder = getActiveTool();
}
// tmppage Fan Speed
if (last_fan_speed != getActualFan_percent(FAN0)) {
SEND_VALasTXT("tmppage.fan", ui8tostr3rj(getActualFan_percent(FAN0)));
last_fan_speed = getActualFan_percent(FAN0);
}
// tmppage Print Speed
if (last_print_speed != getFeedrate_percent()) {
SEND_VALasTXT("tmppage.speed", ui8tostr3rj(getFeedrate_percent()));
last_print_speed = getFeedrate_percent();
}
// tmppage Flow
if (last_flow_speed != getFlowPercentage(getActiveTool())) {
SEND_VALasTXT("tmppage.flow", getFlowPercentage(getActiveTool()));
last_flow_speed = getFlowPercentage(getActiveTool());
}
// tmppage Progress + Layer + Time
if (isPrinting()) {
if (ELAPSED(ms, next_event_ms)) {
next_event_ms = ms + 1000;
#if ENABLED(SHOW_REMAINING_TIME)
const uint32_t remaining = getProgress_seconds_remaining();
char remaining_str[10];
_format_time(remaining_str, remaining);
SEND_VALasTXT("tmppage.remaining", remaining_str);
#endif
const uint32_t elapsed = getProgress_seconds_elapsed();
char elapsed_str[10];
_format_time(elapsed_str, elapsed);
SEND_VALasTXT("tmppage.elapsed", elapsed_str);
}
if (last_progress != getProgress_percent()) {
SEND_VALasTXT("tmppage.progress", ui8tostr3rj(getProgress_percent()));
last_progress = getProgress_percent();
}
if (last_get_axis_position_mmZ < getAxisPosition_mm(Z)) {
layer++;
SEND_VALasTXT("tmppage.layer", layer);
}
if (last_get_axis_position_mmZ > getAxisPosition_mm(Z)) {
layer--;
SEND_VALasTXT("tmppage.layer", layer);
}
}
// tmppage Axis
if (!WITHIN(last_get_axis_position_mmX - getAxisPosition_mm(X), -0.1, 0.1)) {
if (ELAPSED(ms, next_event_ms)) {
next_event_ms = ms + 30;
SEND_VALasTXT("tmppage.x", getAxisPosition_mm(X));
last_get_axis_position_mmX = getAxisPosition_mm(X);
}
}
if (!WITHIN(last_get_axis_position_mmY - getAxisPosition_mm(Y), -0.1, 0.1)) {
if (ELAPSED(ms, next_event_ms)) {
next_event_ms = ms + 30;
SEND_VALasTXT("tmppage.y", getAxisPosition_mm(Y));
last_get_axis_position_mmY = getAxisPosition_mm(Y);
}
}
if (!WITHIN(last_get_axis_position_mmZ - getAxisPosition_mm(Z), -0.1, 0.1)) {
SEND_VALasTXT("tmppage.z", getAxisPosition_mm(Z));
last_get_axis_position_mmZ = getAxisPosition_mm(Z);
}
// tmppage homed
if (last_homed != isPositionKnown()) {
SEND_VAL("tmppage.homed", isPositionKnown());
last_homed = isPositionKnown();
}
if (last_homedX != isAxisPositionKnown(X)) {
SEND_VAL("tmppage.homedx", isAxisPositionKnown(X));
last_homedX = isAxisPositionKnown(X);
}
if (last_homedY != isAxisPositionKnown(Y)) {
SEND_VAL("tmppage.homedy", isAxisPositionKnown(Y));
last_homedY = isAxisPositionKnown(Y);
}
if (last_homedZ != isAxisPositionKnown(Z)) {
SEND_VAL("tmppage.homedz", isAxisPositionKnown(Z));
last_homedZ = isAxisPositionKnown(Z);
}
// tmppage IDEX Mode
#if ENABLED(DUAL_X_CARRIAGE)
if (last_IDEX_Mode != getIDEX_Mode()) {
SEND_VAL("tmppage.idexmode", getIDEX_Mode());
last_IDEX_Mode = getIDEX_Mode();
}
#endif
}
#endif // NEXTION_TFT
@@ -0,0 +1,62 @@
/**
* 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
/* ****************************************
* lcd/extui/lib/nextion/nextion_tft.h
* ****************************************
* Extensible_UI implementation for Nextion
* https://github.com/Skorpi08
* ***************************************/
#include "nextion_tft_defs.h"
#include "../../../../inc/MarlinConfigPre.h"
#include "../../ui_api.h"
class NextionTFT {
private:
static uint8_t command_len;
static char nextion_command[MAX_CMND_LEN];
static char selectedfile[MAX_PATH_LEN];
public:
NextionTFT();
static void Startup();
static void IdleLoop();
static void PrinterKilled(PGM_P, PGM_P);
static void ConfirmationRequest(const char * const );
static void StatusChange(const char * const );
static void SendtoTFT(PGM_P);
static void UpdateOnChange();
static void PrintFinished();
static void PanelInfo(uint8_t);
private:
static bool ReadTFTCommand();
static void SendFileList(int8_t);
static void SelectFile();
static void ProcessPanelRequest();
static void PanelAction(uint8_t);
static void _format_time(char *, uint32_t);
};
extern NextionTFT nextion;
@@ -0,0 +1,63 @@
/**
* 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
/* ****************************************
* lcd/extui/lib/nextion/nextion_tft_defs.h
* ****************************************
* Extensible_UI implementation for Nextion
* https://github.com/Skorpi08
* ***************************************/
#include "../../../../inc/MarlinConfigPre.h"
//#define NEXDEBUGLEVEL 255
#if NEXDEBUGLEVEL
// Bit-masks for selective debug:
enum NexDebugMask : uint8_t {
N_INFO = _BV(0),
N_ACTION = _BV(1),
N_FILE = _BV(2),
N_PANEL = _BV(3),
N_MARLIN = _BV(4),
N_SOME = _BV(5),
N_ALL = _BV(6)
};
#define NEXDEBUG(M) (((M) & NEXDEBUGLEVEL) == M) // Debug flag macro
#else
#define NEXDEBUG(M) false
#endif
#define MAX_FOLDER_DEPTH 4 // Limit folder depth TFT has a limit for the file path
#define MAX_CMND_LEN 16 * MAX_FOLDER_DEPTH // Maximum Length for a Panel command
#define MAX_PATH_LEN 16 * MAX_FOLDER_DEPTH // Maximum number of characters in a SD file path
// TFT panel commands
#define msg_welcome MACHINE_NAME " Ready."
#define SEND_TEMP(x,y,t,z) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR(".txt=\"")), LCD_SERIAL.print(y), nextion.SendtoTFT(PSTR(t)), LCD_SERIAL.print(z), nextion.SendtoTFT(PSTR("\"\xFF\xFF\xFF")))
#define SEND_VAL(x,y) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR(".val=")), LCD_SERIAL.print(y), nextion.SendtoTFT(PSTR("\xFF\xFF\xFF")))
#define SEND_TXT(x,y) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR(".txt=\"")), nextion.SendtoTFT(PSTR(y)), nextion.SendtoTFT(PSTR("\"\xFF\xFF\xFF")))
#define SEND_TXT_P(x,y) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR(".txt=\"")), nextion.SendtoTFT(y), nextion.SendtoTFT(PSTR("\"\xFF\xFF\xFF")))
#define SEND_VALasTXT(x,y) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR(".txt=\"")), LCD_SERIAL.print(y), nextion.SendtoTFT(PSTR("\"\xFF\xFF\xFF")))
#define SEND_TXT_END(x) (nextion.SendtoTFT(PSTR(x)), nextion.SendtoTFT(PSTR("\xFF\xFF\xFF")))
#define SEND_PCO2(x,y,z) (nextion.SendtoTFT(PSTR(x)), LCD_SERIAL.print(y), nextion.SendtoTFT(PSTR(".pco=")), nextion.SendtoTFT(PSTR(z)), nextion.SendtoTFT(PSTR("\xFF\xFF\xFF")))
+117
View File
@@ -0,0 +1,117 @@
/**
* 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/>.
*
*/
/**
* lcd/extui/nextion_lcd.cpp
*
* Nextion TFT support for Marlin
*/
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(NEXTION_TFT)
#include "ui_api.h"
#include "lib/nextion/nextion_tft.h"
namespace ExtUI {
void onStartup() { nextion.Startup(); }
void onIdle() { nextion.IdleLoop(); }
void onPrinterKilled(PGM_P const error, PGM_P const component) { nextion.PrinterKilled(error,component); }
void onMediaInserted() {}
void onMediaError() {}
void onMediaRemoved() {}
void onPlayTone(const uint16_t frequency, const uint16_t duration) {}
void onPrintTimerStarted() {}
void onPrintTimerPaused() {}
void onPrintTimerStopped() {}
void onFilamentRunout(const extruder_t) {}
void onUserConfirmRequired(const char * const msg) { nextion.ConfirmationRequest(msg); }
void onStatusChanged(const char * const msg) { nextion.StatusChange(msg); }
void onHomingStart() {}
void onHomingComplete() {}
void onPrintFinished() { nextion.PrintFinished(); }
void onFactoryReset() {}
void onStoreSettings(char *buff) {
// Called when saving to EEPROM (i.e. M500). If the ExtUI needs
// permanent data to be stored, it can write up to eeprom_data_size bytes
// into buff.
// Example:
// static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size);
// memcpy(buff, &myDataStruct, sizeof(myDataStruct));
}
void onLoadSettings(const char *buff) {
// Called while loading settings from EEPROM. If the ExtUI
// needs to retrieve data, it should copy up to eeprom_data_size bytes
// from buff
// Example:
// static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size);
// memcpy(&myDataStruct, buff, sizeof(myDataStruct));
}
void onConfigurationStoreWritten(bool success) {
// Called after the entire EEPROM has been written,
// whether successful or not.
}
void onConfigurationStoreRead(bool success) {
// Called after the entire EEPROM has been read,
// whether successful or not.
}
#if HAS_MESH
void onMeshLevelingStart() {}
void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) {
// Called when any mesh points are updated
}
void onMeshUpdate(const int8_t xpos, const int8_t ypos, const ExtUI::probe_state_t state) {
// Called to indicate a special condition
}
#endif
#if ENABLED(POWER_LOSS_RECOVERY)
void onPowerLossResume() {
// Called on resume from power-loss
}
#endif
#if HAS_PID_HEATING
void onPidTuning(const result_t rst) {
// Called for temperature PID tuning result
nextion.PanelInfo(37);
}
#endif
void onSteppersDisabled() {}
void onSteppersEnabled() {}
}
#endif // NEXTION_TFT
+13 -4
View File
@@ -587,13 +587,11 @@ namespace ExtUI {
void setAxisMaxAcceleration_mm_s2(const float &value, const axis_t axis) {
planner.set_max_acceleration(axis, value);
planner.reset_acceleration_rates();
}
void setAxisMaxAcceleration_mm_s2(const float &value, const extruder_t extruder) {
UNUSED_E(extruder);
planner.set_max_acceleration(E_AXIS_N(extruder - E0), value);
planner.reset_acceleration_rates();
}
#if HAS_FILAMENT_SENSOR
@@ -653,6 +651,17 @@ namespace ExtUI {
void setAxisMaxJerk_mm_s(const float &value, const extruder_t) { planner.set_max_jerk(E_AXIS, value); }
#endif
#if ENABLED(DUAL_X_CARRIAGE)
uint8_t getIDEX_Mode() { return dual_x_carriage_mode; }
#endif
#if PREHEAT_COUNT
uint16_t getMaterial_preset_E(const uint16_t index) { return ui.material_preset[index].hotend_temp; }
#if HAS_HEATED_BED
uint16_t getMaterial_preset_B(const uint16_t index) { return ui.material_preset[index].bed_temp; }
#endif
#endif
feedRate_t getFeedrate_mm_s() { return feedrate_mm_s; }
int16_t getFlowPercentage(const extruder_t extr) { return planner.flow_percentage[extr]; }
feedRate_t getMinFeedrate_mm_s() { return planner.settings.min_feedrate_mm_s; }
@@ -665,8 +674,8 @@ namespace ExtUI {
void setMinFeedrate_mm_s(const feedRate_t fr) { planner.settings.min_feedrate_mm_s = fr; }
void setMinTravelFeedrate_mm_s(const feedRate_t fr) { planner.settings.min_travel_feedrate_mm_s = fr; }
void setPrintingAcceleration_mm_s2(const float &acc) { planner.settings.acceleration = acc; }
void setRetractAcceleration_mm_s2(const float &acc) { planner.settings.retract_acceleration = acc; }
void setTravelAcceleration_mm_s2(const float &acc) { planner.settings.travel_acceleration = acc; }
void setRetractAcceleration_mm_s2(const float &acc) { planner.settings.retract_acceleration = acc; }
void setTravelAcceleration_mm_s2(const float &acc) { planner.settings.travel_acceleration = acc; }
#if ENABLED(BABYSTEPPING)
+12
View File
@@ -139,6 +139,17 @@ namespace ExtUI {
uint32_t getProgress_seconds_elapsed();
#if PREHEAT_COUNT
uint16_t getMaterial_preset_E(const uint16_t);
#if HAS_HEATED_BED
uint16_t getMaterial_preset_B(const uint16_t);
#endif
#endif
#if ENABLED(DUAL_X_CARRIAGE)
uint8_t getIDEX_Mode();
#endif
#if ENABLED(SHOW_REMAINING_TIME)
inline uint32_t getProgress_seconds_remaining() { return ui.get_remaining_time(); }
#endif
@@ -171,6 +182,7 @@ namespace ExtUI {
#endif
#if ENABLED(PRINTCOUNTER)
char* getFailedPrints_str(char buffer[21]);
char* getTotalPrints_str(char buffer[21]);
char* getFinishedPrints_str(char buffer[21]);
char* getTotalPrintTime_str(char buffer[21]);
+14 -1
View File
@@ -46,7 +46,20 @@ void _lcd_user_gcode(PGM_P const cmd) {
void menu_user() {
START_MENU();
BACK_ITEM(MSG_MAIN);
#define USER_ITEM(N) ACTION_ITEM_P(PSTR(USER_DESC_##N), []{ _lcd_user_gcode(PSTR(USER_GCODE_##N _DONE_SCRIPT)); });
#define GCODE_LAMBDA(N) []{ _lcd_user_gcode(PSTR(USER_GCODE_##N _DONE_SCRIPT)); }
#define _USER_ITEM(N) ACTION_ITEM_P(PSTR(USER_DESC_##N), GCODE_LAMBDA(N));
#define _USER_ITEM_CONFIRM(N) \
SUBMENU_P(PSTR(USER_DESC_##N), []{ \
MenuItem_confirm::confirm_screen( \
GCODE_LAMBDA(N), \
ui.goto_previous_screen, \
PSTR(USER_DESC_##N "?") \
); \
})
#define USER_ITEM(N) do{ if (ENABLED(USER_CONFIRM_##N)) _USER_ITEM_CONFIRM(N); else _USER_ITEM(N); }while(0)
#if HAS_USER_ITEM(1)
USER_ITEM(1);
#endif
+7 -5
View File
@@ -211,11 +211,13 @@ void menu_main() {
SUBMENU(MSG_CONFIGURATION, menu_configuration);
#if ENABLED(CUSTOM_USER_MENUS)
#ifdef CUSTOM_USER_MENU_TITLE
SUBMENU_P(PSTR(CUSTOM_USER_MENU_TITLE), menu_user);
#else
SUBMENU(MSG_USER_MENU, menu_user);
#endif
if (TERN1(CUSTOM_MENU_ONLY_IDLE, !busy)) {
#ifdef CUSTOM_USER_MENU_TITLE
SUBMENU_P(PSTR(CUSTOM_USER_MENU_TITLE), menu_user);
#else
SUBMENU(MSG_USER_MENU, menu_user);
#endif
}
#endif
#if ENABLED(ADVANCED_PAUSE_FEATURE)
+104 -71
View File
@@ -1248,32 +1248,6 @@ void Planner::recalculate() {
recalculate_trapezoids();
}
#if ENABLED(AUTOTEMP)
void Planner::getHighESpeed() {
static float oldt = 0;
if (!autotemp_enabled) return;
if (thermalManager.degTargetHotend(0) + 2 < autotemp_min) return; // probably temperature set to zero.
float high = 0.0;
for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
block_t* block = &block_buffer[b];
if (block->steps.x || block->steps.y || block->steps.z) {
const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec;
NOLESS(high, se);
}
}
float t = autotemp_min + high * autotemp_factor;
LIMIT(t, autotemp_min, autotemp_max);
if (t < oldt) t = t * (1 - float(AUTOTEMP_OLDWEIGHT)) + oldt * float(AUTOTEMP_OLDWEIGHT);
oldt = t;
thermalManager.setTargetHotend(t, 0);
}
#endif // AUTOTEMP
/**
* Maintain fans, paste extruder pressure,
*/
@@ -1398,6 +1372,72 @@ void Planner::check_axes_activity() {
#endif
}
#if ENABLED(AUTOTEMP)
#if ENABLED(AUTOTEMP_PROPORTIONAL)
void Planner::_autotemp_update_from_hotend() {
const int16_t target = thermalManager.degTargetHotend(active_extruder);
autotemp_min = target + AUTOTEMP_MIN_P;
autotemp_max = target + AUTOTEMP_MAX_P;
}
#endif
/**
* Called after changing tools to:
* - Reset or re-apply the default proportional autotemp factor.
* - Enable autotemp if the factor is non-zero.
*/
void Planner::autotemp_update() {
_autotemp_update_from_hotend();
autotemp_factor = TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0);
autotemp_enabled = autotemp_factor != 0;
}
/**
* Called by the M104/M109 commands after setting Hotend Temperature
*
*/
void Planner::autotemp_M104_M109() {
_autotemp_update_from_hotend();
if (parser.seenval('S')) autotemp_min = parser.value_celsius();
if (parser.seenval('B')) autotemp_max = parser.value_celsius();
// When AUTOTEMP_PROPORTIONAL is enabled, F0 disables autotemp.
// Normally, leaving off F also disables autotemp.
autotemp_factor = parser.seen('F') ? parser.value_float() : TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0);
autotemp_enabled = autotemp_factor != 0;
}
/**
* Called every so often to adjust the hotend target temperature
* based on the extrusion speed, which is calculated from the blocks
* currently in the planner.
*/
void Planner::getHighESpeed() {
static float oldt = 0;
if (!autotemp_enabled) return;
if (thermalManager.degTargetHotend(active_extruder) < autotemp_min - 2) return; // Below the min?
float high = 0.0;
for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
block_t* block = &block_buffer[b];
if (block->steps.x || block->steps.y || block->steps.z) {
const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec;
NOLESS(high, se);
}
}
float t = autotemp_min + high * autotemp_factor;
LIMIT(t, autotemp_min, autotemp_max);
if (t < oldt) t *= (1.0f - (AUTOTEMP_OLDWEIGHT)) + oldt * (AUTOTEMP_OLDWEIGHT);
oldt = t;
thermalManager.setTargetHotend(t, active_extruder);
}
#endif
#if DISABLED(NO_VOLUMETRICS)
/**
@@ -2959,13 +2999,17 @@ void Planner::reset_acceleration_rates() {
TERN_(HAS_LINEAR_E_JERK, recalculate_max_e_jerk());
}
// Recalculate position, steps_to_mm if settings.axis_steps_per_mm changes!
/**
* Recalculate 'position' and 'steps_to_mm'.
* Must be called whenever settings.axis_steps_per_mm changes!
*/
void Planner::refresh_positioning() {
LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / settings.axis_steps_per_mm[i];
set_position_mm(current_position);
reset_acceleration_rates();
}
// Apply limits to a variable and give a warning if the value was out of range
inline void limit_and_warn(float &val, const uint8_t axis, PGM_P const setting_name, const xyze_float_t &max_limit) {
const uint8_t lim_axis = axis > E_AXIS ? E_AXIS : axis;
const float before = val;
@@ -2978,7 +3022,14 @@ inline void limit_and_warn(float &val, const uint8_t axis, PGM_P const setting_n
}
}
void Planner::set_max_acceleration(const uint8_t axis, float targetValue) {
/**
* For the specified 'axis' set the Maximum Acceleration to the given value (mm/s^2)
* The value may be limited with warning feedback, if configured.
* Calls reset_acceleration_rates to precalculate planner terms in steps.
*
* This hard limit is applied as a block is being added to the planner queue.
*/
void Planner::set_max_acceleration(const uint8_t axis, float inMaxAccelMMS2) {
#if ENABLED(LIMITED_MAX_ACCEL_EDITING)
#ifdef MAX_ACCEL_EDIT_VALUES
constexpr xyze_float_t max_accel_edit = MAX_ACCEL_EDIT_VALUES;
@@ -2987,15 +3038,21 @@ void Planner::set_max_acceleration(const uint8_t axis, float targetValue) {
constexpr xyze_float_t max_accel_edit = DEFAULT_MAX_ACCELERATION;
const xyze_float_t max_acc_edit_scaled = max_accel_edit * 2;
#endif
limit_and_warn(targetValue, axis, PSTR("Acceleration"), max_acc_edit_scaled);
limit_and_warn(inMaxAccelMMS2, axis, PSTR("Acceleration"), max_acc_edit_scaled);
#endif
settings.max_acceleration_mm_per_s2[axis] = targetValue;
settings.max_acceleration_mm_per_s2[axis] = inMaxAccelMMS2;
// Update steps per s2 to agree with the units per s2 (since they are used in the planner)
reset_acceleration_rates();
}
void Planner::set_max_feedrate(const uint8_t axis, float targetValue) {
/**
* For the specified 'axis' set the Maximum Feedrate to the given value (mm/s)
* The value may be limited with warning feedback, if configured.
*
* This hard limit is applied as a block is being added to the planner queue.
*/
void Planner::set_max_feedrate(const uint8_t axis, float inMaxFeedrateMMS) {
#if ENABLED(LIMITED_MAX_FR_EDITING)
#ifdef MAX_FEEDRATE_EDIT_VALUES
constexpr xyze_float_t max_fr_edit = MAX_FEEDRATE_EDIT_VALUES;
@@ -3004,13 +3061,20 @@ void Planner::set_max_feedrate(const uint8_t axis, float targetValue) {
constexpr xyze_float_t max_fr_edit = DEFAULT_MAX_FEEDRATE;
const xyze_float_t max_fr_edit_scaled = max_fr_edit * 2;
#endif
limit_and_warn(targetValue, axis, PSTR("Feedrate"), max_fr_edit_scaled);
limit_and_warn(inMaxFeedrateMMS, axis, PSTR("Feedrate"), max_fr_edit_scaled);
#endif
settings.max_feedrate_mm_s[axis] = targetValue;
settings.max_feedrate_mm_s[axis] = inMaxFeedrateMMS;
}
void Planner::set_max_jerk(const AxisEnum axis, float targetValue) {
#if HAS_CLASSIC_JERK
#if HAS_CLASSIC_JERK
/**
* For the specified 'axis' set the Maximum Jerk (instant change) to the given value (mm/s)
* The value may be limited with warning feedback, if configured.
*
* This hard limit is applied (to the block start speed) as the block is being added to the planner queue.
*/
void Planner::set_max_jerk(const AxisEnum axis, float inMaxJerkMMS) {
#if ENABLED(LIMITED_JERK_EDITING)
constexpr xyze_float_t max_jerk_edit =
#ifdef MAX_JERK_EDIT_VALUES
@@ -3020,13 +3084,12 @@ void Planner::set_max_jerk(const AxisEnum axis, float targetValue) {
(DEFAULT_ZJERK) * 2, (DEFAULT_EJERK) * 2 }
#endif
;
limit_and_warn(targetValue, axis, PSTR("Jerk"), max_jerk_edit);
limit_and_warn(inMaxJerkMMS, axis, PSTR("Jerk"), max_jerk_edit);
#endif
max_jerk[axis] = targetValue;
#else
UNUSED(axis); UNUSED(targetValue);
#endif
}
max_jerk[axis] = inMaxJerkMMS;
}
#endif
#if HAS_WIRED_LCD
@@ -3069,33 +3132,3 @@ void Planner::set_max_jerk(const AxisEnum axis, float targetValue) {
}
#endif
#if ENABLED(AUTOTEMP)
void Planner::autotemp_update() {
#if ENABLED(AUTOTEMP_PROPORTIONAL)
const int16_t target = thermalManager.degTargetHotend(active_extruder);
autotemp_min = target + AUTOTEMP_MIN_P;
autotemp_max = target + AUTOTEMP_MAX_P;
#endif
autotemp_factor = TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0);
autotemp_enabled = autotemp_factor != 0;
}
void Planner::autotemp_M104_M109() {
#if ENABLED(AUTOTEMP_PROPORTIONAL)
const int16_t target = thermalManager.degTargetHotend(active_extruder);
autotemp_min = target + AUTOTEMP_MIN_P;
autotemp_max = target + AUTOTEMP_MAX_P;
#endif
if (parser.seenval('S')) autotemp_min = parser.value_celsius();
if (parser.seenval('B')) autotemp_max = parser.value_celsius();
// When AUTOTEMP_PROPORTIONAL is enabled, F0 disables autotemp.
// Normally, leaving off F also disables autotemp.
autotemp_factor = parser.seen('F') ? parser.value_float() : TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0);
autotemp_enabled = autotemp_factor != 0;
}
#endif
+29 -6
View File
@@ -460,12 +460,27 @@ class Planner {
* Static (class) Methods
*/
// Recalculate steps/s^2 accelerations based on mm/s^2 settings
static void reset_acceleration_rates();
static void refresh_positioning();
static void set_max_acceleration(const uint8_t axis, float targetValue);
static void set_max_feedrate(const uint8_t axis, float targetValue);
static void set_max_jerk(const AxisEnum axis, float targetValue);
/**
* Recalculate 'position' and 'steps_to_mm'.
* Must be called whenever settings.axis_steps_per_mm changes!
*/
static void refresh_positioning();
// For an axis set the Maximum Acceleration in mm/s^2
static void set_max_acceleration(const uint8_t axis, float inMaxAccelMMS2);
// For an axis set the Maximum Feedrate in mm/s
static void set_max_feedrate(const uint8_t axis, float inMaxFeedrateMMS);
// For an axis set the Maximum Jerk (instant change) in mm/s
#if HAS_CLASSIC_JERK
static void set_max_jerk(const AxisEnum axis, float inMaxJerkMMS);
#else
static inline void set_max_jerk(const AxisEnum, const float&) {}
#endif
#if EXTRUDERS
FORCE_INLINE static void refresh_e_factor(const uint8_t e) {
@@ -883,9 +898,9 @@ class Planner {
#if ENABLED(AUTOTEMP)
static float autotemp_min, autotemp_max, autotemp_factor;
static bool autotemp_enabled;
static void getHighESpeed();
static void autotemp_M104_M109();
static void autotemp_update();
static void autotemp_M104_M109();
static void getHighESpeed();
#endif
#if HAS_LINEAR_E_JERK
@@ -898,6 +913,14 @@ class Planner {
private:
#if ENABLED(AUTOTEMP)
#if ENABLED(AUTOTEMP_PROPORTIONAL)
static void _autotemp_update_from_hotend();
#else
static inline void _autotemp_update_from_hotend() {}
#endif
#endif
/**
* Get the index of the next / previous block in the ring buffer
*/
+2
View File
@@ -447,6 +447,8 @@
#include "sam/pins_PRINTRBOARD_G2.h" // SAM3X8C env:DUE_USB
#elif MB(CNCONTROLS_15D)
#include "sam/pins_CNCONTROLS_15D.h" // SAM3X8E env:DUE env:DUE_USB
#elif MB(KRATOS32)
#include "sam/pins_KRATOS32.h" // SAM3X8E env:DUE env:DUE_USB
//
// STM32 ARM Cortex-M0
+179
View File
@@ -0,0 +1,179 @@
/**
* 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
/**
* KRATOS32
*/
#include "env_validate.h"
#define BOARD_INFO_NAME "K.3D KRATOS32"
//
// EEPROM
//
#if EITHER(NO_EEPROM_SELECTED, I2C_EEPROM)
#define I2C_EEPROM
#define MARLIN_EEPROM_SIZE 0x1F400 // 16KB
#endif
//
// Servos
//
#define SERVO0_PIN 6
#define SERVO1_PIN 5
#define SERVO2_PIN 39
#define SERVO3_PIN 40 // CAMERA_PIN (extended to the top of the LCD module)
#define SERVO4_PIN 45 // FIL_RUNOUT_PIN
//
// Limit Switches
//
#define X_MIN_PIN 28
#define X_MAX_PIN 34
#define Y_MIN_PIN 30
#define Y_MAX_PIN 36
#define Z_MIN_PIN 32
#define Z_MAX_PIN 38
//
// Steppers
//
#define X_STEP_PIN 24
#define X_DIR_PIN 23
#define X_ENABLE_PIN 26
#ifndef X_CS_PIN
#define X_CS_PIN 25
#endif
#define Y_STEP_PIN 17
#define Y_DIR_PIN 16
#define Y_ENABLE_PIN 22
#ifndef Y_CS_PIN
#define Y_CS_PIN 27
#endif
#define Z_STEP_PIN 2
#define Z_DIR_PIN 3
#define Z_ENABLE_PIN 15
#ifndef Z_CS_PIN
#define Z_CS_PIN 29
#endif
#define E0_STEP_PIN 61
#define E0_DIR_PIN 60
#define E0_ENABLE_PIN 62
#ifndef E0_CS_PIN
#define E0_CS_PIN 31
#endif
#define E1_STEP_PIN 64
#define E1_DIR_PIN 63
#define E1_ENABLE_PIN 65
#ifndef E1_CS_PIN
#define E1_CS_PIN 37
#endif
#define E2_STEP_PIN 68
#define E2_DIR_PIN 67
#define E2_ENABLE_PIN 69
#ifndef E2_CS_PIN
#define E2_CS_PIN 35
#endif
#define E3_STEP_PIN 51
#define E3_DIR_PIN 53
#define E3_ENABLE_PIN 49
#ifndef E3_CS_PIN
#define E3_CS_PIN 33
#endif
//
// Temperature Sensors
//
#define TEMP_0_PIN 0 // Analog Input
#define TEMP_1_PIN 1 // Analog Input
#define TEMP_2_PIN 2 // Analog Input
#define TEMP_3_PIN 3 // Analog Input
#define TEMP_BED_PIN 4 // Analog Input
//
// Heaters / Fans
//
#define HEATER_0_PIN 13
#define HEATER_1_PIN 12
#define HEATER_2_PIN 11
#define HEATER_3_PIN 10
#define HEATER_BED_PIN 7 // BED
#ifndef FAN_PIN
#define FAN_PIN 9
#endif
#define FAN1_PIN 8
//
// Misc. Functions
//
#ifndef FIL_RUNOUT_PIN
#define FIL_RUNOUT_PIN 45 // SERVO4_PIN
#endif
#ifndef PS_ON_PIN
#define PS_ON_PIN 59
#endif
//
// LCD / Controller
//
#if HAS_WIRED_LCD
#define BTN_EN1 48
#define BTN_EN2 50
#define BTN_ENC 46
#define SDSS 4
#define SD_DETECT_PIN 14
#define BEEPER_PIN 41
#define KILL_PIN 66
#if IS_RRD_FG_SC
#define LCD_PINS_RS 42
#define LCD_PINS_ENABLE 43
#define LCD_PINS_D4 44
#define BTN_BACK 52
#elif ENABLED(K3D_242_OLED_CONTROLLER)
#define LCD_PINS_DC 44
#define LCD_PINS_RS 42
#define DOGLCD_CS 52
#define DOGLCD_MOSI 43
#define DOGLCD_SCK 47
#define DOGLCD_A0 LCD_PINS_DC
#endif
#endif // HAS_WIRED_LCD
+1 -1
View File
@@ -29,7 +29,7 @@
#define BOARD_ST7920_DELAY_1 DELAY_NS(0)
#endif
#ifndef BOARD_ST7920_DELAY_2
#define BOARD_ST7920_DELAY_2 DELAY_NS(188)
#define BOARD_ST7920_DELAY_2 DELAY_NS(400)
#endif
#ifndef BOARD_ST7920_DELAY_3
#define BOARD_ST7920_DELAY_3 DELAY_NS(0)
@@ -441,10 +441,10 @@
// Alter timing for graphical display
#if HAS_MARLINUI_U8GLIB
#ifndef BOARD_ST7920_DELAY_1
#define BOARD_ST7920_DELAY_1 DELAY_NS(96)
#define BOARD_ST7920_DELAY_1 DELAY_NS(125)
#endif
#ifndef BOARD_ST7920_DELAY_2
#define BOARD_ST7920_DELAY_2 DELAY_NS(48)
#define BOARD_ST7920_DELAY_2 DELAY_NS(90)
#endif
#ifndef BOARD_ST7920_DELAY_3
#define BOARD_ST7920_DELAY_3 DELAY_NS(600)
+13 -13
View File
@@ -30,7 +30,6 @@ OPTIONS
-v --verbose Extra output for debugging.
env shortcuts: tree due esp lin lpc|lpc8 lpc9 m128 m256|mega stm|f1 f4 f7 s6 teensy|t31|t32 t35|t36 t40|t41
"
}
@@ -58,47 +57,48 @@ while getopts 'abhmruvyn:t:-:' OFLAG; do
h) EXIT_USAGE=1 ;;
m) USE_MAKE=1 ; bugout "Using make with Docker..." ;;
n) case "$OPTARG" in
*[!0-9]*) perror "option requires a number" $OFLAG ; EXIT_USAGE=1 ;;
*[!0-9]*) perror "option requires a number" $OFLAG ; EXIT_USAGE=2 ;;
*) CHOICE="$OPTARG" ; bugout "Got a number: $CHOICE" ;;
esac
;;
r) REBUILD=1 ; bugout "Rebuilding previous..." ;;
r) REBUILD=1 ; bugout "Rebuilding previous..." ;;
t) TESTENV="$OPTARG" ; bugout "Got a target: $TESTENV" ;;
u) AUTO_BUILD=2 ; bugout "Auto-Upload target..." ;;
u) AUTO_BUILD=2 ; bugout "Auto-Upload target..." ;;
v) DEBUG=1 ; bugout "Debug ON" ;;
y) BUILD_YES='Y' ; bugout "Build will initiate..." ;;
y) BUILD_YES='Y' ; bugout "Build will initiate..." ;;
-) IFS="=" read -r ONAM OVAL <<< "$OPTARG"
case "$ONAM" in
help) [[ -z "$OVAL" ]] || perror "option can't take value $OVAL" $ONAM ; EXIT_USAGE=1 ;;
autobuild) AUTO_BUILD=1 ; bugout "Auto-Build target..." ;;
autoupload) AUTO_BUILD=2 ; bugout "Auto-Upload target..." ;;
env) case "$OVAL" in
'') perror "option requires a value" $ONAM ; EXIT_USAGE=1 ;;
'') perror "option requires a value" $ONAM ; EXIT_USAGE=2 ;;
*) TESTENV="$OVAL" ; bugout "Got a target: $TESTENV" ;;
esac
;;
num) case "$OVAL" in
[0-9]+) CHOICE="$OVAL" ; bugout "Got a number: $CHOICE" ;;
*) perror "option requires a value" $ONAM ; EXIT_USAGE=1 ;;
*) perror "option requires a value" $ONAM ; EXIT_USAGE=2 ;;
esac
;;
rebuild) REBUILD=1 ; bugout "Rebuilding previous..." ;;
make) USE_MAKE=1 ; bugout "Using make with Docker..." ;;
debug|verbose) DEBUG=1 ; bugout "Debug ON" ;;
rebuild) REBUILD=1 ; bugout "Rebuilding previous..." ;;
make) USE_MAKE=1 ; bugout "Using make with Docker..." ;;
debug|verbose) DEBUG=1 ; bugout "Debug ON" ;;
build) case "$OVAL" in
''|y|yes) BUILD_YES='Y' ;;
n|no) BUILD_YES='N' ;;
*) perror "option value must be y, n, yes, or no" $ONAM ; EXIT_USAGE=1 ;;
*) perror "option value must be y, n, yes, or no" $ONAM ; EXIT_USAGE=2 ;;
esac
bugout "Build will initiate? ($BUILD_YES)"
;;
*) perror "Unknown flag" "$OPTARG" ; EXIT_USAGE=1 ;;
*) perror "Unknown flag" "$OPTARG" ; EXIT_USAGE=2 ;;
esac
;;
*) EXIT_USAGE=2 ;;
esac
done
((EXIT_USAGE)) && { usage ; exit 1 ; }
((EXIT_USAGE)) && { usage ; let EXIT_USAGE-- ; exit $EXIT_USAGE ; }
if ((REBUILD)); then
bugout "Rebuilding previous..."
@@ -22,10 +22,9 @@ def add_cpu_freq():
#
# It will separe release and debug build folders.
# It useful when we need keep two live versions: one debug, for debugging,
# other release, for flashing.
# other release, for flashing (when upload is not done automatically by jlink/stlink).
# Without this, PIO will recompile everything twice for any small change.
#
if env.GetBuildType() == "debug":
if env.GetBuildType() == "debug" and env.get('UPLOAD_PROTOCOL') not in ['jlink', 'stlink']:
env['BUILD_DIR'] = '$PROJECT_BUILD_DIR/$PIOENV/debug'
# On some platform, F_CPU is a runtime variable. Since it's used to convert from ns
@@ -26,8 +26,6 @@
* Used by common-dependencies.py
*/
#define NUM_SERIAL 1 // Normally provided by HAL/HAL.h
#include "../../../../Marlin/src/inc/MarlinConfig.h"
//
@@ -2,33 +2,45 @@
# preflight-checks.py
# Check for common issues prior to compiling
#
import os,re
import os,re,sys
Import("env")
def get_envs_for_board(board):
if board.startswith("BOARD_"):
board = board[6:]
with open(os.path.join("Marlin", "src", "pins", "pins.h"),"r") as f:
board_found = ""
r=re.compile(r"if\s+MB\((.+)\)")
for line in f.readlines():
with open(os.path.join("Marlin", "src", "pins", "pins.h"), "r") as file:
if sys.platform == 'win32':
envregex = r"(?:env|win):"
elif sys.platform == 'darwin':
envregex = r"(?:env|mac|uni):"
elif sys.platform == 'linux':
envregex = r"(?:env|lin|uni):"
else:
envregex = r"(?:env):"
r = re.compile(r"if\s+MB\((.+)\)")
if board.startswith("BOARD_"):
board = board[6:]
for line in file:
mbs = r.findall(line)
if mbs:
board_found = board if board in re.split(r",\s*", mbs[0]) else ""
if board_found and "#include " in line and "env:" in line:
return re.findall(r"env:\w+", line)
if mbs and board in re.split(r",\s*", mbs[0]):
line = file.readline()
found_envs = re.match(r"\s*#include .+" + envregex, line)
if found_envs:
envlist = re.findall(envregex + r"(\w+)", line)
return [ "env:"+s for s in envlist ]
return []
def check_envs(build_env, base_envs, config):
if build_env in base_envs:
def check_envs(build_env, board_envs, config):
if build_env in board_envs:
return True
ext = config.get(build_env, 'extends', default=None)
if ext:
if isinstance(ext, str):
return check_envs(ext, base_envs, config)
return check_envs(ext, board_envs, config)
elif isinstance(ext, list):
for ext_env in ext:
if check_envs(ext_env, base_envs, config):
if check_envs(ext_env, board_envs, config):
return True
return False
@@ -44,13 +56,13 @@ if 'MOTHERBOARD' not in env['MARLIN_FEATURES']:
build_env = env['PIOENV']
motherboard = env['MARLIN_FEATURES']['MOTHERBOARD']
base_envs = get_envs_for_board(motherboard)
board_envs = get_envs_for_board(motherboard)
config = env.GetProjectConfig()
result = check_envs("env:"+build_env, base_envs, config)
result = check_envs("env:"+build_env, board_envs, config)
if not result:
err = "Error: Build environment '%s' is incompatible with %s. Use one of these: %s" % \
(build_env, motherboard, ",".join([e[4:] for e in base_envs if e.startswith("env:")]))
( build_env, motherboard, ", ".join([ e[4:] for e in board_envs if e.startswith("env:") ]) )
raise SystemExit(err)
#
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env python3
#
# 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/>.
#
# Generate Marlin TFT Images from bitmaps/PNG/JPG
import sys,re,struct
from PIL import Image,ImageDraw
def image2bin(image, output_file):
if output_file.endswith(('.c', '.cpp')):
f = open(output_file, 'wt')
is_cpp = True
f.write("const uint16_t image[%d] = {\n" % (image.size[1] * image.size[0]))
else:
f = open(output_file, 'wb')
is_cpp = False
pixs = image.load()
for y in range(image.size[1]):
for x in range(image.size[0]):
R = pixs[x, y][0] >> 3
G = pixs[x, y][1] >> 2
B = pixs[x, y][2] >> 3
rgb = (R << 11) | (G << 5) | B
if is_cpp:
strHex = '0x{0:04X}, '.format(rgb)
f.write(strHex)
else:
f.write(struct.pack("B", (rgb & 0xFF)))
f.write(struct.pack("B", (rgb >> 8) & 0xFF))
if is_cpp:
f.write("\n")
if is_cpp:
f.write("};\n")
f.close()
if len(sys.argv) <= 2:
print("Utility to export a image in Marlin TFT friendly format.")
print("It will dump a raw bin RGB565 image or create a CPP file with an array of 16 bit image pixels.")
print("Usage: gen-tft-image.py INPUT_IMAGE.(png|bmp|jpg) OUTPUT_FILE.(cpp|bin)")
print("Author: rhapsodyv")
exit(1)
output_img = sys.argv[2]
img = Image.open(sys.argv[1])
image2bin(img, output_img)

Before

Width:  |  Height:  |  Size: 881 B

After

Width:  |  Height:  |  Size: 881 B

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

+2
View File
@@ -59,6 +59,7 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
-<src/lcd/extui/lib/ftdi_eve_touch_ui>
-<src/lcd/extui/anycubic_chiron_lcd.cpp> -<src/lcd/extui/lib/anycubic_chiron>
-<src/lcd/extui/anycubic_i3mega_lcd.cpp> -<src/lcd/extui/lib/anycubic_i3mega>
-<src/lcd/extui/nextion_lcd.cpp> -<src/lcd/extui/lib/nextion>
-<src/lcd/lcdprint.cpp>
-<src/lcd/touch/touch_buttons.cpp>
-<src/sd/usb_flashdrive/lib-uhs2> -<src/sd/usb_flashdrive/lib-uhs3>
@@ -289,6 +290,7 @@ HAS_MENU_TRAMMING = src_filter=+<src/lcd/menu/menu_tramming.cpp>
HAS_MENU_UBL = src_filter=+<src/lcd/menu/menu_ubl.cpp>
ANYCUBIC_LCD_CHIRON = src_filter=+<src/lcd/extui/anycubic_chiron_lcd.cpp> +<src/lcd/extui/lib/anycubic_chiron>
ANYCUBIC_LCD_I3MEGA = src_filter=+<src/lcd/extui/anycubic_i3mega_lcd.cpp> +<src/lcd/extui/lib/anycubic_i3mega>
NEXTION_TFT = src_filter=+<src/lcd/extui/nextion_lcd.cpp> +<src/lcd/extui/lib/nextion>
HAS_DGUS_LCD = src_filter=+<src/lcd/extui/lib/dgus> +<src/lcd/extui/dgus_lcd.cpp>
DGUS_LCD_UI_FYSETC = src_filter=+<src/lcd/extui/lib/dgus/fysetc>
DGUS_LCD_UI_HIPRECY = src_filter=+<src/lcd/extui/lib/dgus/hiprecy>