|
|
@ -850,10 +850,6 @@ void servo_init() {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
STOW_Z_SERVO();
|
|
|
|
STOW_Z_SERVO();
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if HAS_BED_PROBE
|
|
|
|
|
|
|
|
endstops.enable_z_probe(false);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -879,216 +875,6 @@ void servo_init() {
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Marlin entry-point: Set up before the program loop
|
|
|
|
|
|
|
|
* - Set up the kill pin, filament runout, power hold
|
|
|
|
|
|
|
|
* - Start the serial port
|
|
|
|
|
|
|
|
* - 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
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DISABLE_JTAG
|
|
|
|
|
|
|
|
// Disable JTAG on AT90USB chips to free up pins for IO
|
|
|
|
|
|
|
|
MCUCR = 0x80;
|
|
|
|
|
|
|
|
MCUCR = 0x80;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|
|
|
|
|
|
|
|
setup_filrunoutpin();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setup_killpin();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setup_powerhold();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if HAS_STEPPER_RESET
|
|
|
|
|
|
|
|
disableStepperDrivers();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MYSERIAL.begin(BAUDRATE);
|
|
|
|
|
|
|
|
SERIAL_PROTOCOLLNPGM("start");
|
|
|
|
|
|
|
|
SERIAL_ECHO_START;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check startup - does nothing if bootloader sets MCUSR to 0
|
|
|
|
|
|
|
|
byte mcu = MCUSR;
|
|
|
|
|
|
|
|
if (mcu & 1) SERIAL_ECHOLNPGM(MSG_POWERUP);
|
|
|
|
|
|
|
|
if (mcu & 2) SERIAL_ECHOLNPGM(MSG_EXTERNAL_RESET);
|
|
|
|
|
|
|
|
if (mcu & 4) SERIAL_ECHOLNPGM(MSG_BROWNOUT_RESET);
|
|
|
|
|
|
|
|
if (mcu & 8) SERIAL_ECHOLNPGM(MSG_WATCHDOG_RESET);
|
|
|
|
|
|
|
|
if (mcu & 32) SERIAL_ECHOLNPGM(MSG_SOFTWARE_RESET);
|
|
|
|
|
|
|
|
MCUSR = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(MSG_MARLIN);
|
|
|
|
|
|
|
|
SERIAL_ECHOLNPGM(" " SHORT_BUILD_VERSION);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef STRING_DISTRIBUTION_DATE
|
|
|
|
|
|
|
|
#ifdef STRING_CONFIG_H_AUTHOR
|
|
|
|
|
|
|
|
SERIAL_ECHO_START;
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(MSG_CONFIGURATION_VER);
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(STRING_DISTRIBUTION_DATE);
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(MSG_AUTHOR);
|
|
|
|
|
|
|
|
SERIAL_ECHOLNPGM(STRING_CONFIG_H_AUTHOR);
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM("Compiled: ");
|
|
|
|
|
|
|
|
SERIAL_ECHOLNPGM(__DATE__);
|
|
|
|
|
|
|
|
#endif // STRING_CONFIG_H_AUTHOR
|
|
|
|
|
|
|
|
#endif // STRING_DISTRIBUTION_DATE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SERIAL_ECHO_START;
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(MSG_FREE_MEMORY);
|
|
|
|
|
|
|
|
SERIAL_ECHO(freeMemory());
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(MSG_PLANNER_BUFFER_BYTES);
|
|
|
|
|
|
|
|
SERIAL_ECHOLN((int)sizeof(block_t)*BLOCK_BUFFER_SIZE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Send "ok" after commands by default
|
|
|
|
|
|
|
|
for (int8_t i = 0; i < BUFSIZE; i++) send_ok[i] = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Load data from EEPROM if available (or use defaults)
|
|
|
|
|
|
|
|
// This also updates variables in the planner, elsewhere
|
|
|
|
|
|
|
|
Config_RetrieveSettings();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize current position based on home_offset
|
|
|
|
|
|
|
|
memcpy(current_position, home_offset, sizeof(home_offset));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Vital to init stepper/planner equivalent for current_position
|
|
|
|
|
|
|
|
SYNC_PLAN_POSITION_KINEMATIC();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
thermalManager.init(); // Initialize temperature loop
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(USE_WATCHDOG)
|
|
|
|
|
|
|
|
watchdog_init();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stepper.init(); // Initialize stepper, this enables interrupts!
|
|
|
|
|
|
|
|
setup_photpin();
|
|
|
|
|
|
|
|
servo_init();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if HAS_CONTROLLERFAN
|
|
|
|
|
|
|
|
SET_OUTPUT(CONTROLLERFAN_PIN); //Set pin used for driver cooling fan
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if HAS_STEPPER_RESET
|
|
|
|
|
|
|
|
enableStepperDrivers();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(DIGIPOT_I2C)
|
|
|
|
|
|
|
|
digipot_i2c_init();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(DAC_STEPPER_CURRENT)
|
|
|
|
|
|
|
|
dac_init();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(Z_PROBE_SLED) && PIN_EXISTS(SLED)
|
|
|
|
|
|
|
|
pinMode(SLED_PIN, OUTPUT);
|
|
|
|
|
|
|
|
digitalWrite(SLED_PIN, LOW); // turn it off
|
|
|
|
|
|
|
|
#endif // Z_PROBE_SLED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setup_homepin();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef STAT_LED_RED
|
|
|
|
|
|
|
|
pinMode(STAT_LED_RED, OUTPUT);
|
|
|
|
|
|
|
|
digitalWrite(STAT_LED_RED, LOW); // turn it off
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef STAT_LED_BLUE
|
|
|
|
|
|
|
|
pinMode(STAT_LED_BLUE, OUTPUT);
|
|
|
|
|
|
|
|
digitalWrite(STAT_LED_BLUE, LOW); // turn it off
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lcd_init();
|
|
|
|
|
|
|
|
#if ENABLED(SHOW_BOOTSCREEN)
|
|
|
|
|
|
|
|
#if ENABLED(DOGLCD)
|
|
|
|
|
|
|
|
safe_delay(BOOTSCREEN_TIMEOUT);
|
|
|
|
|
|
|
|
#elif ENABLED(ULTRA_LCD)
|
|
|
|
|
|
|
|
bootscreen();
|
|
|
|
|
|
|
|
lcd_init();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1
|
|
|
|
|
|
|
|
// Initialize mixing to 100% color 1
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
|
|
|
|
|
|
|
|
mixing_factor[i] = (i == 0) ? 1 : 0;
|
|
|
|
|
|
|
|
for (uint8_t t = 0; t < MIXING_VIRTUAL_TOOLS; t++)
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
|
|
|
|
|
|
|
|
mixing_virtual_tool_mix[t][i] = mixing_factor[i];
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
|
|
|
|
|
|
|
|
i2c.onReceive(i2c_on_receive);
|
|
|
|
|
|
|
|
i2c.onRequest(i2c_on_request);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The main Marlin program loop
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* - Save or log commands to SD
|
|
|
|
|
|
|
|
* - Process available commands (if not saving)
|
|
|
|
|
|
|
|
* - Call heater manager
|
|
|
|
|
|
|
|
* - Call inactivity manager
|
|
|
|
|
|
|
|
* - Call endstop manager
|
|
|
|
|
|
|
|
* - Call LCD update
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
|
|
|
|
if (commands_in_queue < BUFSIZE) get_available_commands();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(SDSUPPORT)
|
|
|
|
|
|
|
|
card.checkautostart(false);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (commands_in_queue) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(SDSUPPORT)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (card.saving) {
|
|
|
|
|
|
|
|
char* command = command_queue[cmd_queue_index_r];
|
|
|
|
|
|
|
|
if (strstr_P(command, PSTR("M29"))) {
|
|
|
|
|
|
|
|
// M29 closes the file
|
|
|
|
|
|
|
|
card.closefile();
|
|
|
|
|
|
|
|
SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED);
|
|
|
|
|
|
|
|
ok_to_send();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
// Write the string from the read buffer to SD
|
|
|
|
|
|
|
|
card.write_command(command);
|
|
|
|
|
|
|
|
if (card.logging)
|
|
|
|
|
|
|
|
process_next_command(); // The card is saving because it's logging
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
ok_to_send();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
process_next_command();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
process_next_command();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif // SDSUPPORT
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The queue may be reset by a command handler or by code invoked by idle() within a handler
|
|
|
|
|
|
|
|
if (commands_in_queue) {
|
|
|
|
|
|
|
|
--commands_in_queue;
|
|
|
|
|
|
|
|
cmd_queue_index_r = (cmd_queue_index_r + 1) % BUFSIZE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
endstops.report_state();
|
|
|
|
|
|
|
|
idle();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void gcode_line_error(const char* err, bool doFlush = true) {
|
|
|
|
void gcode_line_error(const char* err, bool doFlush = true) {
|
|
|
|
SERIAL_ERROR_START;
|
|
|
|
SERIAL_ERROR_START;
|
|
|
|
serialprintPGM(err);
|
|
|
|
serialprintPGM(err);
|
|
|
@ -8889,3 +8675,217 @@ void calculate_volumetric_multipliers() {
|
|
|
|
for (uint8_t i = 0; i < COUNT(filament_size); i++)
|
|
|
|
for (uint8_t i = 0; i < COUNT(filament_size); i++)
|
|
|
|
volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]);
|
|
|
|
volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Marlin entry-point: Set up before the program loop
|
|
|
|
|
|
|
|
* - Set up the kill pin, filament runout, power hold
|
|
|
|
|
|
|
|
* - Start the serial port
|
|
|
|
|
|
|
|
* - 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
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DISABLE_JTAG
|
|
|
|
|
|
|
|
// Disable JTAG on AT90USB chips to free up pins for IO
|
|
|
|
|
|
|
|
MCUCR = 0x80;
|
|
|
|
|
|
|
|
MCUCR = 0x80;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|
|
|
|
|
|
|
|
setup_filrunoutpin();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setup_killpin();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setup_powerhold();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if HAS_STEPPER_RESET
|
|
|
|
|
|
|
|
disableStepperDrivers();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MYSERIAL.begin(BAUDRATE);
|
|
|
|
|
|
|
|
SERIAL_PROTOCOLLNPGM("start");
|
|
|
|
|
|
|
|
SERIAL_ECHO_START;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check startup - does nothing if bootloader sets MCUSR to 0
|
|
|
|
|
|
|
|
byte mcu = MCUSR;
|
|
|
|
|
|
|
|
if (mcu & 1) SERIAL_ECHOLNPGM(MSG_POWERUP);
|
|
|
|
|
|
|
|
if (mcu & 2) SERIAL_ECHOLNPGM(MSG_EXTERNAL_RESET);
|
|
|
|
|
|
|
|
if (mcu & 4) SERIAL_ECHOLNPGM(MSG_BROWNOUT_RESET);
|
|
|
|
|
|
|
|
if (mcu & 8) SERIAL_ECHOLNPGM(MSG_WATCHDOG_RESET);
|
|
|
|
|
|
|
|
if (mcu & 32) SERIAL_ECHOLNPGM(MSG_SOFTWARE_RESET);
|
|
|
|
|
|
|
|
MCUSR = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(MSG_MARLIN);
|
|
|
|
|
|
|
|
SERIAL_ECHOLNPGM(" " SHORT_BUILD_VERSION);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef STRING_DISTRIBUTION_DATE
|
|
|
|
|
|
|
|
#ifdef STRING_CONFIG_H_AUTHOR
|
|
|
|
|
|
|
|
SERIAL_ECHO_START;
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(MSG_CONFIGURATION_VER);
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(STRING_DISTRIBUTION_DATE);
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(MSG_AUTHOR);
|
|
|
|
|
|
|
|
SERIAL_ECHOLNPGM(STRING_CONFIG_H_AUTHOR);
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM("Compiled: ");
|
|
|
|
|
|
|
|
SERIAL_ECHOLNPGM(__DATE__);
|
|
|
|
|
|
|
|
#endif // STRING_CONFIG_H_AUTHOR
|
|
|
|
|
|
|
|
#endif // STRING_DISTRIBUTION_DATE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SERIAL_ECHO_START;
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(MSG_FREE_MEMORY);
|
|
|
|
|
|
|
|
SERIAL_ECHO(freeMemory());
|
|
|
|
|
|
|
|
SERIAL_ECHOPGM(MSG_PLANNER_BUFFER_BYTES);
|
|
|
|
|
|
|
|
SERIAL_ECHOLN((int)sizeof(block_t)*BLOCK_BUFFER_SIZE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Send "ok" after commands by default
|
|
|
|
|
|
|
|
for (int8_t i = 0; i < BUFSIZE; i++) send_ok[i] = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Load data from EEPROM if available (or use defaults)
|
|
|
|
|
|
|
|
// This also updates variables in the planner, elsewhere
|
|
|
|
|
|
|
|
Config_RetrieveSettings();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize current position based on home_offset
|
|
|
|
|
|
|
|
memcpy(current_position, home_offset, sizeof(home_offset));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Vital to init stepper/planner equivalent for current_position
|
|
|
|
|
|
|
|
SYNC_PLAN_POSITION_KINEMATIC();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
thermalManager.init(); // Initialize temperature loop
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(USE_WATCHDOG)
|
|
|
|
|
|
|
|
watchdog_init();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stepper.init(); // Initialize stepper, this enables interrupts!
|
|
|
|
|
|
|
|
setup_photpin();
|
|
|
|
|
|
|
|
servo_init();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if HAS_BED_PROBE
|
|
|
|
|
|
|
|
endstops.enable_z_probe(false);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if HAS_CONTROLLERFAN
|
|
|
|
|
|
|
|
SET_OUTPUT(CONTROLLERFAN_PIN); //Set pin used for driver cooling fan
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if HAS_STEPPER_RESET
|
|
|
|
|
|
|
|
enableStepperDrivers();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(DIGIPOT_I2C)
|
|
|
|
|
|
|
|
digipot_i2c_init();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(DAC_STEPPER_CURRENT)
|
|
|
|
|
|
|
|
dac_init();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(Z_PROBE_SLED) && PIN_EXISTS(SLED)
|
|
|
|
|
|
|
|
pinMode(SLED_PIN, OUTPUT);
|
|
|
|
|
|
|
|
digitalWrite(SLED_PIN, LOW); // turn it off
|
|
|
|
|
|
|
|
#endif // Z_PROBE_SLED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setup_homepin();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef STAT_LED_RED
|
|
|
|
|
|
|
|
pinMode(STAT_LED_RED, OUTPUT);
|
|
|
|
|
|
|
|
digitalWrite(STAT_LED_RED, LOW); // turn it off
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef STAT_LED_BLUE
|
|
|
|
|
|
|
|
pinMode(STAT_LED_BLUE, OUTPUT);
|
|
|
|
|
|
|
|
digitalWrite(STAT_LED_BLUE, LOW); // turn it off
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lcd_init();
|
|
|
|
|
|
|
|
#if ENABLED(SHOW_BOOTSCREEN)
|
|
|
|
|
|
|
|
#if ENABLED(DOGLCD)
|
|
|
|
|
|
|
|
safe_delay(BOOTSCREEN_TIMEOUT);
|
|
|
|
|
|
|
|
#elif ENABLED(ULTRA_LCD)
|
|
|
|
|
|
|
|
bootscreen();
|
|
|
|
|
|
|
|
lcd_init();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1
|
|
|
|
|
|
|
|
// Initialize mixing to 100% color 1
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
|
|
|
|
|
|
|
|
mixing_factor[i] = (i == 0) ? 1 : 0;
|
|
|
|
|
|
|
|
for (uint8_t t = 0; t < MIXING_VIRTUAL_TOOLS; t++)
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
|
|
|
|
|
|
|
|
mixing_virtual_tool_mix[t][i] = mixing_factor[i];
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
|
|
|
|
|
|
|
|
i2c.onReceive(i2c_on_receive);
|
|
|
|
|
|
|
|
i2c.onRequest(i2c_on_request);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The main Marlin program loop
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* - Save or log commands to SD
|
|
|
|
|
|
|
|
* - Process available commands (if not saving)
|
|
|
|
|
|
|
|
* - Call heater manager
|
|
|
|
|
|
|
|
* - Call inactivity manager
|
|
|
|
|
|
|
|
* - Call endstop manager
|
|
|
|
|
|
|
|
* - Call LCD update
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
|
|
|
|
if (commands_in_queue < BUFSIZE) get_available_commands();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(SDSUPPORT)
|
|
|
|
|
|
|
|
card.checkautostart(false);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (commands_in_queue) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(SDSUPPORT)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (card.saving) {
|
|
|
|
|
|
|
|
char* command = command_queue[cmd_queue_index_r];
|
|
|
|
|
|
|
|
if (strstr_P(command, PSTR("M29"))) {
|
|
|
|
|
|
|
|
// M29 closes the file
|
|
|
|
|
|
|
|
card.closefile();
|
|
|
|
|
|
|
|
SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED);
|
|
|
|
|
|
|
|
ok_to_send();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
// Write the string from the read buffer to SD
|
|
|
|
|
|
|
|
card.write_command(command);
|
|
|
|
|
|
|
|
if (card.logging)
|
|
|
|
|
|
|
|
process_next_command(); // The card is saving because it's logging
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
ok_to_send();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
process_next_command();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
process_next_command();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif // SDSUPPORT
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The queue may be reset by a command handler or by code invoked by idle() within a handler
|
|
|
|
|
|
|
|
if (commands_in_queue) {
|
|
|
|
|
|
|
|
--commands_in_queue;
|
|
|
|
|
|
|
|
cmd_queue_index_r = (cmd_queue_index_r + 1) % BUFSIZE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
endstops.report_state();
|
|
|
|
|
|
|
|
idle();
|
|
|
|
|
|
|
|
}
|
|
|
|