🔧 Config INI, dump options (#24528)
This commit is contained in:
parent
9a42d1e577
commit
bbf2033211
@ -112,6 +112,7 @@
|
||||
* :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000]
|
||||
*/
|
||||
#define BAUDRATE 250000
|
||||
|
||||
//#define BAUD_RATE_GCODE // Enable G-code M575 to set the baud rate
|
||||
|
||||
/**
|
||||
@ -120,7 +121,7 @@
|
||||
* :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
|
||||
*/
|
||||
//#define SERIAL_PORT_2 -1
|
||||
//#define BAUDRATE_2 250000 // Enable to override BAUDRATE
|
||||
//#define BAUDRATE_2 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE
|
||||
|
||||
/**
|
||||
* Select a third serial port on the board to use for communication with the host.
|
||||
@ -128,7 +129,7 @@
|
||||
* :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
|
||||
*/
|
||||
//#define SERIAL_PORT_3 1
|
||||
//#define BAUDRATE_3 250000 // Enable to override BAUDRATE
|
||||
//#define BAUDRATE_3 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE
|
||||
|
||||
// Enable the Bluetooth serial interface on AT90USB devices
|
||||
//#define BLUETOOTH
|
||||
@ -387,7 +388,7 @@
|
||||
//#define HOTEND_OFFSET_Y { 0.0, 5.00 } // (mm) relative Y-offset for each nozzle
|
||||
//#define HOTEND_OFFSET_Z { 0.0, 0.00 } // (mm) relative Z-offset for each nozzle
|
||||
|
||||
// @section machine
|
||||
// @section psu control
|
||||
|
||||
/**
|
||||
* Power Supply Control
|
||||
@ -549,22 +550,32 @@
|
||||
#define DUMMY_THERMISTOR_999_VALUE 100
|
||||
|
||||
// Resistor values when using MAX31865 sensors (-5) on TEMP_SENSOR_0 / 1
|
||||
//#define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000)
|
||||
//#define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for Adafruit PT100; 4300 for Adafruit PT1000
|
||||
//#define MAX31865_SENSOR_OHMS_1 100
|
||||
//#define MAX31865_CALIBRATION_OHMS_1 430
|
||||
#if TEMP_SENSOR_IS_MAX_TC(0)
|
||||
#define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000)
|
||||
#define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for Adafruit PT100; 4300 for Adafruit PT1000
|
||||
#endif
|
||||
#if TEMP_SENSOR_IS_MAX_TC(1)
|
||||
#define MAX31865_SENSOR_OHMS_1 100
|
||||
#define MAX31865_CALIBRATION_OHMS_1 430
|
||||
#endif
|
||||
|
||||
#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
|
||||
#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
||||
#define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
||||
#if HAS_E_TEMP_SENSOR
|
||||
#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
|
||||
#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
||||
#define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
||||
#endif
|
||||
|
||||
#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) Time to wait for bed to "settle" in M190
|
||||
#define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
||||
#define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
||||
#if TEMP_SENSOR_BED
|
||||
#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) Time to wait for bed to "settle" in M190
|
||||
#define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
||||
#define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
||||
#endif
|
||||
|
||||
#define TEMP_CHAMBER_RESIDENCY_TIME 10 // (seconds) Time to wait for chamber to "settle" in M191
|
||||
#define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
||||
#define TEMP_CHAMBER_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
||||
#if TEMP_SENSOR_CHAMBER
|
||||
#define TEMP_CHAMBER_RESIDENCY_TIME 10 // (seconds) Time to wait for chamber to "settle" in M191
|
||||
#define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
||||
#define TEMP_CHAMBER_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Redundant Temperature Sensor (TEMP_SENSOR_REDUNDANT)
|
||||
@ -623,6 +634,8 @@
|
||||
//============================= PID Settings ================================
|
||||
//===========================================================================
|
||||
|
||||
// @section hotend temp
|
||||
|
||||
// Enable PIDTEMP for PID control or MPCTEMP for Predictive Model.
|
||||
// temperature control. Disable both for bang-bang heating.
|
||||
#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning
|
||||
@ -633,7 +646,8 @@
|
||||
#define PID_K1 0.95 // Smoothing factor within any PID loop
|
||||
|
||||
#if ENABLED(PIDTEMP)
|
||||
//#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders)
|
||||
//#define PID_DEBUG // Print PID debug data to the serial port. Use 'M303 D' to toggle activation.
|
||||
//#define PID_PARAMS_PER_HOTEND // Use separate PID parameters for each extruder (useful for mismatched extruders)
|
||||
// Set/get with G-code: M301 E[extruder number, 0-2]
|
||||
|
||||
#if ENABLED(PID_PARAMS_PER_HOTEND)
|
||||
@ -655,6 +669,7 @@
|
||||
* Use a physical model of the hotend to control temperature. When configured correctly
|
||||
* this gives better responsiveness and stability than PID and it also removes the need
|
||||
* for PID_EXTRUSION_SCALING and PID_FAN_SCALING. Use M306 T to autotune the model.
|
||||
* @section mpctemp
|
||||
*/
|
||||
#if ENABLED(MPCTEMP)
|
||||
//#define MPC_EDIT_MENU // Add MPC editing to the "Advanced Settings" menu. (~1300 bytes of flash)
|
||||
@ -707,6 +722,7 @@
|
||||
* impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W
|
||||
* heater. If your configuration is significantly different than this and you don't understand
|
||||
* the issues involved, don't use bed PID until someone else verifies that your hardware works.
|
||||
* @section bed temp
|
||||
*/
|
||||
//#define PIDTEMPBED
|
||||
|
||||
@ -722,7 +738,7 @@
|
||||
|
||||
#if ENABLED(PIDTEMPBED)
|
||||
//#define MIN_BED_POWER 0
|
||||
//#define PID_BED_DEBUG // Sends debug data to the serial port.
|
||||
//#define PID_BED_DEBUG // Print Bed PID debug data to the serial port.
|
||||
|
||||
// 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
|
||||
// from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
|
||||
@ -750,6 +766,7 @@
|
||||
* impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 200W
|
||||
* heater. If your configuration is significantly different than this and you don't understand
|
||||
* the issues involved, don't use chamber PID until someone else verifies that your hardware works.
|
||||
* @section chamber temp
|
||||
*/
|
||||
//#define PIDTEMPCHAMBER
|
||||
//#define CHAMBER_LIMIT_SWITCHING
|
||||
@ -764,7 +781,7 @@
|
||||
|
||||
#if ENABLED(PIDTEMPCHAMBER)
|
||||
#define MIN_CHAMBER_POWER 0
|
||||
//#define PID_CHAMBER_DEBUG // Sends debug data to the serial port.
|
||||
//#define PID_CHAMBER_DEBUG // Print Chamber PID debug data to the serial port.
|
||||
|
||||
// Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element
|
||||
// and placed inside the small Creality printer enclosure tent.
|
||||
@ -778,7 +795,6 @@
|
||||
#endif // PIDTEMPCHAMBER
|
||||
|
||||
#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER)
|
||||
//#define PID_DEBUG // Sends debug data to the serial port. Use 'M303 D' to toggle activation.
|
||||
//#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
|
||||
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
|
||||
#define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
|
||||
@ -788,7 +804,7 @@
|
||||
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash)
|
||||
#endif
|
||||
|
||||
// @section extruder
|
||||
// @section safety
|
||||
|
||||
/**
|
||||
* Prevent extrusion if the temperature is below EXTRUDE_MINTEMP.
|
||||
@ -856,6 +872,8 @@
|
||||
#define POLAR_SEGMENTS_PER_SECOND 5
|
||||
#endif
|
||||
|
||||
// @section delta
|
||||
|
||||
// Enable for DELTA kinematics and configure below
|
||||
//#define DELTA
|
||||
#if ENABLED(DELTA)
|
||||
@ -915,6 +933,8 @@
|
||||
//#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 }
|
||||
#endif
|
||||
|
||||
// @section scara
|
||||
|
||||
/**
|
||||
* MORGAN_SCARA was developed by QHARLEY in South Africa in 2012-2013.
|
||||
* Implemented and slightly reworked by JCERNY in June, 2014.
|
||||
@ -958,6 +978,8 @@
|
||||
|
||||
#endif
|
||||
|
||||
// @section tpara
|
||||
|
||||
// Enable for TPARA kinematics and configure below
|
||||
//#define AXEL_TPARA
|
||||
#if ENABLED(AXEL_TPARA)
|
||||
@ -984,6 +1006,8 @@
|
||||
#define PSI_HOMING_OFFSET 0
|
||||
#endif
|
||||
|
||||
// @section machine
|
||||
|
||||
// Articulated robot (arm). Joints are directly mapped to axes with no kinematics.
|
||||
//#define ARTICULATED_ROBOT_ARM
|
||||
|
||||
@ -995,7 +1019,7 @@
|
||||
//============================== Endstop Settings ===========================
|
||||
//===========================================================================
|
||||
|
||||
// @section homing
|
||||
// @section endstops
|
||||
|
||||
// Specify here all the endstop connectors that are connected to any endstop or probe.
|
||||
// Almost all printers will be using one per axis. Probes will use one or more of the
|
||||
@ -1659,7 +1683,7 @@
|
||||
//#define V_HOME_DIR -1
|
||||
//#define W_HOME_DIR -1
|
||||
|
||||
// @section machine
|
||||
// @section geometry
|
||||
|
||||
// The size of the printable area
|
||||
#define X_BED_SIZE 200
|
||||
@ -2119,7 +2143,7 @@
|
||||
//============================= Additional Features ===========================
|
||||
//=============================================================================
|
||||
|
||||
// @section extras
|
||||
// @section eeprom
|
||||
|
||||
/**
|
||||
* EEPROM
|
||||
@ -2139,6 +2163,8 @@
|
||||
//#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build.
|
||||
#endif
|
||||
|
||||
// @section host
|
||||
|
||||
//
|
||||
// Host Keepalive
|
||||
//
|
||||
@ -2149,6 +2175,8 @@
|
||||
#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113.
|
||||
#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating
|
||||
|
||||
// @section units
|
||||
|
||||
//
|
||||
// G20/G21 Inch mode support
|
||||
//
|
||||
@ -2176,6 +2204,8 @@
|
||||
#define PREHEAT_2_TEMP_CHAMBER 35
|
||||
#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255
|
||||
|
||||
// @section motion
|
||||
|
||||
/**
|
||||
* Nozzle Park
|
||||
*
|
||||
@ -2274,6 +2304,8 @@
|
||||
|
||||
#endif
|
||||
|
||||
// @section host
|
||||
|
||||
/**
|
||||
* Print Job Timer
|
||||
*
|
||||
@ -2300,6 +2332,8 @@
|
||||
*/
|
||||
#define PRINTJOB_TIMER_AUTOSTART
|
||||
|
||||
// @section stats
|
||||
|
||||
/**
|
||||
* Print Counter
|
||||
*
|
||||
@ -2317,6 +2351,8 @@
|
||||
#define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print
|
||||
#endif
|
||||
|
||||
// @section security
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
@ -2352,7 +2388,7 @@
|
||||
//============================= LCD and SD support ============================
|
||||
//=============================================================================
|
||||
|
||||
// @section lcd
|
||||
// @section interface
|
||||
|
||||
/**
|
||||
* LCD LANGUAGE
|
||||
@ -2508,6 +2544,7 @@
|
||||
//======================== LCD / Controller Selection =========================
|
||||
//======================== (Character-based LCDs) =========================
|
||||
//=============================================================================
|
||||
// @section lcd
|
||||
|
||||
//
|
||||
// RepRapDiscount Smart Controller.
|
||||
@ -3142,7 +3179,7 @@
|
||||
//=============================== Extra Features ==============================
|
||||
//=============================================================================
|
||||
|
||||
// @section extras
|
||||
// @section fans
|
||||
|
||||
// Set number of user-controlled fans. Disable to use all board-defined fans.
|
||||
// :[1,2,3,4,5,6,7,8]
|
||||
@ -3166,14 +3203,18 @@
|
||||
// duty cycle is attained.
|
||||
//#define SOFT_PWM_DITHER
|
||||
|
||||
// @section extras
|
||||
|
||||
// Support for the BariCUDA Paste Extruder
|
||||
//#define BARICUDA
|
||||
|
||||
// @section lights
|
||||
|
||||
// Temperature status LEDs that display the hotend and bed temperature.
|
||||
// If all hotends, bed temperature, and target temperature are under 54C
|
||||
// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis)
|
||||
//#define TEMP_STAT_LEDS
|
||||
|
||||
// Support for the BariCUDA Paste Extruder
|
||||
//#define BARICUDA
|
||||
|
||||
// Support for BlinkM/CyzRgb
|
||||
//#define BLINKM
|
||||
|
||||
@ -3259,6 +3300,8 @@
|
||||
#define PRINTER_EVENT_LEDS
|
||||
#endif
|
||||
|
||||
// @section servos
|
||||
|
||||
/**
|
||||
* Number of servos
|
||||
*
|
||||
|
@ -32,6 +32,24 @@
|
||||
*/
|
||||
#define CONFIGURATION_ADV_H_VERSION 02010100
|
||||
|
||||
// @section develop
|
||||
|
||||
/**
|
||||
* Configuration Export
|
||||
*
|
||||
* Export the configuration as part of the build. (See signature.py)
|
||||
* Output files are saved with the build (e.g., .pio/build/mega2560).
|
||||
*
|
||||
* See `build_all_examples --ini` as an example of config.ini archiving.
|
||||
*
|
||||
* 1 = marlin_config.json - Dictionary containing the configuration.
|
||||
* This file is also generated for CONFIGURATION_EMBEDDING.
|
||||
* 2 = config.ini - File format for PlatformIO preprocessing.
|
||||
* 3 = schema.json - The entire configuration schema. (13 = pattern groups)
|
||||
* 4 = schema.yml - The entire configuration schema.
|
||||
*/
|
||||
//#define CONFIG_EXPORT // :[1:'JSON', 2:'config.ini', 3:'schema.json', 4:'schema.yml']
|
||||
|
||||
//===========================================================================
|
||||
//============================= Thermal Settings ============================
|
||||
//===========================================================================
|
||||
@ -2545,6 +2563,8 @@
|
||||
#endif
|
||||
#endif // HAS_MULTI_EXTRUDER
|
||||
|
||||
// @section advanced pause
|
||||
|
||||
/**
|
||||
* Advanced Pause for Filament Change
|
||||
* - Adds the G-code M600 Filament Change to initiate a filament change.
|
||||
@ -2603,13 +2623,12 @@
|
||||
//#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302)
|
||||
#endif
|
||||
|
||||
// @section tmc
|
||||
|
||||
/**
|
||||
* TMC26X Stepper Driver options
|
||||
*
|
||||
* The TMC26XStepper library is required for this stepper driver.
|
||||
* https://github.com/trinamic/TMC26XStepper
|
||||
* @section tmc/tmc26x
|
||||
*/
|
||||
#if HAS_DRIVER(TMC26X)
|
||||
|
||||
@ -2747,8 +2766,6 @@
|
||||
|
||||
#endif // TMC26X
|
||||
|
||||
// @section tmc_smart
|
||||
|
||||
/**
|
||||
* To use TMC2130, TMC2160, TMC2660, TMC5130, TMC5160 stepper drivers in SPI mode
|
||||
* connect your SPI pins to the hardware SPI interface on your board and define
|
||||
@ -2764,6 +2781,7 @@
|
||||
*
|
||||
* TMCStepper library is required to use TMC stepper drivers.
|
||||
* https://github.com/teemuatlut/TMCStepper
|
||||
* @section tmc/config
|
||||
*/
|
||||
#if HAS_TRINAMIC_CONFIG
|
||||
|
||||
@ -2987,6 +3005,8 @@
|
||||
//#define E7_HOLD_MULTIPLIER 0.5
|
||||
#endif
|
||||
|
||||
// @section tmc/spi
|
||||
|
||||
/**
|
||||
* Override default SPI pins for TMC2130, TMC2160, TMC2660, TMC5130 and TMC5160 drivers here.
|
||||
* The default pins can be found in your board's pins file.
|
||||
@ -3024,6 +3044,8 @@
|
||||
//#define TMC_SW_MISO -1
|
||||
//#define TMC_SW_SCK -1
|
||||
|
||||
// @section tmc/serial
|
||||
|
||||
/**
|
||||
* Four TMC2209 drivers can use the same HW/SW serial port with hardware configured addresses.
|
||||
* Set the address using jumpers on pins MS1 and MS2.
|
||||
@ -3059,6 +3081,8 @@
|
||||
//#define E6_SLAVE_ADDRESS 0
|
||||
//#define E7_SLAVE_ADDRESS 0
|
||||
|
||||
// @section tmc/smart
|
||||
|
||||
/**
|
||||
* Software enable
|
||||
*
|
||||
@ -3067,6 +3091,8 @@
|
||||
*/
|
||||
//#define SOFTWARE_DRIVER_ENABLE
|
||||
|
||||
// @section tmc/stealthchop
|
||||
|
||||
/**
|
||||
* TMC2130, TMC2160, TMC2208, TMC2209, TMC5130 and TMC5160 only
|
||||
* Use Trinamic's ultra quiet stepping mode.
|
||||
@ -3121,6 +3147,8 @@
|
||||
//#define CHOPPER_TIMING_E6 CHOPPER_TIMING_E
|
||||
//#define CHOPPER_TIMING_E7 CHOPPER_TIMING_E
|
||||
|
||||
// @section tmc/status
|
||||
|
||||
/**
|
||||
* Monitor Trinamic drivers
|
||||
* for error conditions like overtemperature and short to ground.
|
||||
@ -3140,6 +3168,8 @@
|
||||
#define STOP_ON_ERROR
|
||||
#endif
|
||||
|
||||
// @section tmc/hybrid
|
||||
|
||||
/**
|
||||
* TMC2130, TMC2160, TMC2208, TMC2209, TMC5130 and TMC5160 only
|
||||
* The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD.
|
||||
@ -3196,6 +3226,7 @@
|
||||
* homing and adds a guard period for endstop triggering.
|
||||
*
|
||||
* Comment *_STALL_SENSITIVITY to disable sensorless homing for that axis.
|
||||
* @section tmc/stallguard
|
||||
*/
|
||||
//#define SENSORLESS_HOMING // StallGuard capable drivers only
|
||||
|
||||
@ -3219,6 +3250,8 @@
|
||||
//#define IMPROVE_HOMING_RELIABILITY
|
||||
#endif
|
||||
|
||||
// @section tmc/config
|
||||
|
||||
/**
|
||||
* TMC Homing stepper phase.
|
||||
*
|
||||
@ -3258,7 +3291,6 @@
|
||||
|
||||
#endif // HAS_TRINAMIC_CONFIG
|
||||
|
||||
|
||||
// @section i2cbus
|
||||
|
||||
//
|
||||
@ -3300,7 +3332,7 @@
|
||||
#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave
|
||||
#endif
|
||||
|
||||
// @section extras
|
||||
// @section photo
|
||||
|
||||
/**
|
||||
* Photo G-code
|
||||
@ -3343,6 +3375,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// @section cnc
|
||||
|
||||
/**
|
||||
* Spindle & Laser control
|
||||
*
|
||||
@ -3546,6 +3580,8 @@
|
||||
#define COOLANT_FLOOD_INVERT false // Set "true" if the on/off function is reversed
|
||||
#endif
|
||||
|
||||
// @section filament width
|
||||
|
||||
/**
|
||||
* Filament Width Sensor
|
||||
*
|
||||
@ -3579,6 +3615,8 @@
|
||||
//#define FILAMENT_LCD_DISPLAY
|
||||
#endif
|
||||
|
||||
// @section power
|
||||
|
||||
/**
|
||||
* Power Monitor
|
||||
* Monitor voltage (V) and/or current (A), and -when possible- power (W)
|
||||
@ -3602,6 +3640,8 @@
|
||||
#define POWER_MONITOR_VOLTAGE_OFFSET 0 // Offset (in volts) applied to the calculated voltage
|
||||
#endif
|
||||
|
||||
// @section safety
|
||||
|
||||
/**
|
||||
* Stepper Driver Anti-SNAFU Protection
|
||||
*
|
||||
@ -3611,6 +3651,8 @@
|
||||
*/
|
||||
//#define DISABLE_DRIVER_SAFE_POWER_PROTECT
|
||||
|
||||
// @section cnc
|
||||
|
||||
/**
|
||||
* CNC Coordinate Systems
|
||||
*
|
||||
@ -3619,6 +3661,8 @@
|
||||
*/
|
||||
//#define CNC_COORDINATE_SYSTEMS
|
||||
|
||||
// @section reporting
|
||||
|
||||
/**
|
||||
* Auto-report fan speed with M123 S<seconds>
|
||||
* Requires fans with tachometer pins
|
||||
@ -3646,6 +3690,8 @@
|
||||
//#define M115_GEOMETRY_REPORT
|
||||
#endif
|
||||
|
||||
// @section security
|
||||
|
||||
/**
|
||||
* Expected Printer Check
|
||||
* Add the M16 G-code to compare a string to the MACHINE_NAME.
|
||||
@ -3653,6 +3699,8 @@
|
||||
*/
|
||||
//#define EXPECTED_PRINTER_CHECK
|
||||
|
||||
// @section volumetrics
|
||||
|
||||
/**
|
||||
* Disable all Volumetric extrusion options
|
||||
*/
|
||||
@ -3681,14 +3729,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Enable this option for a leaner build of Marlin that removes all
|
||||
* workspace offsets, simplifying coordinate transformations, leveling, etc.
|
||||
*
|
||||
* - M206 and M428 are disabled.
|
||||
* - G92 will revert to its behavior from Marlin 1.0.
|
||||
*/
|
||||
//#define NO_WORKSPACE_OFFSETS
|
||||
// @section reporting
|
||||
|
||||
// Extra options for the M114 "Current Position" report
|
||||
//#define M114_DETAIL // Use 'M114` for details to check planner calculations
|
||||
@ -3697,6 +3738,8 @@
|
||||
|
||||
//#define REPORT_FAN_CHANGE // Report the new fan speed when changed by M106 (and others)
|
||||
|
||||
// @section gcode
|
||||
|
||||
/**
|
||||
* Spend 28 bytes of SRAM to optimize the G-code parser
|
||||
*/
|
||||
@ -3714,6 +3757,15 @@
|
||||
|
||||
//#define REPETIER_GCODE_M360 // Add commands originally from Repetier FW
|
||||
|
||||
/**
|
||||
* Enable this option for a leaner build of Marlin that removes all
|
||||
* workspace offsets, simplifying coordinate transformations, leveling, etc.
|
||||
*
|
||||
* - M206 and M428 are disabled.
|
||||
* - G92 will revert to its behavior from Marlin 1.0.
|
||||
*/
|
||||
//#define NO_WORKSPACE_OFFSETS
|
||||
|
||||
/**
|
||||
* CNC G-code options
|
||||
* Support CNC-style G-code dialects used by laser cutters, drawing machine cams, etc.
|
||||
@ -3729,6 +3781,8 @@
|
||||
//#define VARIABLE_G0_FEEDRATE // The G0 feedrate is set by F in G0 motion mode
|
||||
#endif
|
||||
|
||||
// @section gcode
|
||||
|
||||
/**
|
||||
* Startup commands
|
||||
*
|
||||
@ -3753,6 +3807,8 @@
|
||||
* Up to 25 may be defined, but the actual number is LCD-dependent.
|
||||
*/
|
||||
|
||||
// @section custom main menu
|
||||
|
||||
// Custom Menu: Main Menu
|
||||
//#define CUSTOM_MENU_MAIN
|
||||
#if ENABLED(CUSTOM_MENU_MAIN)
|
||||
@ -3783,6 +3839,8 @@
|
||||
//#define MAIN_MENU_ITEM_5_CONFIRM
|
||||
#endif
|
||||
|
||||
// @section custom config menu
|
||||
|
||||
// Custom Menu: Configuration Menu
|
||||
//#define CUSTOM_MENU_CONFIG
|
||||
#if ENABLED(CUSTOM_MENU_CONFIG)
|
||||
@ -3813,6 +3871,8 @@
|
||||
//#define CONFIG_MENU_ITEM_5_CONFIRM
|
||||
#endif
|
||||
|
||||
// @section custom buttons
|
||||
|
||||
/**
|
||||
* User-defined buttons to run custom G-code.
|
||||
* Up to 25 may be defined.
|
||||
@ -3844,6 +3904,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// @section host
|
||||
|
||||
/**
|
||||
* Host Action Commands
|
||||
*
|
||||
@ -3869,6 +3931,8 @@
|
||||
//#define HOST_SHUTDOWN_MENU_ITEM // Add a menu item that tells the host to shut down
|
||||
#endif
|
||||
|
||||
// @section extras
|
||||
|
||||
/**
|
||||
* Cancel Objects
|
||||
*
|
||||
@ -3890,6 +3954,7 @@
|
||||
* Alternative Supplier: https://reliabuild3d.com/
|
||||
*
|
||||
* Reliabuild encoders have been modified to improve reliability.
|
||||
* @section i2c encoders
|
||||
*/
|
||||
|
||||
//#define I2C_POSITION_ENCODERS
|
||||
@ -3961,6 +4026,7 @@
|
||||
|
||||
/**
|
||||
* Analog Joystick(s)
|
||||
* @section joystick
|
||||
*/
|
||||
//#define JOYSTICK
|
||||
#if ENABLED(JOYSTICK)
|
||||
@ -3985,6 +4051,7 @@
|
||||
* Modern replacement for the Prusa TMC_Z_CALIBRATION.
|
||||
* Adds capability to work with any adjustable current drivers.
|
||||
* Implemented as G34 because M915 is deprecated.
|
||||
* @section calibrate
|
||||
*/
|
||||
//#define MECHANICAL_GANTRY_CALIBRATION
|
||||
#if ENABLED(MECHANICAL_GANTRY_CALIBRATION)
|
||||
@ -4002,6 +4069,7 @@
|
||||
/**
|
||||
* Instant freeze / unfreeze functionality
|
||||
* Potentially useful for emergency stop that allows being resumed.
|
||||
* @section interface
|
||||
*/
|
||||
//#define FREEZE_FEATURE
|
||||
#if ENABLED(FREEZE_FEATURE)
|
||||
@ -4014,6 +4082,7 @@
|
||||
*
|
||||
* Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip as a realtime status display.
|
||||
* Requires 3 signal wires. Some useful debug options are included to demonstrate its usage.
|
||||
* @section debug matrix
|
||||
*/
|
||||
//#define MAX7219_DEBUG
|
||||
#if ENABLED(MAX7219_DEBUG)
|
||||
@ -4052,6 +4121,7 @@
|
||||
* 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.
|
||||
* @section nanodlp
|
||||
*/
|
||||
//#define NANODLP_Z_SYNC
|
||||
#if ENABLED(NANODLP_Z_SYNC)
|
||||
@ -4060,6 +4130,7 @@
|
||||
|
||||
/**
|
||||
* Ethernet. Use M552 to enable and set the IP address.
|
||||
* @section network
|
||||
*/
|
||||
#if HAS_ETHERNET
|
||||
#define MAC_ADDRESS { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D } // A MAC address unique to your network
|
||||
@ -4087,6 +4158,8 @@
|
||||
//#include "Configuration_Secure.h" // External file with WiFi SSID / Password
|
||||
#endif
|
||||
|
||||
// @section multi-material
|
||||
|
||||
/**
|
||||
* Průša Multi-Material Unit (MMU)
|
||||
* Enable in Configuration.h
|
||||
@ -4192,6 +4265,7 @@
|
||||
|
||||
/**
|
||||
* Advanced Print Counter settings
|
||||
* @section stats
|
||||
*/
|
||||
#if ENABLED(PRINTCOUNTER)
|
||||
#define SERVICE_WARNING_BUZZES 3
|
||||
|
211
Marlin/config.ini
Normal file
211
Marlin/config.ini
Normal file
@ -0,0 +1,211 @@
|
||||
#
|
||||
# Marlin Firmware
|
||||
# config.ini - Options to apply before the build
|
||||
#
|
||||
[config:base]
|
||||
ini_use_config = none
|
||||
|
||||
# Load all config: sections in this file
|
||||
;ini_use_config = all
|
||||
# Load config file relative to Marlin/
|
||||
;ini_use_config = another.ini
|
||||
# Download configurations from GitHub
|
||||
;ini_use_config = example/Creality/Ender-5 Plus @ bugfix-2.1.x
|
||||
# Download configurations from your server
|
||||
;ini_use_config = https://me.myserver.com/path/to/configs
|
||||
# Evaluate config:base and do a config dump
|
||||
;ini_use_config = base
|
||||
;config_export = 2
|
||||
|
||||
[config:minimal]
|
||||
motherboard = BOARD_RAMPS_14_EFB
|
||||
serial_port = 0
|
||||
baudrate = 250000
|
||||
|
||||
use_watchdog = on
|
||||
thermal_protection_hotends = on
|
||||
thermal_protection_hysteresis = 4
|
||||
thermal_protection_period = 40
|
||||
|
||||
bufsize = 4
|
||||
block_buffer_size = 16
|
||||
max_cmd_size = 96
|
||||
|
||||
extruders = 1
|
||||
temp_sensor_0 = 1
|
||||
|
||||
temp_hysteresis = 3
|
||||
heater_0_mintemp = 5
|
||||
heater_0_maxtemp = 275
|
||||
preheat_1_temp_hotend = 180
|
||||
|
||||
bang_max = 255
|
||||
pidtemp = on
|
||||
pid_k1 = 0.95
|
||||
pid_max = BANG_MAX
|
||||
pid_functional_range = 10
|
||||
|
||||
default_kp = 22.20
|
||||
default_ki = 1.08
|
||||
default_kd = 114.00
|
||||
|
||||
x_driver_type = A4988
|
||||
y_driver_type = A4988
|
||||
z_driver_type = A4988
|
||||
e0_driver_type = A4988
|
||||
|
||||
x_bed_size = 200
|
||||
x_min_pos = 0
|
||||
x_max_pos = X_BED_SIZE
|
||||
|
||||
y_bed_size = 200
|
||||
y_min_pos = 0
|
||||
y_max_pos = Y_BED_SIZE
|
||||
|
||||
z_min_pos = 0
|
||||
z_max_pos = 200
|
||||
|
||||
x_home_dir = -1
|
||||
y_home_dir = -1
|
||||
z_home_dir = -1
|
||||
|
||||
use_xmin_plug = on
|
||||
use_ymin_plug = on
|
||||
use_zmin_plug = on
|
||||
|
||||
x_min_endstop_inverting = false
|
||||
y_min_endstop_inverting = false
|
||||
z_min_endstop_inverting = false
|
||||
|
||||
default_axis_steps_per_unit = { 80, 80, 400, 500 }
|
||||
axis_relative_modes = { false, false, false, false }
|
||||
default_max_feedrate = { 300, 300, 5, 25 }
|
||||
default_max_acceleration = { 3000, 3000, 100, 10000 }
|
||||
|
||||
homing_feedrate_mm_m = { (50*60), (50*60), (4*60) }
|
||||
homing_bump_divisor = { 2, 2, 4 }
|
||||
|
||||
x_enable_on = 0
|
||||
y_enable_on = 0
|
||||
z_enable_on = 0
|
||||
e_enable_on = 0
|
||||
|
||||
invert_x_dir = false
|
||||
invert_y_dir = true
|
||||
invert_z_dir = false
|
||||
invert_e0_dir = false
|
||||
|
||||
invert_e_step_pin = false
|
||||
invert_x_step_pin = false
|
||||
invert_y_step_pin = false
|
||||
invert_z_step_pin = false
|
||||
|
||||
disable_x = false
|
||||
disable_y = false
|
||||
disable_z = false
|
||||
disable_e = false
|
||||
|
||||
proportional_font_ratio = 1.0
|
||||
default_nominal_filament_dia = 1.75
|
||||
|
||||
junction_deviation_mm = 0.013
|
||||
|
||||
default_acceleration = 3000
|
||||
default_travel_acceleration = 3000
|
||||
default_retract_acceleration = 3000
|
||||
|
||||
default_minimumfeedrate = 0.0
|
||||
default_mintravelfeedrate = 0.0
|
||||
|
||||
minimum_planner_speed = 0.05
|
||||
min_steps_per_segment = 6
|
||||
default_minsegmenttime = 20000
|
||||
|
||||
[config:basic]
|
||||
bed_overshoot = 10
|
||||
busy_while_heating = on
|
||||
default_ejerk = 5.0
|
||||
default_keepalive_interval = 2
|
||||
default_leveling_fade_height = 0.0
|
||||
disable_inactive_extruder = on
|
||||
display_charset_hd44780 = JAPANESE
|
||||
eeprom_boot_silent = on
|
||||
eeprom_chitchat = on
|
||||
endstoppullups = on
|
||||
extrude_maxlength = 200
|
||||
extrude_mintemp = 170
|
||||
host_keepalive_feature = on
|
||||
hotend_overshoot = 15
|
||||
jd_handle_small_segments = on
|
||||
lcd_info_screen_style = 0
|
||||
lcd_language = en
|
||||
max_bed_power = 255
|
||||
mesh_inset = 0
|
||||
min_software_endstops = on
|
||||
max_software_endstops = on
|
||||
min_software_endstop_x = on
|
||||
min_software_endstop_y = on
|
||||
min_software_endstop_z = on
|
||||
max_software_endstop_x = on
|
||||
max_software_endstop_y = on
|
||||
max_software_endstop_z = on
|
||||
preheat_1_fan_speed = 0
|
||||
preheat_1_label = "PLA"
|
||||
preheat_1_temp_bed = 70
|
||||
prevent_cold_extrusion = on
|
||||
prevent_lengthy_extrude = on
|
||||
printjob_timer_autostart = on
|
||||
probing_margin = 10
|
||||
show_bootscreen = on
|
||||
soft_pwm_scale = 0
|
||||
string_config_h_author = "(none, default config)"
|
||||
temp_bed_hysteresis = 3
|
||||
temp_bed_residency_time = 10
|
||||
temp_bed_window = 1
|
||||
temp_residency_time = 10
|
||||
temp_window = 1
|
||||
validate_homing_endstops = on
|
||||
xy_probe_feedrate = (133*60)
|
||||
z_clearance_between_probes = 5
|
||||
z_clearance_deploy_probe = 10
|
||||
z_clearance_multi_probe = 5
|
||||
|
||||
[config:advanced]
|
||||
arc_support = on
|
||||
auto_report_temperatures = on
|
||||
autotemp = on
|
||||
autotemp_oldweight = 0.98
|
||||
bed_check_interval = 5000
|
||||
default_stepper_deactive_time = 120
|
||||
default_volumetric_extruder_limit = 0.00
|
||||
disable_inactive_e = true
|
||||
disable_inactive_x = true
|
||||
disable_inactive_y = true
|
||||
disable_inactive_z = true
|
||||
e0_auto_fan_pin = -1
|
||||
encoder_100x_steps_per_sec = 80
|
||||
encoder_10x_steps_per_sec = 30
|
||||
encoder_rate_multiplier = on
|
||||
extended_capabilities_report = on
|
||||
extruder_auto_fan_speed = 255
|
||||
extruder_auto_fan_temperature = 50
|
||||
fanmux0_pin = -1
|
||||
fanmux1_pin = -1
|
||||
fanmux2_pin = -1
|
||||
faster_gcode_parser = on
|
||||
homing_bump_mm = { 5, 5, 2 }
|
||||
max_arc_segment_mm = 1.0
|
||||
min_arc_segment_mm = 0.1
|
||||
min_circle_segments = 72
|
||||
n_arc_correction = 25
|
||||
serial_overrun_protection = on
|
||||
slowdown = on
|
||||
slowdown_divisor = 2
|
||||
temp_sensor_bed = 0
|
||||
thermal_protection_bed_hysteresis = 2
|
||||
thermocouple_max_errors = 15
|
||||
tx_buffer_size = 0
|
||||
watch_bed_temp_increase = 2
|
||||
watch_bed_temp_period = 60
|
||||
watch_temp_increase = 2
|
||||
watch_temp_period = 20
|
@ -1220,10 +1220,10 @@ void setup() {
|
||||
SETUP_RUN(hal.init());
|
||||
|
||||
// Init and disable SPI thermocouples; this is still needed
|
||||
#if TEMP_SENSOR_0_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E0))
|
||||
#if TEMP_SENSOR_IS_MAX_TC(0) || (TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E0))
|
||||
OUT_WRITE(TEMP_0_CS_PIN, HIGH); // Disable
|
||||
#endif
|
||||
#if TEMP_SENSOR_1_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E1))
|
||||
#if TEMP_SENSOR_IS_MAX_TC(1) || (TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E1))
|
||||
OUT_WRITE(TEMP_1_CS_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
|
@ -730,3 +730,8 @@
|
||||
#define __MAPLIST() _MAPLIST
|
||||
|
||||
#define MAPLIST(OP,V...) EVAL(_MAPLIST(OP,V))
|
||||
|
||||
// Temperature Sensor Config
|
||||
#define _HAS_E_TEMP(N) || (TEMP_SENSOR_##N != 0)
|
||||
#define HAS_E_TEMP_SENSOR (0 REPEAT(EXTRUDERS, _HAS_E_TEMP))
|
||||
#define TEMP_SENSOR_IS_MAX_TC(T) (TEMP_SENSOR_##T == -5 || TEMP_SENSOR_##T == -3 || TEMP_SENSOR_##T == -2)
|
||||
|
@ -48,7 +48,7 @@
|
||||
|
||||
void GcodeSuite::M303() {
|
||||
|
||||
#if ANY(PID_DEBUG, PID_BED_DEBUG, PID_CHAMBER_DEBUG)
|
||||
#if HAS_PID_DEBUG
|
||||
if (parser.seen_test('D')) {
|
||||
thermalManager.pid_debug_flag ^= true;
|
||||
SERIAL_ECHO_START();
|
||||
|
@ -668,6 +668,31 @@
|
||||
#define E_MANUAL EXTRUDERS
|
||||
#endif
|
||||
|
||||
#if E_STEPPERS <= 7
|
||||
#undef INVERT_E7_DIR
|
||||
#if E_STEPPERS <= 6
|
||||
#undef INVERT_E6_DIR
|
||||
#if E_STEPPERS <= 5
|
||||
#undef INVERT_E5_DIR
|
||||
#if E_STEPPERS <= 4
|
||||
#undef INVERT_E4_DIR
|
||||
#if E_STEPPERS <= 3
|
||||
#undef INVERT_E3_DIR
|
||||
#if E_STEPPERS <= 2
|
||||
#undef INVERT_E2_DIR
|
||||
#if E_STEPPERS <= 1
|
||||
#undef INVERT_E1_DIR
|
||||
#if E_STEPPERS == 0
|
||||
#undef INVERT_E0_DIR
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Number of Linear Axes (e.g., XYZIJKUVW)
|
||||
* All the logical axes except for the tool (E) axis
|
||||
@ -768,6 +793,9 @@
|
||||
#undef Y_MIN_POS
|
||||
#undef Y_MAX_POS
|
||||
#undef MANUAL_Y_HOME_POS
|
||||
#undef MIN_SOFTWARE_ENDSTOP_Y
|
||||
#undef MAX_SOFTWARE_ENDSTOP_Y
|
||||
#undef SAFE_BED_LEVELING_START_Y
|
||||
#endif
|
||||
|
||||
#if !HAS_Z_AXIS
|
||||
@ -785,6 +813,9 @@
|
||||
#undef Z_MIN_POS
|
||||
#undef Z_MAX_POS
|
||||
#undef MANUAL_Z_HOME_POS
|
||||
#undef MIN_SOFTWARE_ENDSTOP_Z
|
||||
#undef MAX_SOFTWARE_ENDSTOP_Z
|
||||
#undef SAFE_BED_LEVELING_START_Z
|
||||
#endif
|
||||
|
||||
#if !HAS_I_AXIS
|
||||
@ -799,6 +830,9 @@
|
||||
#undef I_MIN_POS
|
||||
#undef I_MAX_POS
|
||||
#undef MANUAL_I_HOME_POS
|
||||
#undef MIN_SOFTWARE_ENDSTOP_I
|
||||
#undef MAX_SOFTWARE_ENDSTOP_I
|
||||
#undef SAFE_BED_LEVELING_START_I
|
||||
#endif
|
||||
|
||||
#if !HAS_J_AXIS
|
||||
@ -813,6 +847,9 @@
|
||||
#undef J_MIN_POS
|
||||
#undef J_MAX_POS
|
||||
#undef MANUAL_J_HOME_POS
|
||||
#undef MIN_SOFTWARE_ENDSTOP_J
|
||||
#undef MAX_SOFTWARE_ENDSTOP_J
|
||||
#undef SAFE_BED_LEVELING_START_J
|
||||
#endif
|
||||
|
||||
#if !HAS_K_AXIS
|
||||
@ -827,6 +864,9 @@
|
||||
#undef K_MIN_POS
|
||||
#undef K_MAX_POS
|
||||
#undef MANUAL_K_HOME_POS
|
||||
#undef MIN_SOFTWARE_ENDSTOP_K
|
||||
#undef MAX_SOFTWARE_ENDSTOP_K
|
||||
#undef SAFE_BED_LEVELING_START_K
|
||||
#endif
|
||||
|
||||
#if !HAS_U_AXIS
|
||||
@ -841,6 +881,9 @@
|
||||
#undef U_MIN_POS
|
||||
#undef U_MAX_POS
|
||||
#undef MANUAL_U_HOME_POS
|
||||
#undef MIN_SOFTWARE_ENDSTOP_U
|
||||
#undef MAX_SOFTWARE_ENDSTOP_U
|
||||
#undef SAFE_BED_LEVELING_START_U
|
||||
#endif
|
||||
|
||||
#if !HAS_V_AXIS
|
||||
@ -855,6 +898,9 @@
|
||||
#undef V_MIN_POS
|
||||
#undef V_MAX_POS
|
||||
#undef MANUAL_V_HOME_POS
|
||||
#undef MIN_SOFTWARE_ENDSTOP_V
|
||||
#undef MAX_SOFTWARE_ENDSTOP_V
|
||||
#undef SAFE_BED_LEVELING_START_V
|
||||
#endif
|
||||
|
||||
#if !HAS_W_AXIS
|
||||
@ -869,6 +915,9 @@
|
||||
#undef W_MIN_POS
|
||||
#undef W_MAX_POS
|
||||
#undef MANUAL_W_HOME_POS
|
||||
#undef MIN_SOFTWARE_ENDSTOP_W
|
||||
#undef MAX_SOFTWARE_ENDSTOP_W
|
||||
#undef SAFE_BED_LEVELING_START_W
|
||||
#endif
|
||||
|
||||
#ifdef X2_DRIVER_TYPE
|
||||
@ -1398,6 +1447,10 @@
|
||||
#define EXTRUDE_MINTEMP 170
|
||||
#endif
|
||||
|
||||
#if ANY(PID_DEBUG, PID_BED_DEBUG, PID_CHAMBER_DEBUG)
|
||||
#define HAS_PID_DEBUG 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* TFT Displays
|
||||
*
|
||||
|
@ -116,6 +116,31 @@
|
||||
#undef STEALTHCHOP_E
|
||||
#endif
|
||||
|
||||
#if HOTENDS <= 7
|
||||
#undef E7_AUTO_FAN_PIN
|
||||
#if HOTENDS <= 6
|
||||
#undef E6_AUTO_FAN_PIN
|
||||
#if HOTENDS <= 5
|
||||
#undef E5_AUTO_FAN_PIN
|
||||
#if HOTENDS <= 4
|
||||
#undef E4_AUTO_FAN_PIN
|
||||
#if HOTENDS <= 3
|
||||
#undef E3_AUTO_FAN_PIN
|
||||
#if HOTENDS <= 2
|
||||
#undef E2_AUTO_FAN_PIN
|
||||
#if HOTENDS <= 1
|
||||
#undef E1_AUTO_FAN_PIN
|
||||
#if HOTENDS == 0
|
||||
#undef E0_AUTO_FAN_PIN
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Temperature Sensors; define what sensor(s) we have.
|
||||
*/
|
||||
@ -154,8 +179,7 @@
|
||||
#define REDUNDANT_TEMP_MATCH(...) 0
|
||||
#endif
|
||||
|
||||
#if TEMP_SENSOR_0 == -5 || TEMP_SENSOR_0 == -3 || TEMP_SENSOR_0 == -2
|
||||
#define TEMP_SENSOR_0_IS_MAX_TC 1
|
||||
#if TEMP_SENSOR_IS_MAX_TC(0)
|
||||
#if TEMP_SENSOR_0 == -5
|
||||
#define TEMP_SENSOR_0_IS_MAX31865 1
|
||||
#define TEMP_SENSOR_0_MAX_TC_TMIN 0
|
||||
@ -191,8 +215,7 @@
|
||||
#undef HEATER_0_MAXTEMP
|
||||
#endif
|
||||
|
||||
#if TEMP_SENSOR_1 == -5 || TEMP_SENSOR_1 == -3 || TEMP_SENSOR_1 == -2
|
||||
#define TEMP_SENSOR_1_IS_MAX_TC 1
|
||||
#if TEMP_SENSOR_IS_MAX_TC(1)
|
||||
#if TEMP_SENSOR_1 == -5
|
||||
#define TEMP_SENSOR_1_IS_MAX31865 1
|
||||
#define TEMP_SENSOR_1_MAX_TC_TMIN 0
|
||||
@ -238,9 +261,7 @@
|
||||
#undef HEATER_1_MAXTEMP
|
||||
#endif
|
||||
|
||||
#if TEMP_SENSOR_REDUNDANT == -5 || TEMP_SENSOR_REDUNDANT == -3 || TEMP_SENSOR_REDUNDANT == -2
|
||||
#define TEMP_SENSOR_REDUNDANT_IS_MAX_TC 1
|
||||
|
||||
#if TEMP_SENSOR_IS_MAX_TC(REDUNDANT)
|
||||
#if TEMP_SENSOR_REDUNDANT == -5
|
||||
#if !REDUNDANT_TEMP_MATCH(SOURCE, E0) && !REDUNDANT_TEMP_MATCH(SOURCE, E1)
|
||||
#error "MAX31865 Thermocouples (-5) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1 (0/1)."
|
||||
@ -282,7 +303,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (TEMP_SENSOR_0_IS_MAX_TC && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_0) || (TEMP_SENSOR_1_IS_MAX_TC && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_1)
|
||||
#if (TEMP_SENSOR_IS_MAX_TC(0) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_0) || (TEMP_SENSOR_IS_MAX_TC(1) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_1)
|
||||
#if TEMP_SENSOR_REDUNDANT == -5
|
||||
#error "If MAX31865 Thermocouple (-5) is used for TEMP_SENSOR_0/TEMP_SENSOR_1 then TEMP_SENSOR_REDUNDANT must match."
|
||||
#elif TEMP_SENSOR_REDUNDANT == -3
|
||||
@ -304,7 +325,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if TEMP_SENSOR_0_IS_MAX_TC || TEMP_SENSOR_1_IS_MAX_TC || TEMP_SENSOR_REDUNDANT_IS_MAX_TC
|
||||
#if TEMP_SENSOR_IS_MAX_TC(0) || TEMP_SENSOR_IS_MAX_TC(1) || TEMP_SENSOR_IS_MAX_TC(REDUNDANT)
|
||||
#define HAS_MAX_TC 1
|
||||
#endif
|
||||
#if TEMP_SENSOR_0_IS_MAX6675 || TEMP_SENSOR_1_IS_MAX6675 || TEMP_SENSOR_REDUNDANT_IS_MAX6675
|
||||
|
@ -681,7 +681,7 @@
|
||||
#if HAS_MAX_TC
|
||||
|
||||
// Translate old _SS, _CS, _SCK, _DO, _DI, _MISO, and _MOSI PIN defines.
|
||||
#if TEMP_SENSOR_0_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E1))
|
||||
#if TEMP_SENSOR_IS_MAX_TC(0) || (TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E1))
|
||||
|
||||
#if !PIN_EXISTS(TEMP_0_CS) // SS, CS
|
||||
#if PIN_EXISTS(MAX6675_SS)
|
||||
@ -748,9 +748,9 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // TEMP_SENSOR_0_IS_MAX_TC
|
||||
#endif // TEMP_SENSOR_IS_MAX_TC(0)
|
||||
|
||||
#if TEMP_SENSOR_1_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E1))
|
||||
#if TEMP_SENSOR_IS_MAX_TC(1) || (TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E1))
|
||||
|
||||
#if !PIN_EXISTS(TEMP_1_CS) // SS2, CS2
|
||||
#if PIN_EXISTS(MAX6675_SS2)
|
||||
@ -817,7 +817,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // TEMP_SENSOR_1_IS_MAX_TC
|
||||
#endif // TEMP_SENSOR_IS_MAX_TC(1)
|
||||
|
||||
//
|
||||
// User-defined thermocouple libraries
|
||||
@ -2656,7 +2656,7 @@
|
||||
//
|
||||
// ADC Temp Sensors (Thermistor or Thermocouple with amplifier ADC interface)
|
||||
//
|
||||
#define HAS_ADC_TEST(P) (PIN_EXISTS(TEMP_##P) && TEMP_SENSOR_##P != 0 && NONE(TEMP_SENSOR_##P##_IS_MAX_TC, TEMP_SENSOR_##P##_IS_DUMMY))
|
||||
#define HAS_ADC_TEST(P) (PIN_EXISTS(TEMP_##P) && TEMP_SENSOR_##P != 0 && !TEMP_SENSOR_IS_MAX_TC(P) && !TEMP_SENSOR_##P##_IS_DUMMY)
|
||||
#if HOTENDS > 0 && HAS_ADC_TEST(0)
|
||||
#define HAS_TEMP_ADC_0 1
|
||||
#endif
|
||||
@ -2700,7 +2700,7 @@
|
||||
#define HAS_TEMP_ADC_REDUNDANT 1
|
||||
#endif
|
||||
|
||||
#define HAS_TEMP(N) ANY(HAS_TEMP_ADC_##N, TEMP_SENSOR_##N##_IS_MAX_TC, TEMP_SENSOR_##N##_IS_DUMMY)
|
||||
#define HAS_TEMP(N) (TEMP_SENSOR_IS_MAX_TC(N) || EITHER(HAS_TEMP_ADC_##N, TEMP_SENSOR_##N##_IS_DUMMY))
|
||||
#if HAS_HOTEND && HAS_TEMP(0)
|
||||
#define HAS_TEMP_HOTEND 1
|
||||
#endif
|
||||
|
@ -2328,9 +2328,9 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
|
||||
#error "TEMP_SENSOR_REDUNDANT_TARGET can't be COOLER without TEMP_COOLER_PIN defined."
|
||||
#endif
|
||||
|
||||
#if TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E0) && !PIN_EXISTS(TEMP_0_CS)
|
||||
#if TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E0) && !PIN_EXISTS(TEMP_0_CS)
|
||||
#error "TEMP_SENSOR_REDUNDANT MAX Thermocouple with TEMP_SENSOR_REDUNDANT_SOURCE E0 requires TEMP_0_CS_PIN."
|
||||
#elif TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E1) && !PIN_EXISTS(TEMP_1_CS)
|
||||
#elif TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E1) && !PIN_EXISTS(TEMP_1_CS)
|
||||
#error "TEMP_SENSOR_REDUNDANT MAX Thermocouple with TEMP_SENSOR_REDUNDANT_SOURCE E1 requires TEMP_1_CS_PIN."
|
||||
#endif
|
||||
#endif
|
||||
@ -2343,7 +2343,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
|
||||
#error "TEMP_0_PIN or TEMP_0_CS_PIN not defined for this board."
|
||||
#elif HAS_EXTRUDERS && !HAS_HEATER_0
|
||||
#error "HEATER_0_PIN not defined for this board."
|
||||
#elif TEMP_SENSOR_0_IS_MAX_TC && !PIN_EXISTS(TEMP_0_CS)
|
||||
#elif TEMP_SENSOR_IS_MAX_TC(0) && !PIN_EXISTS(TEMP_0_CS)
|
||||
#error "TEMP_SENSOR_0 MAX thermocouple requires TEMP_0_CS_PIN."
|
||||
#elif HAS_HOTEND && !HAS_TEMP_HOTEND && !TEMP_SENSOR_0_IS_DUMMY
|
||||
#error "TEMP_0_PIN (required for TEMP_SENSOR_0) not defined for this board."
|
||||
@ -2352,7 +2352,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
|
||||
#endif
|
||||
|
||||
#if HAS_MULTI_HOTEND
|
||||
#if TEMP_SENSOR_1_IS_MAX_TC && !PIN_EXISTS(TEMP_1_CS)
|
||||
#if TEMP_SENSOR_IS_MAX_TC(1) && !PIN_EXISTS(TEMP_1_CS)
|
||||
#error "TEMP_SENSOR_1 MAX thermocouple requires TEMP_1_CS_PIN."
|
||||
#elif TEMP_SENSOR_1 == 0
|
||||
#error "TEMP_SENSOR_1 is required with 2 or more HOTENDS."
|
||||
|
@ -77,7 +77,7 @@
|
||||
|
||||
// MAX TC related macros
|
||||
#define TEMP_SENSOR_IS_MAX(n, M) (ENABLED(TEMP_SENSOR_##n##_IS_MAX##M) || (ENABLED(TEMP_SENSOR_REDUNDANT_IS_MAX##M) && REDUNDANT_TEMP_MATCH(SOURCE, E##n)))
|
||||
#define TEMP_SENSOR_IS_ANY_MAX_TC(n) (ENABLED(TEMP_SENSOR_##n##_IS_MAX_TC) || (ENABLED(TEMP_SENSOR_REDUNDANT_IS_MAX_TC) && REDUNDANT_TEMP_MATCH(SOURCE, E##n)))
|
||||
#define TEMP_SENSOR_IS_ANY_MAX_TC(n) (TEMP_SENSOR_IS_MAX_TC(n) || (TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E##n)))
|
||||
|
||||
// LIB_MAX6675 can be added to the build_flags in platformio.ini to use a user-defined library
|
||||
// If LIB_MAX6675 is not on the build_flags then raw SPI reads will be used.
|
||||
@ -1317,8 +1317,7 @@ void Temperature::min_temp_error(const heater_id_t heater_id) {
|
||||
_temp_error(heater_id, F(STR_T_MINTEMP), GET_TEXT_F(MSG_ERR_MINTEMP));
|
||||
}
|
||||
|
||||
#if ANY(PID_DEBUG, PID_BED_DEBUG, PID_CHAMBER_DEBUG)
|
||||
#define HAS_PID_DEBUG 1
|
||||
#if HAS_PID_DEBUG
|
||||
bool Temperature::pid_debug_flag; // = false
|
||||
#endif
|
||||
|
||||
@ -1856,15 +1855,15 @@ void Temperature::task() {
|
||||
if (!updateTemperaturesIfReady()) return; // Will also reset the watchdog if temperatures are ready
|
||||
|
||||
#if DISABLED(IGNORE_THERMOCOUPLE_ERRORS)
|
||||
#if TEMP_SENSOR_0_IS_MAX_TC
|
||||
#if TEMP_SENSOR_IS_MAX_TC(0)
|
||||
if (degHotend(0) > _MIN(HEATER_0_MAXTEMP, TEMP_SENSOR_0_MAX_TC_TMAX - 1.0)) max_temp_error(H_E0);
|
||||
if (degHotend(0) < _MAX(HEATER_0_MINTEMP, TEMP_SENSOR_0_MAX_TC_TMIN + .01)) min_temp_error(H_E0);
|
||||
#endif
|
||||
#if TEMP_SENSOR_1_IS_MAX_TC
|
||||
#if TEMP_SENSOR_IS_MAX_TC(1)
|
||||
if (degHotend(1) > _MIN(HEATER_1_MAXTEMP, TEMP_SENSOR_1_MAX_TC_TMAX - 1.0)) max_temp_error(H_E1);
|
||||
if (degHotend(1) < _MAX(HEATER_1_MINTEMP, TEMP_SENSOR_1_MAX_TC_TMIN + .01)) min_temp_error(H_E1);
|
||||
#endif
|
||||
#if TEMP_SENSOR_REDUNDANT_IS_MAX_TC
|
||||
#if TEMP_SENSOR_IS_MAX_TC(REDUNDANT)
|
||||
if (degRedundant() > TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX - 1.0) max_temp_error(H_REDUNDANT);
|
||||
if (degRedundant() < TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN + .01) min_temp_error(H_REDUNDANT);
|
||||
#endif
|
||||
@ -2072,7 +2071,7 @@ void Temperature::task() {
|
||||
case 0:
|
||||
#if TEMP_SENSOR_0_IS_CUSTOM
|
||||
return user_thermistor_to_deg_c(CTI_HOTEND_0, raw);
|
||||
#elif TEMP_SENSOR_0_IS_MAX_TC
|
||||
#elif TEMP_SENSOR_IS_MAX_TC(0)
|
||||
#if TEMP_SENSOR_0_IS_MAX31865
|
||||
return TERN(LIB_INTERNAL_MAX31865,
|
||||
max31865_0.temperature(raw),
|
||||
@ -2091,7 +2090,7 @@ void Temperature::task() {
|
||||
case 1:
|
||||
#if TEMP_SENSOR_1_IS_CUSTOM
|
||||
return user_thermistor_to_deg_c(CTI_HOTEND_1, raw);
|
||||
#elif TEMP_SENSOR_1_IS_MAX_TC
|
||||
#elif TEMP_SENSOR_IS_MAX_TC(1)
|
||||
#if TEMP_SENSOR_0_IS_MAX31865
|
||||
return TERN(LIB_INTERNAL_MAX31865,
|
||||
max31865_1.temperature(raw),
|
||||
@ -2275,9 +2274,9 @@ void Temperature::task() {
|
||||
celsius_float_t Temperature::analog_to_celsius_redundant(const raw_adc_t raw) {
|
||||
#if TEMP_SENSOR_REDUNDANT_IS_CUSTOM
|
||||
return user_thermistor_to_deg_c(CTI_REDUNDANT, raw);
|
||||
#elif TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E0)
|
||||
#elif TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E0)
|
||||
return TERN(TEMP_SENSOR_REDUNDANT_IS_MAX31865, max31865_0.temperature(raw), (int16_t)raw * 0.25);
|
||||
#elif TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E1)
|
||||
#elif TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E1)
|
||||
return TERN(TEMP_SENSOR_REDUNDANT_IS_MAX31865, max31865_1.temperature(raw), (int16_t)raw * 0.25);
|
||||
#elif TEMP_SENSOR_REDUNDANT_IS_THERMISTOR
|
||||
SCAN_THERMISTOR_TABLE(TEMPTABLE_REDUNDANT, TEMPTABLE_REDUNDANT_LEN);
|
||||
@ -2308,9 +2307,15 @@ void Temperature::updateTemperaturesFromRawValues() {
|
||||
|
||||
hal.watchdog_refresh(); // Reset because raw_temps_ready was set by the interrupt
|
||||
|
||||
TERN_(TEMP_SENSOR_0_IS_MAX_TC, temp_hotend[0].setraw(READ_MAX_TC(0)));
|
||||
TERN_(TEMP_SENSOR_1_IS_MAX_TC, temp_hotend[1].setraw(READ_MAX_TC(1)));
|
||||
TERN_(TEMP_SENSOR_REDUNDANT_IS_MAX_TC, temp_redundant.setraw(READ_MAX_TC(HEATER_ID(TEMP_SENSOR_REDUNDANT_SOURCE))));
|
||||
#if TEMP_SENSOR_IS_MAX_TC(0)
|
||||
temp_hotend[0].setraw(READ_MAX_TC(0));
|
||||
#endif
|
||||
#if TEMP_SENSOR_IS_MAX_TC(1)
|
||||
temp_hotend[1].setraw(READ_MAX_TC(1));
|
||||
#endif
|
||||
#if TEMP_SENSOR_IS_MAX_TC(REDUNDANT)
|
||||
temp_redundant.setraw(READ_MAX_TC(HEATER_ID(TEMP_SENSOR_REDUNDANT_SOURCE)));
|
||||
#endif
|
||||
|
||||
#if HAS_HOTEND
|
||||
HOTEND_LOOP() temp_hotend[e].celsius = analog_to_celsius_hotend(temp_hotend[e].getraw(), e);
|
||||
@ -3139,15 +3144,15 @@ void Temperature::disable_all_heaters() {
|
||||
void Temperature::update_raw_temperatures() {
|
||||
|
||||
// TODO: can this be collapsed into a HOTEND_LOOP()?
|
||||
#if HAS_TEMP_ADC_0 && !TEMP_SENSOR_0_IS_MAX_TC
|
||||
#if HAS_TEMP_ADC_0 && !TEMP_SENSOR_IS_MAX_TC(0)
|
||||
temp_hotend[0].update();
|
||||
#endif
|
||||
|
||||
#if HAS_TEMP_ADC_1 && !TEMP_SENSOR_1_IS_MAX_TC
|
||||
#if HAS_TEMP_ADC_1 && !TEMP_SENSOR_IS_MAX_TC(1)
|
||||
temp_hotend[1].update();
|
||||
#endif
|
||||
|
||||
#if HAS_TEMP_ADC_REDUNDANT && !TEMP_SENSOR_REDUNDANT_IS_MAX_TC
|
||||
#if HAS_TEMP_ADC_REDUNDANT && !TEMP_SENSOR_IS_MAX_TC(REDUNDANT)
|
||||
temp_redundant.update();
|
||||
#endif
|
||||
|
||||
|
@ -953,7 +953,7 @@ class Temperature {
|
||||
*/
|
||||
#if HAS_PID_HEATING
|
||||
|
||||
#if ANY(PID_DEBUG, PID_BED_DEBUG, PID_CHAMBER_DEBUG)
|
||||
#if HAS_PID_DEBUG
|
||||
static bool pid_debug_flag;
|
||||
#endif
|
||||
|
||||
@ -1035,7 +1035,7 @@ class Temperature {
|
||||
|
||||
// MAX Thermocouples
|
||||
#if HAS_MAX_TC
|
||||
#define MAX_TC_COUNT COUNT_ENABLED(TEMP_SENSOR_0_IS_MAX_TC, TEMP_SENSOR_1_IS_MAX_TC, TEMP_SENSOR_REDUNDANT_IS_MAX_TC)
|
||||
#define MAX_TC_COUNT TEMP_SENSOR_IS_MAX_TC(0) + TEMP_SENSOR_IS_MAX_TC(1) + TEMP_SENSOR_IS_MAX_TC(REDUNDANT)
|
||||
#if MAX_TC_COUNT > 1
|
||||
#define HAS_MULTI_MAX_TC 1
|
||||
#define READ_MAX_TC(N) read_max_tc(N)
|
||||
|
239
buildroot/share/PlatformIO/scripts/configuration.py
Normal file
239
buildroot/share/PlatformIO/scripts/configuration.py
Normal file
@ -0,0 +1,239 @@
|
||||
#
|
||||
# configuration.py
|
||||
# Apply options from config.ini to the existing Configuration headers
|
||||
#
|
||||
import re, shutil, configparser
|
||||
from pathlib import Path
|
||||
|
||||
verbose = 0
|
||||
def blab(str,level=1):
|
||||
if verbose >= level: print(f"[config] {str}")
|
||||
|
||||
def config_path(cpath):
|
||||
return Path("Marlin", cpath)
|
||||
|
||||
# Apply a single name = on/off ; name = value ; etc.
|
||||
# TODO: Limit to the given (optional) configuration
|
||||
def apply_opt(name, val, conf=None):
|
||||
if name == "lcd": name, val = val, "on"
|
||||
|
||||
# Create a regex to match the option and capture parts of the line
|
||||
regex = re.compile(rf'^(\s*)(//\s*)?(#define\s+)({name}\b)(\s*)(.*?)(\s*)(//.*)?$', re.IGNORECASE)
|
||||
|
||||
# Find and enable and/or update all matches
|
||||
for file in ("Configuration.h", "Configuration_adv.h"):
|
||||
fullpath = config_path(file)
|
||||
lines = fullpath.read_text().split('\n')
|
||||
found = False
|
||||
for i in range(len(lines)):
|
||||
line = lines[i]
|
||||
match = regex.match(line)
|
||||
if match and match[4].upper() == name.upper():
|
||||
found = True
|
||||
# For boolean options un/comment the define
|
||||
if val in ("on", "", None):
|
||||
newline = re.sub(r'^(\s*)//+\s*(#define)(\s{1,3})?(\s*)', r'\1\2 \4', line)
|
||||
elif val == "off":
|
||||
newline = re.sub(r'^(\s*)(#define)(\s{1,3})?(\s*)', r'\1//\2 \4', line)
|
||||
else:
|
||||
# For options with values, enable and set the value
|
||||
newline = match[1] + match[3] + match[4] + match[5] + val
|
||||
if match[8]:
|
||||
sp = match[7] if match[7] else ' '
|
||||
newline += sp + match[8]
|
||||
lines[i] = newline
|
||||
blab(f"Set {name} to {val}")
|
||||
|
||||
# If the option was found, write the modified lines
|
||||
if found:
|
||||
fullpath.write_text('\n'.join(lines))
|
||||
break
|
||||
|
||||
# If the option didn't appear in either config file, add it
|
||||
if not found:
|
||||
# OFF options are added as disabled items so they appear
|
||||
# in config dumps. Useful for custom settings.
|
||||
prefix = ""
|
||||
if val == "off":
|
||||
prefix, val = "//", "" # Item doesn't appear in config dump
|
||||
#val = "false" # Item appears in config dump
|
||||
|
||||
# Uppercase the option unless already mixed/uppercase
|
||||
added = name.upper() if name.islower() else name
|
||||
|
||||
# Add the provided value after the name
|
||||
if val != "on" and val != "" and val is not None:
|
||||
added += " " + val
|
||||
|
||||
# Prepend the new option after the first set of #define lines
|
||||
fullpath = config_path("Configuration.h")
|
||||
with fullpath.open() as f:
|
||||
lines = f.readlines()
|
||||
linenum = 0
|
||||
gotdef = False
|
||||
for line in lines:
|
||||
isdef = line.startswith("#define")
|
||||
if not gotdef:
|
||||
gotdef = isdef
|
||||
elif not isdef:
|
||||
break
|
||||
linenum += 1
|
||||
lines.insert(linenum, f"{prefix}#define {added} // Added by config.ini\n")
|
||||
fullpath.write_text('\n'.join(lines))
|
||||
|
||||
# Fetch configuration files from GitHub given the path.
|
||||
# Return True if any files were fetched.
|
||||
def fetch_example(path):
|
||||
if path.endswith("/"):
|
||||
path = path[:-1]
|
||||
|
||||
if '@' in path:
|
||||
path, brch = map(strip, path.split('@'))
|
||||
|
||||
url = path.replace("%", "%25").replace(" ", "%20")
|
||||
if not path.startswith('http'):
|
||||
url = "https://raw.githubusercontent.com/MarlinFirmware/Configurations/bugfix-2.1.x/config/%s" % url
|
||||
|
||||
# Find a suitable fetch command
|
||||
if shutil.which("curl") is not None:
|
||||
fetch = "curl -L -s -S -f -o"
|
||||
elif shutil.which("wget") is not None:
|
||||
fetch = "wget -q -O"
|
||||
else:
|
||||
blab("Couldn't find curl or wget", -1)
|
||||
return False
|
||||
|
||||
import os
|
||||
|
||||
# Reset configurations to default
|
||||
os.system("git reset --hard HEAD")
|
||||
|
||||
gotfile = False
|
||||
|
||||
# Try to fetch the remote files
|
||||
for fn in ("Configuration.h", "Configuration_adv.h", "_Bootscreen.h", "_Statusscreen.h"):
|
||||
if os.system("%s wgot %s/%s >/dev/null 2>&1" % (fetch, url, fn)) == 0:
|
||||
shutil.move('wgot', config_path(fn))
|
||||
gotfile = True
|
||||
|
||||
if Path('wgot').exists():
|
||||
shutil.rmtree('wgot')
|
||||
|
||||
return gotfile
|
||||
|
||||
def section_items(cp, sectkey):
|
||||
return cp.items(sectkey) if sectkey in cp.sections() else []
|
||||
|
||||
# Apply all items from a config section
|
||||
def apply_ini_by_name(cp, sect):
|
||||
iniok = True
|
||||
if sect in ('config:base', 'config:root'):
|
||||
iniok = False
|
||||
items = section_items(cp, 'config:base') + section_items(cp, 'config:root')
|
||||
else:
|
||||
items = cp.items(sect)
|
||||
|
||||
for item in items:
|
||||
if iniok or not item[0].startswith('ini_'):
|
||||
apply_opt(item[0], item[1])
|
||||
|
||||
# Apply all config sections from a parsed file
|
||||
def apply_all_sections(cp):
|
||||
for sect in cp.sections():
|
||||
if sect.startswith('config:'):
|
||||
apply_ini_by_name(cp, sect)
|
||||
|
||||
# Apply certain config sections from a parsed file
|
||||
def apply_sections(cp, ckey='all', addbase=False):
|
||||
blab("[config] apply section key: %s" % ckey)
|
||||
if ckey == 'all':
|
||||
apply_all_sections(cp)
|
||||
else:
|
||||
# Apply the base/root config.ini settings after external files are done
|
||||
if addbase or ckey in ('base', 'root'):
|
||||
apply_ini_by_name(cp, 'config:base')
|
||||
|
||||
# Apply historically 'Configuration.h' settings everywhere
|
||||
if ckey == 'basic':
|
||||
apply_ini_by_name(cp, 'config:basic')
|
||||
|
||||
# Apply historically Configuration_adv.h settings everywhere
|
||||
# (Some of which rely on defines in 'Conditionals_LCD.h')
|
||||
elif ckey in ('adv', 'advanced'):
|
||||
apply_ini_by_name(cp, 'config:advanced')
|
||||
|
||||
# Apply a specific config:<name> section directly
|
||||
elif ckey.startswith('config:'):
|
||||
apply_ini_by_name(cp, ckey)
|
||||
|
||||
# Apply settings from a top level config.ini
|
||||
def apply_config_ini(cp):
|
||||
blab("=" * 20 + " Gather 'config.ini' entries...")
|
||||
|
||||
# Pre-scan for ini_use_config to get config_keys
|
||||
base_items = section_items(cp, 'config:base') + section_items(cp, 'config:root')
|
||||
config_keys = ['base']
|
||||
for ikey, ival in base_items:
|
||||
if ikey == 'ini_use_config':
|
||||
config_keys = [ x.strip() for x in ival.split(',') ]
|
||||
|
||||
# For each ini_use_config item perform an action
|
||||
for ckey in config_keys:
|
||||
addbase = False
|
||||
|
||||
# For a key ending in .ini load and parse another .ini file
|
||||
if ckey.endswith('.ini'):
|
||||
sect = 'base'
|
||||
if '@' in ckey: sect, ckey = ckey.split('@')
|
||||
other_ini = configparser.ConfigParser()
|
||||
other_ini.read(config_path(ckey))
|
||||
apply_sections(other_ini, sect)
|
||||
|
||||
# (Allow 'example/' as a shortcut for 'examples/')
|
||||
elif ckey.startswith('example/'):
|
||||
ckey = 'examples' + ckey[7:]
|
||||
|
||||
# For 'examples/<path>' fetch an example set from GitHub.
|
||||
# For https?:// do a direct fetch of the URL.
|
||||
elif ckey.startswith('examples/') or ckey.startswith('http'):
|
||||
addbase = True
|
||||
fetch_example(ckey)
|
||||
|
||||
# Apply keyed sections after external files are done
|
||||
apply_sections(cp, 'config:' + ckey, addbase)
|
||||
|
||||
if __name__ == "__main__":
|
||||
#
|
||||
# From command line use the given file name
|
||||
#
|
||||
import sys
|
||||
args = sys.argv[1:]
|
||||
if len(args) > 0:
|
||||
if args[0].endswith('.ini'):
|
||||
ini_file = args[0]
|
||||
else:
|
||||
print("Usage: %s <.ini file>" % sys.argv[0])
|
||||
else:
|
||||
ini_file = config_path('config.ini')
|
||||
|
||||
if ini_file:
|
||||
user_ini = configparser.ConfigParser()
|
||||
user_ini.read(ini_file)
|
||||
apply_config_ini(user_ini)
|
||||
|
||||
else:
|
||||
#
|
||||
# From within PlatformIO use the loaded INI file
|
||||
#
|
||||
import pioutil
|
||||
if pioutil.is_pio_build():
|
||||
|
||||
Import("env")
|
||||
|
||||
try:
|
||||
verbose = int(env.GetProjectOption('custom_verbose'))
|
||||
except:
|
||||
pass
|
||||
|
||||
from platformio.project.config import ProjectConfig
|
||||
apply_config_ini(ProjectConfig())
|
403
buildroot/share/PlatformIO/scripts/schema.py
Executable file
403
buildroot/share/PlatformIO/scripts/schema.py
Executable file
@ -0,0 +1,403 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# schema.py
|
||||
#
|
||||
# Used by signature.py via common-dependencies.py to generate a schema file during the PlatformIO build.
|
||||
# This script can also be run standalone from within the Marlin repo to generate all schema files.
|
||||
#
|
||||
import re,json
|
||||
from pathlib import Path
|
||||
|
||||
def extend_dict(d:dict, k:tuple):
|
||||
if len(k) >= 1 and k[0] not in d:
|
||||
d[k[0]] = {}
|
||||
if len(k) >= 2 and k[1] not in d[k[0]]:
|
||||
d[k[0]][k[1]] = {}
|
||||
if len(k) >= 3 and k[2] not in d[k[0]][k[1]]:
|
||||
d[k[0]][k[1]][k[2]] = {}
|
||||
|
||||
grouping_patterns = [
|
||||
re.compile(r'^([XYZIJKUVW]|[XYZ]2|Z[34]|E[0-7])$'),
|
||||
re.compile(r'^AXIS\d$'),
|
||||
re.compile(r'^(MIN|MAX)$'),
|
||||
re.compile(r'^[0-8]$'),
|
||||
re.compile(r'^HOTEND[0-7]$'),
|
||||
re.compile(r'^(HOTENDS|BED|PROBE|COOLER)$'),
|
||||
re.compile(r'^[XYZIJKUVW]M(IN|AX)$')
|
||||
]
|
||||
# If the indexed part of the option name matches a pattern
|
||||
# then add it to the dictionary.
|
||||
def find_grouping(gdict, filekey, sectkey, optkey, pindex):
|
||||
optparts = optkey.split('_')
|
||||
if 1 < len(optparts) > pindex:
|
||||
for patt in grouping_patterns:
|
||||
if patt.match(optparts[pindex]):
|
||||
subkey = optparts[pindex]
|
||||
modkey = '_'.join(optparts)
|
||||
optparts[pindex] = '*'
|
||||
wildkey = '_'.join(optparts)
|
||||
kkey = f'{filekey}|{sectkey}|{wildkey}'
|
||||
if kkey not in gdict: gdict[kkey] = []
|
||||
gdict[kkey].append((subkey, modkey))
|
||||
|
||||
# Build a list of potential groups. Only those with multiple items will be grouped.
|
||||
def group_options(schema):
|
||||
for pindex in range(10, -1, -1):
|
||||
found_groups = {}
|
||||
for filekey, f in schema.items():
|
||||
for sectkey, s in f.items():
|
||||
for optkey in s:
|
||||
find_grouping(found_groups, filekey, sectkey, optkey, pindex)
|
||||
|
||||
fkeys = [ k for k in found_groups.keys() ]
|
||||
for kkey in fkeys:
|
||||
items = found_groups[kkey]
|
||||
if len(items) > 1:
|
||||
f, s, w = kkey.split('|')
|
||||
extend_dict(schema, (f, s, w)) # Add wildcard group to schema
|
||||
for subkey, optkey in items: # Add all items to wildcard group
|
||||
schema[f][s][w][subkey] = schema[f][s][optkey] # Move non-wildcard item to wildcard group
|
||||
del schema[f][s][optkey]
|
||||
del found_groups[kkey]
|
||||
|
||||
# Extract all board names from boards.h
|
||||
def load_boards():
|
||||
bpath = Path("Marlin/src/core/boards.h")
|
||||
if bpath.is_file():
|
||||
with bpath.open() as bfile:
|
||||
boards = []
|
||||
for line in bfile:
|
||||
if line.startswith("#define BOARD_"):
|
||||
bname = line.split()[1]
|
||||
if bname != "BOARD_UNKNOWN": boards.append(bname)
|
||||
return "['" + "','".join(boards) + "']"
|
||||
return ''
|
||||
|
||||
#
|
||||
# Extract a schema from the current configuration files
|
||||
#
|
||||
def extract():
|
||||
# Load board names from boards.h
|
||||
boards = load_boards()
|
||||
|
||||
# Parsing states
|
||||
class Parse:
|
||||
NORMAL = 0 # No condition yet
|
||||
BLOCK_COMMENT = 1 # Looking for the end of the block comment
|
||||
EOL_COMMENT = 2 # EOL comment started, maybe add the next comment?
|
||||
GET_SENSORS = 3 # Gathering temperature sensor options
|
||||
ERROR = 9 # Syntax error
|
||||
|
||||
# List of files to process, with shorthand
|
||||
filekey = { 'Configuration.h':'basic', 'Configuration_adv.h':'advanced' }
|
||||
# A JSON object to store the data
|
||||
sch_out = { 'basic':{}, 'advanced':{} }
|
||||
# Regex for #define NAME [VALUE] [COMMENT] with sanitized line
|
||||
defgrep = re.compile(r'^(//)?\s*(#define)\s+([A-Za-z0-9_]+)\s*(.*?)\s*(//.+)?$')
|
||||
# Defines to ignore
|
||||
ignore = ('CONFIGURATION_H_VERSION', 'CONFIGURATION_ADV_H_VERSION', 'CONFIG_EXPORT')
|
||||
# Start with unknown state
|
||||
state = Parse.NORMAL
|
||||
# Serial ID
|
||||
sid = 0
|
||||
# Loop through files and parse them line by line
|
||||
for fn, fk in filekey.items():
|
||||
with Path("Marlin", fn).open() as fileobj:
|
||||
section = 'none' # Current Settings section
|
||||
line_number = 0 # Counter for the line number of the file
|
||||
conditions = [] # Create a condition stack for the current file
|
||||
comment_buff = [] # A temporary buffer for comments
|
||||
options_json = '' # A buffer for the most recent options JSON found
|
||||
eol_options = False # The options came from end of line, so only apply once
|
||||
join_line = False # A flag that the line should be joined with the previous one
|
||||
line = '' # A line buffer to handle \ continuation
|
||||
last_added_ref = None # Reference to the last added item
|
||||
# Loop through the lines in the file
|
||||
for the_line in fileobj.readlines():
|
||||
line_number += 1
|
||||
|
||||
# Clean the line for easier parsing
|
||||
the_line = the_line.strip()
|
||||
|
||||
if join_line: # A previous line is being made longer
|
||||
line += (' ' if line else '') + the_line
|
||||
else: # Otherwise, start the line anew
|
||||
line, line_start = the_line, line_number
|
||||
|
||||
# If the resulting line ends with a \, don't process now.
|
||||
# Strip the end off. The next line will be joined with it.
|
||||
join_line = line.endswith("\\")
|
||||
if join_line:
|
||||
line = line[:-1].strip()
|
||||
continue
|
||||
else:
|
||||
line_end = line_number
|
||||
|
||||
defmatch = defgrep.match(line)
|
||||
|
||||
# Special handling for EOL comments after a #define.
|
||||
# At this point the #define is already digested and inserted,
|
||||
# so we have to extend it
|
||||
if state == Parse.EOL_COMMENT:
|
||||
# If the line is not a comment, we're done with the EOL comment
|
||||
if not defmatch and the_line.startswith('//'):
|
||||
comment_buff.append(the_line[2:].strip())
|
||||
else:
|
||||
last_added_ref['comment'] = ' '.join(comment_buff)
|
||||
comment_buff = []
|
||||
state = Parse.NORMAL
|
||||
|
||||
def use_comment(c, opt, sec, bufref):
|
||||
if c.startswith(':'): # If the comment starts with : then it has magic JSON
|
||||
d = c[1:].strip() # Strip the leading :
|
||||
cbr = c.rindex('}') if d.startswith('{') else c.rindex(']') if d.startswith('[') else 0
|
||||
if cbr:
|
||||
opt, cmt = c[1:cbr+1].strip(), c[cbr+1:].strip()
|
||||
if cmt != '': bufref.append(cmt)
|
||||
else:
|
||||
opt = c[1:].strip()
|
||||
elif c.startswith('@section'): # Start a new section
|
||||
sec = c[8:].strip()
|
||||
elif not c.startswith('========'):
|
||||
bufref.append(c)
|
||||
return opt, sec
|
||||
|
||||
# In a block comment, capture lines up to the end of the comment.
|
||||
# Assume nothing follows the comment closure.
|
||||
if state in (Parse.BLOCK_COMMENT, Parse.GET_SENSORS):
|
||||
endpos = line.find('*/')
|
||||
if endpos < 0:
|
||||
cline = line
|
||||
else:
|
||||
cline, line = line[:endpos].strip(), line[endpos+2:].strip()
|
||||
|
||||
# Temperature sensors are done
|
||||
if state == Parse.GET_SENSORS:
|
||||
options_json = f'[ {options_json[:-2]} ]'
|
||||
|
||||
state = Parse.NORMAL
|
||||
|
||||
# Strip the leading '*' from block comments
|
||||
if cline.startswith('*'): cline = cline[1:].strip()
|
||||
|
||||
# Collect temperature sensors
|
||||
if state == Parse.GET_SENSORS:
|
||||
sens = re.match(r'^(-?\d+)\s*:\s*(.+)$', cline)
|
||||
if sens:
|
||||
s2 = sens[2].replace("'","''")
|
||||
options_json += f"{sens[1]}:'{s2}', "
|
||||
|
||||
elif state == Parse.BLOCK_COMMENT:
|
||||
|
||||
# Look for temperature sensors
|
||||
if cline == "Temperature sensors available:":
|
||||
state, cline = Parse.GET_SENSORS, "Temperature Sensors"
|
||||
|
||||
options_json, section = use_comment(cline, options_json, section, comment_buff)
|
||||
|
||||
# For the normal state we're looking for any non-blank line
|
||||
elif state == Parse.NORMAL:
|
||||
# Skip a commented define when evaluating comment opening
|
||||
st = 2 if re.match(r'^//\s*#define', line) else 0
|
||||
cpos1 = line.find('/*') # Start a block comment on the line?
|
||||
cpos2 = line.find('//', st) # Start an end of line comment on the line?
|
||||
|
||||
# Only the first comment starter gets evaluated
|
||||
cpos = -1
|
||||
if cpos1 != -1 and (cpos1 < cpos2 or cpos2 == -1):
|
||||
cpos = cpos1
|
||||
comment_buff = []
|
||||
state = Parse.BLOCK_COMMENT
|
||||
eol_options = False
|
||||
|
||||
elif cpos2 != -1 and (cpos2 < cpos1 or cpos1 == -1):
|
||||
cpos = cpos2
|
||||
|
||||
# Expire end-of-line options after first use
|
||||
if cline.startswith(':'): eol_options = True
|
||||
|
||||
# Comment after a define may be continued on the following lines
|
||||
if state == Parse.NORMAL and defmatch != None and cpos > 10:
|
||||
state = Parse.EOL_COMMENT
|
||||
comment_buff = []
|
||||
|
||||
# Process the start of a new comment
|
||||
if cpos != -1:
|
||||
cline, line = line[cpos+2:].strip(), line[:cpos].strip()
|
||||
|
||||
# Strip leading '*' from block comments
|
||||
if state == Parse.BLOCK_COMMENT:
|
||||
if cline.startswith('*'): cline = cline[1:].strip()
|
||||
|
||||
# Buffer a non-empty comment start
|
||||
if cline != '':
|
||||
options_json, section = use_comment(cline, options_json, section, comment_buff)
|
||||
|
||||
# If the line has nothing before the comment, go to the next line
|
||||
if line == '':
|
||||
options_json = ''
|
||||
continue
|
||||
|
||||
# Parenthesize the given expression if needed
|
||||
def atomize(s):
|
||||
if s == '' \
|
||||
or re.match(r'^[A-Za-z0-9_]*(\([^)]+\))?$', s) \
|
||||
or re.match(r'^[A-Za-z0-9_]+ == \d+?$', s):
|
||||
return s
|
||||
return f'({s})'
|
||||
|
||||
#
|
||||
# The conditions stack is an array containing condition-arrays.
|
||||
# Each condition-array lists the conditions for the current block.
|
||||
# IF/N/DEF adds a new condition-array to the stack.
|
||||
# ELSE/ELIF/ENDIF pop the condition-array.
|
||||
# ELSE/ELIF negate the last item in the popped condition-array.
|
||||
# ELIF adds a new condition to the end of the array.
|
||||
# ELSE/ELIF re-push the condition-array.
|
||||
#
|
||||
cparts = line.split()
|
||||
iselif, iselse = cparts[0] == '#elif', cparts[0] == '#else'
|
||||
if iselif or iselse or cparts[0] == '#endif':
|
||||
if len(conditions) == 0:
|
||||
raise Exception(f'no #if block at line {line_number}')
|
||||
|
||||
# Pop the last condition-array from the stack
|
||||
prev = conditions.pop()
|
||||
|
||||
if iselif or iselse:
|
||||
prev[-1] = '!' + prev[-1] # Invert the last condition
|
||||
if iselif: prev.append(atomize(line[5:].strip()))
|
||||
conditions.append(prev)
|
||||
|
||||
elif cparts[0] == '#if':
|
||||
conditions.append([ atomize(line[3:].strip()) ])
|
||||
elif cparts[0] == '#ifdef':
|
||||
conditions.append([ f'defined({line[6:].strip()})' ])
|
||||
elif cparts[0] == '#ifndef':
|
||||
conditions.append([ f'!defined({line[7:].strip()})' ])
|
||||
|
||||
# Handle a complete #define line
|
||||
elif defmatch != None:
|
||||
|
||||
# Get the match groups into vars
|
||||
enabled, define_name, val = defmatch[1] == None, defmatch[3], defmatch[4]
|
||||
|
||||
# Increment the serial ID
|
||||
sid += 1
|
||||
|
||||
# Create a new dictionary for the current #define
|
||||
define_info = {
|
||||
'section': section,
|
||||
'name': define_name,
|
||||
'enabled': enabled,
|
||||
'line': line_start,
|
||||
'sid': sid
|
||||
}
|
||||
|
||||
if val != '': define_info['value'] = val
|
||||
|
||||
# Type is based on the value
|
||||
if val == '':
|
||||
value_type = 'switch'
|
||||
elif re.match(r'^(true|false)$', val):
|
||||
value_type = 'bool'
|
||||
val = val == 'true'
|
||||
elif re.match(r'^[-+]?\s*\d+$', val):
|
||||
value_type = 'int'
|
||||
val = int(val)
|
||||
elif re.match(r'[-+]?\s*(\d+\.|\d*\.\d+)([eE][-+]?\d+)?[fF]?', val):
|
||||
value_type = 'float'
|
||||
val = float(val.replace('f',''))
|
||||
else:
|
||||
value_type = 'string' if val[0] == '"' \
|
||||
else 'char' if val[0] == "'" \
|
||||
else 'state' if re.match(r'^(LOW|HIGH)$', val) \
|
||||
else 'enum' if re.match(r'^[A-Za-z0-9_]{3,}$', val) \
|
||||
else 'int[]' if re.match(r'^{(\s*[-+]?\s*\d+\s*(,\s*)?)+}$', val) \
|
||||
else 'float[]' if re.match(r'^{(\s*[-+]?\s*(\d+\.|\d*\.\d+)([eE][-+]?\d+)?[fF]?\s*(,\s*)?)+}$', val) \
|
||||
else 'array' if val[0] == '{' \
|
||||
else ''
|
||||
|
||||
if value_type != '': define_info['type'] = value_type
|
||||
|
||||
# Join up accumulated conditions with &&
|
||||
if conditions: define_info['requires'] = ' && '.join(sum(conditions, []))
|
||||
|
||||
# If the comment_buff is not empty, add the comment to the info
|
||||
if comment_buff:
|
||||
full_comment = '\n'.join(comment_buff)
|
||||
|
||||
# An EOL comment will be added later
|
||||
# The handling could go here instead of above
|
||||
if state == Parse.EOL_COMMENT:
|
||||
define_info['comment'] = ''
|
||||
else:
|
||||
define_info['comment'] = full_comment
|
||||
comment_buff = []
|
||||
|
||||
# If the comment specifies units, add that to the info
|
||||
units = re.match(r'^\(([^)]+)\)', full_comment)
|
||||
if units:
|
||||
units = units[1]
|
||||
if units == 's' or units == 'sec': units = 'seconds'
|
||||
define_info['units'] = units
|
||||
|
||||
# Set the options for the current #define
|
||||
if define_name == "MOTHERBOARD" and boards != '':
|
||||
define_info['options'] = boards
|
||||
elif options_json != '':
|
||||
define_info['options'] = options_json
|
||||
if eol_options: options_json = ''
|
||||
|
||||
# Create section dict if it doesn't exist yet
|
||||
if section not in sch_out[fk]: sch_out[fk][section] = {}
|
||||
|
||||
# If define has already been seen...
|
||||
if define_name in sch_out[fk][section]:
|
||||
info = sch_out[fk][section][define_name]
|
||||
if isinstance(info, dict): info = [ info ] # Convert a single dict into a list
|
||||
info.append(define_info) # Add to the list
|
||||
else:
|
||||
# Add the define dict with name as key
|
||||
sch_out[fk][section][define_name] = define_info
|
||||
|
||||
if state == Parse.EOL_COMMENT:
|
||||
last_added_ref = define_info
|
||||
|
||||
return sch_out
|
||||
|
||||
def dump_json(schema:dict, jpath:Path):
|
||||
with jpath.open('w') as jfile:
|
||||
json.dump(schema, jfile, ensure_ascii=False, indent=2)
|
||||
|
||||
def dump_yaml(schema:dict, ypath:Path):
|
||||
import yaml
|
||||
with ypath.open('w') as yfile:
|
||||
yaml.dump(schema, yfile, default_flow_style=False, width=120, indent=2)
|
||||
|
||||
def main():
|
||||
try:
|
||||
schema = extract()
|
||||
except Exception as exc:
|
||||
print("Error: " + str(exc))
|
||||
schema = None
|
||||
|
||||
if schema:
|
||||
print("Generating JSON ...")
|
||||
dump_json(schema, Path('schema.json'))
|
||||
group_options(schema)
|
||||
dump_json(schema, Path('schema_grouped.json'))
|
||||
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
print("Installing YAML module ...")
|
||||
import subprocess
|
||||
subprocess.run(['python3', '-m', 'pip', 'install', 'pyyaml'])
|
||||
import yaml
|
||||
|
||||
print("Generating YML ...")
|
||||
dump_yaml(schema, Path('schema.yml'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,7 +1,11 @@
|
||||
#
|
||||
# signature.py
|
||||
#
|
||||
import os,subprocess,re,json,hashlib
|
||||
import schema
|
||||
|
||||
import subprocess,re,json,hashlib
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
#
|
||||
# Return all macro names in a header as an array, so we can take
|
||||
@ -35,8 +39,8 @@ def get_file_sha256sum(filepath):
|
||||
# Compress a JSON file into a zip file
|
||||
#
|
||||
import zipfile
|
||||
def compress_file(filepath, outputbase):
|
||||
with zipfile.ZipFile(outputbase + '.zip', 'w', compression=zipfile.ZIP_BZIP2, compresslevel=9) as zipf:
|
||||
def compress_file(filepath, outpath):
|
||||
with zipfile.ZipFile(outpath, 'w', compression=zipfile.ZIP_BZIP2, compresslevel=9) as zipf:
|
||||
zipf.write(filepath, compress_type=zipfile.ZIP_BZIP2, compresslevel=9)
|
||||
|
||||
#
|
||||
@ -51,19 +55,19 @@ def compute_build_signature(env):
|
||||
# Definitions from these files will be kept
|
||||
files_to_keep = [ 'Marlin/Configuration.h', 'Marlin/Configuration_adv.h' ]
|
||||
|
||||
build_dir = os.path.join(env['PROJECT_BUILD_DIR'], env['PIOENV'])
|
||||
build_path = Path(env['PROJECT_BUILD_DIR'], env['PIOENV'])
|
||||
|
||||
# Check if we can skip processing
|
||||
hashes = ''
|
||||
for header in files_to_keep:
|
||||
hashes += get_file_sha256sum(header)[0:10]
|
||||
|
||||
marlin_json = os.path.join(build_dir, 'marlin_config.json')
|
||||
marlin_zip = os.path.join(build_dir, 'mc')
|
||||
marlin_json = build_path / 'marlin_config.json'
|
||||
marlin_zip = build_path / 'mc.zip'
|
||||
|
||||
# Read existing config file
|
||||
try:
|
||||
with open(marlin_json, 'r') as infile:
|
||||
with marlin_json.open() as infile:
|
||||
conf = json.load(infile)
|
||||
if conf['__INITIAL_HASH'] == hashes:
|
||||
# Same configuration, skip recomputing the building signature
|
||||
@ -109,7 +113,10 @@ def compute_build_signature(env):
|
||||
|
||||
defines[key] = value if len(value) else ""
|
||||
|
||||
if not 'CONFIGURATION_EMBEDDING' in defines:
|
||||
#
|
||||
# Continue to gather data for CONFIGURATION_EMBEDDING or CONFIG_EXPORT
|
||||
#
|
||||
if not ('CONFIGURATION_EMBEDDING' in defines or 'CONFIG_EXPORT' in defines):
|
||||
return
|
||||
|
||||
# Second step is to filter useless macro
|
||||
@ -145,6 +152,85 @@ def compute_build_signature(env):
|
||||
if key in conf_defines[header]:
|
||||
data[header][key] = resolved_defines[key]
|
||||
|
||||
# Every python needs this toy
|
||||
def tryint(key):
|
||||
try:
|
||||
return int(defines[key])
|
||||
except:
|
||||
return 0
|
||||
|
||||
config_dump = tryint('CONFIG_EXPORT')
|
||||
|
||||
#
|
||||
# Produce an INI file if CONFIG_EXPORT == 2
|
||||
#
|
||||
if config_dump == 2:
|
||||
print("Generating config.ini ...")
|
||||
config_ini = build_path / 'config.ini'
|
||||
with config_ini.open('w') as outfile:
|
||||
ignore = ('CONFIGURATION_H_VERSION', 'CONFIGURATION_ADV_H_VERSION', 'CONFIG_EXPORT')
|
||||
filegrp = { 'Configuration.h':'config:basic', 'Configuration_adv.h':'config:advanced' }
|
||||
vers = defines["CONFIGURATION_H_VERSION"]
|
||||
dt_string = datetime.now().strftime("%Y-%m-%d at %H:%M:%S")
|
||||
ini_fmt = '{0:40}{1}\n'
|
||||
outfile.write(
|
||||
'#\n'
|
||||
+ '# Marlin Firmware\n'
|
||||
+ '# config.ini - Options to apply before the build\n'
|
||||
+ '#\n'
|
||||
+ f'# Generated by Marlin build on {dt_string}\n'
|
||||
+ '#\n'
|
||||
+ '\n'
|
||||
+ '[config:base]\n'
|
||||
+ ini_fmt.format('ini_use_config', ' = all')
|
||||
+ ini_fmt.format('ini_config_vers', f' = {vers}')
|
||||
)
|
||||
# Loop through the data array of arrays
|
||||
for header in data:
|
||||
if header.startswith('__'):
|
||||
continue
|
||||
outfile.write('\n[' + filegrp[header] + ']\n')
|
||||
for key in sorted(data[header]):
|
||||
if key not in ignore:
|
||||
val = 'on' if data[header][key] == '' else data[header][key]
|
||||
outfile.write(ini_fmt.format(key.lower(), ' = ' + val))
|
||||
|
||||
#
|
||||
# Produce a schema.json file if CONFIG_EXPORT == 3
|
||||
#
|
||||
if config_dump >= 3:
|
||||
try:
|
||||
conf_schema = schema.extract()
|
||||
except Exception as exc:
|
||||
print("Error: " + str(exc))
|
||||
conf_schema = None
|
||||
|
||||
if conf_schema:
|
||||
#
|
||||
# Produce a schema.json file if CONFIG_EXPORT == 3
|
||||
#
|
||||
if config_dump in (3, 13):
|
||||
print("Generating schema.json ...")
|
||||
schema.dump_json(conf_schema, build_path / 'schema.json')
|
||||
if config_dump == 13:
|
||||
schema.group_options(conf_schema)
|
||||
schema.dump_json(conf_schema, build_path / 'schema_grouped.json')
|
||||
|
||||
#
|
||||
# Produce a schema.yml file if CONFIG_EXPORT == 4
|
||||
#
|
||||
elif config_dump == 4:
|
||||
print("Generating schema.yml ...")
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
env.Execute(env.VerboseAction(
|
||||
'$PYTHONEXE -m pip install "pyyaml"',
|
||||
"Installing YAML for schema.yml export",
|
||||
))
|
||||
import yaml
|
||||
schema.dump_yaml(conf_schema, build_path / 'schema.yml')
|
||||
|
||||
# Append the source code version and date
|
||||
data['VERSION'] = {}
|
||||
data['VERSION']['DETAILED_BUILD_VERSION'] = resolved_defines['DETAILED_BUILD_VERSION']
|
||||
@ -156,10 +242,17 @@ def compute_build_signature(env):
|
||||
pass
|
||||
|
||||
#
|
||||
# Produce a JSON file for CONFIGURATION_EMBEDDING or CONFIG_DUMP > 0
|
||||
# Produce a JSON file for CONFIGURATION_EMBEDDING or CONFIG_EXPORT == 1
|
||||
#
|
||||
with open(marlin_json, 'w') as outfile:
|
||||
json.dump(data, outfile, separators=(',', ':'))
|
||||
if config_dump == 1 or 'CONFIGURATION_EMBEDDING' in defines:
|
||||
with marlin_json.open('w') as outfile:
|
||||
json.dump(data, outfile, separators=(',', ':'))
|
||||
|
||||
#
|
||||
# The rest only applies to CONFIGURATION_EMBEDDING
|
||||
#
|
||||
if not 'CONFIGURATION_EMBEDDING' in defines:
|
||||
return
|
||||
|
||||
# Compress the JSON file as much as we can
|
||||
compress_file(marlin_json, marlin_zip)
|
||||
@ -167,17 +260,17 @@ def compute_build_signature(env):
|
||||
# Generate a C source file for storing this array
|
||||
with open('Marlin/src/mczip.h','wb') as result_file:
|
||||
result_file.write(
|
||||
b'#ifndef NO_CONFIGURATION_EMBEDDING_WARNING\n'
|
||||
b'#ifndef NO_CONFIGURATION_EMBEDDING_WARNING\n'
|
||||
+ b' #warning "Generated file \'mc.zip\' is embedded (Define NO_CONFIGURATION_EMBEDDING_WARNING to suppress this warning.)"\n'
|
||||
+ b'#endif\n'
|
||||
+ b'const unsigned char mc_zip[] PROGMEM = {\n '
|
||||
)
|
||||
count = 0
|
||||
for b in open(os.path.join(build_dir, 'mc.zip'), 'rb').read():
|
||||
for b in (build_path / 'mc.zip').open('rb').read():
|
||||
result_file.write(b' 0x%02X,' % b)
|
||||
count += 1
|
||||
if (count % 16 == 0):
|
||||
result_file.write(b'\n ')
|
||||
if (count % 16):
|
||||
if count % 16 == 0:
|
||||
result_file.write(b'\n ')
|
||||
if count % 16:
|
||||
result_file.write(b'\n')
|
||||
result_file.write(b'};\n')
|
||||
|
@ -16,6 +16,7 @@ boards_dir = buildroot/share/PlatformIO/boards
|
||||
default_envs = mega2560
|
||||
include_dir = Marlin
|
||||
extra_configs =
|
||||
Marlin/config.ini
|
||||
ini/avr.ini
|
||||
ini/due.ini
|
||||
ini/esp32.ini
|
||||
@ -44,12 +45,13 @@ extra_configs =
|
||||
build_flags = -g3 -D__MARLIN_FIRMWARE__ -DNDEBUG
|
||||
-fmax-errors=5
|
||||
extra_scripts =
|
||||
pre:buildroot/share/PlatformIO/scripts/configuration.py
|
||||
pre:buildroot/share/PlatformIO/scripts/common-dependencies.py
|
||||
pre:buildroot/share/PlatformIO/scripts/common-cxxflags.py
|
||||
pre:buildroot/share/PlatformIO/scripts/preflight-checks.py
|
||||
post:buildroot/share/PlatformIO/scripts/common-dependencies-post.py
|
||||
lib_deps =
|
||||
default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
|
||||
default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared> -<Marlin/Marlin.ino>
|
||||
-<src/lcd/HD44780> -<src/lcd/TFTGLCD> -<src/lcd/dogm> -<src/lcd/tft> -<src/lcd/tft_io>
|
||||
-<src/HAL/STM32/tft> -<src/HAL/STM32F1/tft>
|
||||
-<src/lcd/e3v2/common> -<src/lcd/e3v2/creality> -<src/lcd/e3v2/proui> -<src/lcd/e3v2/jyersui> -<src/lcd/e3v2/marlinui>
|
||||
|
Loading…
Reference in New Issue
Block a user