- Probe index (optional - defaults to 0
- */
- inline void gcode_M43() {
-
- if (parser.seen('T')) { // must be first or else its "S" and "E" parameters will execute endstop or servo test
- toggle_pins();
- return;
- }
-
- // Enable or disable endstop monitoring
- if (parser.seen('E')) {
- endstop_monitor_flag = parser.value_bool();
- SERIAL_PROTOCOLPGM("endstop monitor ");
- serialprintPGM(endstop_monitor_flag ? PSTR("en") : PSTR("dis"));
- SERIAL_PROTOCOLLNPGM("abled");
- return;
- }
-
- if (parser.seen('S')) {
- servo_probe_test();
- return;
- }
-
- // Get the range of pins to test or watch
- const pin_t first_pin = parser.byteval('P'),
- last_pin = parser.seenval('P') ? first_pin : NUM_DIGITAL_PINS - 1;
-
- if (first_pin > last_pin) return;
-
- const bool ignore_protection = parser.boolval('I');
-
- // Watch until click, M108, or reset
- if (parser.boolval('W')) {
- SERIAL_PROTOCOLLNPGM("Watching pins");
- byte pin_state[last_pin - first_pin + 1];
- for (pin_t pin = first_pin; pin <= last_pin; pin++) {
- if (!ignore_protection && pin_is_protected(pin)) continue;
- pinMode(pin, INPUT_PULLUP);
- delay(1);
- /*
- if (IS_ANALOG(pin))
- pin_state[pin - first_pin] = analogRead(pin - analogInputToDigitalPin(0)); // int16_t pin_state[...]
- else
- //*/
- pin_state[pin - first_pin] = digitalRead(pin);
- }
-
- #if HAS_RESUME_CONTINUE
- wait_for_user = true;
- KEEPALIVE_STATE(PAUSED_FOR_USER);
- #endif
-
- for (;;) {
- for (pin_t pin = first_pin; pin <= last_pin; pin++) {
- if (!ignore_protection && pin_is_protected(pin)) continue;
- const byte val =
- /*
- IS_ANALOG(pin)
- ? analogRead(pin - analogInputToDigitalPin(0)) : // int16_t val
- :
- //*/
- digitalRead(pin);
- if (val != pin_state[pin - first_pin]) {
- report_pin_state_extended(pin, ignore_protection, false);
- pin_state[pin - first_pin] = val;
- }
- }
-
- #if HAS_RESUME_CONTINUE
- if (!wait_for_user) {
- KEEPALIVE_STATE(IN_HANDLER);
- break;
- }
- #endif
-
- safe_delay(200);
- }
- return;
- }
-
- // Report current state of selected pin(s)
- for (pin_t pin = first_pin; pin <= last_pin; pin++)
- report_pin_state_extended(pin, ignore_protection, true);
- }
-
-#endif // PINS_DEBUGGING
-
-#if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST)
-
- /**
- * M48: Z probe repeatability measurement function.
- *
- * Usage:
- * M48
- * P = Number of sampled points (4-50, default 10)
- * X = Sample X position
- * Y = Sample Y position
- * V = Verbose level (0-4, default=1)
- * E = Engage Z probe for each reading
- * L = Number of legs of movement before probe
- * S = Schizoid (Or Star if you prefer)
- *
- * This function requires the machine to be homed before invocation.
- */
- inline void gcode_M48() {
-
- if (axis_unhomed_error()) return;
-
- const int8_t verbose_level = parser.byteval('V', 1);
- if (!WITHIN(verbose_level, 0, 4)) {
- SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-4).");
- return;
- }
-
- if (verbose_level > 0)
- SERIAL_PROTOCOLLNPGM("M48 Z-Probe Repeatability Test");
-
- const int8_t n_samples = parser.byteval('P', 10);
- if (!WITHIN(n_samples, 4, 50)) {
- SERIAL_PROTOCOLLNPGM("?Sample size not plausible (4-50).");
- return;
- }
-
- const ProbePtRaise raise_after = parser.boolval('E') ? PROBE_PT_STOW : PROBE_PT_RAISE;
-
- float X_current = current_position[X_AXIS],
- Y_current = current_position[Y_AXIS];
-
- const float X_probe_location = parser.linearval('X', X_current + X_PROBE_OFFSET_FROM_EXTRUDER),
- Y_probe_location = parser.linearval('Y', Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER);
-
- if (!position_is_reachable_by_probe(X_probe_location, Y_probe_location)) {
- SERIAL_PROTOCOLLNPGM("? (X,Y) out of bounds.");
- return;
- }
-
- bool seen_L = parser.seen('L');
- uint8_t n_legs = seen_L ? parser.value_byte() : 0;
- if (n_legs > 15) {
- SERIAL_PROTOCOLLNPGM("?Number of legs in movement not plausible (0-15).");
- return;
- }
- if (n_legs == 1) n_legs = 2;
-
- const bool schizoid_flag = parser.boolval('S');
- if (schizoid_flag && !seen_L) n_legs = 7;
-
- /**
- * Now get everything to the specified probe point So we can safely do a
- * probe to get us close to the bed. If the Z-Axis is far from the bed,
- * we don't want to use that as a starting point for each probe.
- */
- if (verbose_level > 2)
- SERIAL_PROTOCOLLNPGM("Positioning the probe...");
-
- // Disable bed level correction in M48 because we want the raw data when we probe
-
- #if HAS_LEVELING
- const bool was_enabled = planner.leveling_active;
- set_bed_leveling_enabled(false);
- #endif
-
- setup_for_endstop_or_probe_move();
-
- float mean = 0.0, sigma = 0.0, min = 99999.9, max = -99999.9, sample_set[n_samples];
-
- // Move to the first point, deploy, and probe
- const float t = probe_pt(X_probe_location, Y_probe_location, raise_after, verbose_level);
- bool probing_good = !isnan(t);
-
- if (probing_good) {
- randomSeed(millis());
-
- for (uint8_t n = 0; n < n_samples; n++) {
- if (n_legs) {
- const int dir = (random(0, 10) > 5.0) ? -1 : 1; // clockwise or counter clockwise
- float angle = random(0.0, 360.0);
- const float radius = random(
- #if ENABLED(DELTA)
- 0.1250000000 * (DELTA_PRINTABLE_RADIUS),
- 0.3333333333 * (DELTA_PRINTABLE_RADIUS)
- #else
- 5.0, 0.125 * MIN(X_BED_SIZE, Y_BED_SIZE)
- #endif
- );
-
- if (verbose_level > 3) {
- SERIAL_ECHOPAIR("Starting radius: ", radius);
- SERIAL_ECHOPAIR(" angle: ", angle);
- SERIAL_ECHOPGM(" Direction: ");
- if (dir > 0) SERIAL_ECHOPGM("Counter-");
- SERIAL_ECHOLNPGM("Clockwise");
- }
-
- for (uint8_t l = 0; l < n_legs - 1; l++) {
- float delta_angle;
-
- if (schizoid_flag)
- // The points of a 5 point star are 72 degrees apart. We need to
- // skip a point and go to the next one on the star.
- delta_angle = dir * 2.0 * 72.0;
-
- else
- // If we do this line, we are just trying to move further
- // around the circle.
- delta_angle = dir * (float) random(25, 45);
-
- angle += delta_angle;
-
- while (angle > 360.0) // We probably do not need to keep the angle between 0 and 2*PI, but the
- angle -= 360.0; // Arduino documentation says the trig functions should not be given values
- while (angle < 0.0) // outside of this range. It looks like they behave correctly with
- angle += 360.0; // numbers outside of the range, but just to be safe we clamp them.
-
- X_current = X_probe_location - (X_PROBE_OFFSET_FROM_EXTRUDER) + cos(RADIANS(angle)) * radius;
- Y_current = Y_probe_location - (Y_PROBE_OFFSET_FROM_EXTRUDER) + sin(RADIANS(angle)) * radius;
-
- #if DISABLED(DELTA)
- X_current = constrain(X_current, X_MIN_POS, X_MAX_POS);
- Y_current = constrain(Y_current, Y_MIN_POS, Y_MAX_POS);
- #else
- // If we have gone out too far, we can do a simple fix and scale the numbers
- // back in closer to the origin.
- while (!position_is_reachable_by_probe(X_current, Y_current)) {
- X_current *= 0.8;
- Y_current *= 0.8;
- if (verbose_level > 3) {
- SERIAL_ECHOPAIR("Pulling point towards center:", X_current);
- SERIAL_ECHOLNPAIR(", ", Y_current);
- }
- }
- #endif
- if (verbose_level > 3) {
- SERIAL_PROTOCOLPGM("Going to:");
- SERIAL_ECHOPAIR(" X", X_current);
- SERIAL_ECHOPAIR(" Y", Y_current);
- SERIAL_ECHOLNPAIR(" Z", current_position[Z_AXIS]);
- }
- do_blocking_move_to_xy(X_current, Y_current);
- } // n_legs loop
- } // n_legs
-
- // Probe a single point
- sample_set[n] = probe_pt(X_probe_location, Y_probe_location, raise_after);
-
- // Break the loop if the probe fails
- probing_good = !isnan(sample_set[n]);
- if (!probing_good) break;
-
- /**
- * Get the current mean for the data points we have so far
- */
- float sum = 0.0;
- for (uint8_t j = 0; j <= n; j++) sum += sample_set[j];
- mean = sum / (n + 1);
-
- NOMORE(min, sample_set[n]);
- NOLESS(max, sample_set[n]);
-
- /**
- * Now, use that mean to calculate the standard deviation for the
- * data points we have so far
- */
- sum = 0.0;
- for (uint8_t j = 0; j <= n; j++)
- sum += sq(sample_set[j] - mean);
-
- sigma = SQRT(sum / (n + 1));
- if (verbose_level > 0) {
- if (verbose_level > 1) {
- SERIAL_PROTOCOL(n + 1);
- SERIAL_PROTOCOLPGM(" of ");
- SERIAL_PROTOCOL((int)n_samples);
- SERIAL_PROTOCOLPGM(": z: ");
- SERIAL_PROTOCOL_F(sample_set[n], 3);
- if (verbose_level > 2) {
- SERIAL_PROTOCOLPGM(" mean: ");
- SERIAL_PROTOCOL_F(mean, 4);
- SERIAL_PROTOCOLPGM(" sigma: ");
- SERIAL_PROTOCOL_F(sigma, 6);
- SERIAL_PROTOCOLPGM(" min: ");
- SERIAL_PROTOCOL_F(min, 3);
- SERIAL_PROTOCOLPGM(" max: ");
- SERIAL_PROTOCOL_F(max, 3);
- SERIAL_PROTOCOLPGM(" range: ");
- SERIAL_PROTOCOL_F(max-min, 3);
- }
- SERIAL_EOL();
- }
- }
-
- } // n_samples loop
- }
-
- STOW_PROBE();
-
- if (probing_good) {
- SERIAL_PROTOCOLLNPGM("Finished!");
-
- if (verbose_level > 0) {
- SERIAL_PROTOCOLPGM("Mean: ");
- SERIAL_PROTOCOL_F(mean, 6);
- SERIAL_PROTOCOLPGM(" Min: ");
- SERIAL_PROTOCOL_F(min, 3);
- SERIAL_PROTOCOLPGM(" Max: ");
- SERIAL_PROTOCOL_F(max, 3);
- SERIAL_PROTOCOLPGM(" Range: ");
- SERIAL_PROTOCOL_F(max-min, 3);
- SERIAL_EOL();
- }
-
- SERIAL_PROTOCOLPGM("Standard Deviation: ");
- SERIAL_PROTOCOL_F(sigma, 6);
- SERIAL_EOL();
- SERIAL_EOL();
- }
-
- clean_up_after_endstop_or_probe_move();
-
- // Re-enable bed level correction if it had been on
- #if HAS_LEVELING
- set_bed_leveling_enabled(was_enabled);
- #endif
-
- #ifdef Z_AFTER_PROBING
- move_z_after_probing();
- #endif
-
- report_current_position();
- }
-
-#endif // Z_MIN_PROBE_REPEATABILITY_TEST
-
-#if ENABLED(G26_MESH_VALIDATION)
-
- inline void gcode_M49() {
- g26_debug_flag ^= true;
- SERIAL_PROTOCOLPGM("G26 Debug ");
- serialprintPGM(g26_debug_flag ? PSTR("on.\n") : PSTR("off.\n"));
- }
-
-#endif // G26_MESH_VALIDATION
-
-#if ENABLED(ULTRA_LCD) && ENABLED(LCD_SET_PROGRESS_MANUALLY)
- /**
- * M73: Set percentage complete (for display on LCD)
- *
- * Example:
- * M73 P25 ; Set progress to 25%
- *
- * Notes:
- * This has no effect during an SD print job
- */
- inline void gcode_M73() {
- if (!IS_SD_PRINTING && parser.seen('P')) {
- progress_bar_percent = parser.value_byte();
- NOMORE(progress_bar_percent, 100);
- }
- }
-#endif // ULTRA_LCD && LCD_SET_PROGRESS_MANUALLY
-
-/**
- * M75: Start print timer
- */
-inline void gcode_M75() { print_job_timer.start(); }
-
-/**
- * M76: Pause print timer
- */
-inline void gcode_M76() { print_job_timer.pause(); }
-
-/**
- * M77: Stop print timer
- */
-inline void gcode_M77() { print_job_timer.stop(); }
-
-#if ENABLED(PRINTCOUNTER)
- /**
- * M78: Show print statistics
- */
- inline void gcode_M78() {
- // "M78 S78" will reset the statistics
- if (parser.intval('S') == 78)
- print_job_timer.initStats();
- else
- print_job_timer.showStats();
- }
-#endif
-
-/**
- * M104: Set hot end temperature
- */
-inline void gcode_M104() {
- if (get_target_extruder_from_command(104)) return;
- if (DEBUGGING(DRYRUN)) return;
-
- #if ENABLED(SINGLENOZZLE)
- if (target_extruder != active_extruder) return;
- #endif
-
- if (parser.seenval('S')) {
- const int16_t temp = parser.value_celsius();
- thermalManager.setTargetHotend(temp, target_extruder);
-
- #if ENABLED(DUAL_X_CARRIAGE)
- if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && target_extruder == 0)
- thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1);
- #endif
-
- #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
- /**
- * Stop the timer at the end of print. Start is managed by 'heat and wait' M109.
- * We use half EXTRUDE_MINTEMP here to allow nozzles to be put into hot
- * standby mode, for instance in a dual extruder setup, without affecting
- * the running print timer.
- */
- if (parser.value_celsius() <= (EXTRUDE_MINTEMP) / 2) {
- print_job_timer.stop();
- lcd_reset_status();
- }
- #endif
- }
-
- #if ENABLED(AUTOTEMP)
- planner.autotemp_M104_M109();
- #endif
-}
-
-/**
- * M105: Read hot end and bed temperature
- */
-inline void gcode_M105() {
- if (get_target_extruder_from_command(105)) return;
-
- #if HAS_TEMP_SENSOR
- SERIAL_PROTOCOLPGM(MSG_OK);
- thermalManager.print_heaterstates();
- #else // !HAS_TEMP_SENSOR
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_NO_THERMISTORS);
- #endif
-
- SERIAL_EOL();
-}
-
-#if ENABLED(AUTO_REPORT_TEMPERATURES)
-
- /**
- * M155: Set temperature auto-report interval. M155 S
- */
- inline void gcode_M155() {
- if (parser.seenval('S'))
- thermalManager.set_auto_report_interval(parser.value_byte());
- }
-
-#endif // AUTO_REPORT_TEMPERATURES
-
-#if FAN_COUNT > 0
-
- /**
- * M106: Set Fan Speed
- *
- * S Speed between 0-255
- * P Fan index, if more than one fan
- *
- * With EXTRA_FAN_SPEED enabled:
- *
- * T Restore/Use/Set Temporary Speed:
- * 1 = Restore previous speed after T2
- * 2 = Use temporary speed set with T3-255
- * 3-255 = Set the speed for use with T2
- */
- inline void gcode_M106() {
- const uint8_t p = parser.byteval('P');
- if (p < FAN_COUNT) {
- #if ENABLED(EXTRA_FAN_SPEED)
- const int16_t t = parser.intval('T');
- if (t > 0) {
- switch (t) {
- case 1:
- fanSpeeds[p] = old_fanSpeeds[p];
- break;
- case 2:
- old_fanSpeeds[p] = fanSpeeds[p];
- fanSpeeds[p] = new_fanSpeeds[p];
- break;
- default:
- new_fanSpeeds[p] = MIN(t, 255);
- break;
- }
- return;
- }
- #endif // EXTRA_FAN_SPEED
- const uint16_t s = parser.ushortval('S', 255);
- fanSpeeds[p] = MIN(s, 255U);
- }
- }
-
- /**
- * M107: Fan Off
- */
- inline void gcode_M107() {
- const uint16_t p = parser.ushortval('P');
- if (p < FAN_COUNT) fanSpeeds[p] = 0;
- }
-
-#endif // FAN_COUNT > 0
-
-#if DISABLED(EMERGENCY_PARSER)
-
- /**
- * M108: Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature.
- */
- inline void gcode_M108() { wait_for_heatup = false; }
-
-
- /**
- * M112: Emergency Stop
- */
- inline void gcode_M112() { kill(PSTR(MSG_KILLED)); }
-
-
- /**
- * M410: Quickstop - Abort all planned moves
- *
- * This will stop the carriages mid-move, so most likely they
- * will be out of sync with the stepper position after this.
- */
- inline void gcode_M410() { quickstop_stepper(); }
-
-#endif
-
-/**
- * M109: Sxxx Wait for extruder(s) to reach temperature. Waits only when heating.
- * Rxxx Wait for extruder(s) to reach temperature. Waits when heating and cooling.
- */
-
-#ifndef MIN_COOLING_SLOPE_DEG
- #define MIN_COOLING_SLOPE_DEG 1.50
-#endif
-#ifndef MIN_COOLING_SLOPE_TIME
- #define MIN_COOLING_SLOPE_TIME 60
-#endif
-
-inline void gcode_M109() {
-
- if (get_target_extruder_from_command(109)) return;
- if (DEBUGGING(DRYRUN)) return;
-
- #if ENABLED(SINGLENOZZLE)
- if (target_extruder != active_extruder) return;
- #endif
-
- const bool no_wait_for_cooling = parser.seenval('S');
- if (no_wait_for_cooling || parser.seenval('R')) {
- const int16_t temp = parser.value_celsius();
- thermalManager.setTargetHotend(temp, target_extruder);
-
- #if ENABLED(DUAL_X_CARRIAGE)
- if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && target_extruder == 0)
- thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1);
- #endif
-
- #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
- /**
- * Use half EXTRUDE_MINTEMP to allow nozzles to be put into hot
- * standby mode, (e.g., in a dual extruder setup) without affecting
- * the running print timer.
- */
- if (parser.value_celsius() <= (EXTRUDE_MINTEMP) / 2) {
- print_job_timer.stop();
- lcd_reset_status();
- }
- else
- print_job_timer.start();
- #endif
-
- #if ENABLED(ULTRA_LCD)
- const bool heating = thermalManager.isHeatingHotend(target_extruder);
- if (heating || !no_wait_for_cooling)
- #if HOTENDS > 1
- lcd_status_printf_P(0, heating ? PSTR("E%i " MSG_HEATING) : PSTR("E%i " MSG_COOLING), target_extruder + 1);
- #else
- lcd_setstatusPGM(heating ? PSTR("E " MSG_HEATING) : PSTR("E " MSG_COOLING));
- #endif
- #endif
- }
- else return;
-
- #if ENABLED(AUTOTEMP)
- planner.autotemp_M104_M109();
- #endif
-
- #if TEMP_RESIDENCY_TIME > 0
- millis_t residency_start_ms = 0;
- // Loop until the temperature has stabilized
- #define TEMP_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_RESIDENCY_TIME) * 1000UL))
- #else
- // Loop until the temperature is very close target
- #define TEMP_CONDITIONS (wants_to_cool ? thermalManager.isCoolingHotend(target_extruder) : thermalManager.isHeatingHotend(target_extruder))
- #endif
-
- float target_temp = -1, old_temp = 9999;
- bool wants_to_cool = false;
- wait_for_heatup = true;
- millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
-
- #if DISABLED(BUSY_WHILE_HEATING)
- KEEPALIVE_STATE(NOT_BUSY);
- #endif
-
- #if ENABLED(PRINTER_EVENT_LEDS)
- const float start_temp = thermalManager.degHotend(target_extruder);
- uint8_t old_blue = 0;
- #endif
-
- do {
- // Target temperature might be changed during the loop
- if (target_temp != thermalManager.degTargetHotend(target_extruder)) {
- wants_to_cool = thermalManager.isCoolingHotend(target_extruder);
- target_temp = thermalManager.degTargetHotend(target_extruder);
-
- // Exit if S, continue if S, R, or R
- if (no_wait_for_cooling && wants_to_cool) break;
- }
-
- now = millis();
- if (ELAPSED(now, next_temp_ms)) { //Print temp & remaining time every 1s while waiting
- next_temp_ms = now + 1000UL;
- thermalManager.print_heaterstates();
- #if TEMP_RESIDENCY_TIME > 0
- SERIAL_PROTOCOLPGM(" W:");
- if (residency_start_ms)
- SERIAL_PROTOCOL(long((((TEMP_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL));
- else
- SERIAL_PROTOCOLCHAR('?');
- #endif
- SERIAL_EOL();
- }
-
- idle();
- reset_stepper_timeout(); // Keep steppers powered
-
- const float temp = thermalManager.degHotend(target_extruder);
-
- #if ENABLED(PRINTER_EVENT_LEDS)
- // Gradually change LED strip from violet to red as nozzle heats up
- if (!wants_to_cool) {
- const uint8_t blue = map(constrain(temp, start_temp, target_temp), start_temp, target_temp, 255, 0);
- if (blue != old_blue) {
- old_blue = blue;
- leds.set_color(
- MakeLEDColor(255, 0, blue, 0, pixels.getBrightness())
- #if ENABLED(NEOPIXEL_IS_SEQUENTIAL)
- , true
- #endif
- );
- }
- }
- #endif
-
- #if TEMP_RESIDENCY_TIME > 0
-
- const float temp_diff = ABS(target_temp - temp);
-
- if (!residency_start_ms) {
- // Start the TEMP_RESIDENCY_TIME timer when we reach target temp for the first time.
- if (temp_diff < TEMP_WINDOW) residency_start_ms = now;
- }
- else if (temp_diff > TEMP_HYSTERESIS) {
- // Restart the timer whenever the temperature falls outside the hysteresis.
- residency_start_ms = now;
- }
-
- #endif
-
- // Prevent a wait-forever situation if R is misused i.e. M109 R0
- if (wants_to_cool) {
- // break after MIN_COOLING_SLOPE_TIME seconds
- // if the temperature did not drop at least MIN_COOLING_SLOPE_DEG
- if (!next_cool_check_ms || ELAPSED(now, next_cool_check_ms)) {
- if (old_temp - temp < float(MIN_COOLING_SLOPE_DEG)) break;
- next_cool_check_ms = now + 1000UL * MIN_COOLING_SLOPE_TIME;
- old_temp = temp;
- }
- }
-
- } while (wait_for_heatup && TEMP_CONDITIONS);
-
- if (wait_for_heatup) {
- lcd_reset_status();
- #if ENABLED(PRINTER_EVENT_LEDS)
- leds.set_white();
- #endif
- }
-
- #if DISABLED(BUSY_WHILE_HEATING)
- KEEPALIVE_STATE(IN_HANDLER);
- #endif
-}
-
-#if HAS_HEATED_BED
-
- /**
- * M140: Set bed temperature
- */
- inline void gcode_M140() {
- if (DEBUGGING(DRYRUN)) return;
- if (parser.seenval('S')) thermalManager.setTargetBed(parser.value_celsius());
- }
-
- #ifndef MIN_COOLING_SLOPE_DEG_BED
- #define MIN_COOLING_SLOPE_DEG_BED 1.50
- #endif
- #ifndef MIN_COOLING_SLOPE_TIME_BED
- #define MIN_COOLING_SLOPE_TIME_BED 60
- #endif
-
- /**
- * M190: Sxxx Wait for bed current temp to reach target temp. Waits only when heating
- * Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling
- */
- inline void gcode_M190() {
- if (DEBUGGING(DRYRUN)) return;
-
- const bool no_wait_for_cooling = parser.seenval('S');
- if (no_wait_for_cooling || parser.seenval('R')) {
- thermalManager.setTargetBed(parser.value_celsius());
- #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
- if (parser.value_celsius() > BED_MINTEMP)
- print_job_timer.start();
- #endif
- }
- else return;
-
- lcd_setstatusPGM(thermalManager.isHeatingBed() ? PSTR(MSG_BED_HEATING) : PSTR(MSG_BED_COOLING));
-
- #if TEMP_BED_RESIDENCY_TIME > 0
- millis_t residency_start_ms = 0;
- // Loop until the temperature has stabilized
- #define TEMP_BED_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_BED_RESIDENCY_TIME) * 1000UL))
- #else
- // Loop until the temperature is very close target
- #define TEMP_BED_CONDITIONS (wants_to_cool ? thermalManager.isCoolingBed() : thermalManager.isHeatingBed())
- #endif
-
- float target_temp = -1.0, old_temp = 9999.0;
- bool wants_to_cool = false;
- wait_for_heatup = true;
- millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
-
- #if DISABLED(BUSY_WHILE_HEATING)
- KEEPALIVE_STATE(NOT_BUSY);
- #endif
-
- target_extruder = active_extruder; // for print_heaterstates
-
- #if ENABLED(PRINTER_EVENT_LEDS)
- const float start_temp = thermalManager.degBed();
- uint8_t old_red = 127;
- #endif
-
- do {
- // Target temperature might be changed during the loop
- if (target_temp != thermalManager.degTargetBed()) {
- wants_to_cool = thermalManager.isCoolingBed();
- target_temp = thermalManager.degTargetBed();
-
- // Exit if S, continue if S, R, or R
- if (no_wait_for_cooling && wants_to_cool) break;
- }
-
- now = millis();
- if (ELAPSED(now, next_temp_ms)) { //Print Temp Reading every 1 second while heating up.
- next_temp_ms = now + 1000UL;
- thermalManager.print_heaterstates();
- #if TEMP_BED_RESIDENCY_TIME > 0
- SERIAL_PROTOCOLPGM(" W:");
- if (residency_start_ms)
- SERIAL_PROTOCOL(long((((TEMP_BED_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL));
- else
- SERIAL_PROTOCOLCHAR('?');
- #endif
- SERIAL_EOL();
- }
-
- idle();
- reset_stepper_timeout(); // Keep steppers powered
-
- const float temp = thermalManager.degBed();
-
- #if ENABLED(PRINTER_EVENT_LEDS)
- // Gradually change LED strip from blue to violet as bed heats up
- if (!wants_to_cool) {
- const uint8_t red = map(constrain(temp, start_temp, target_temp), start_temp, target_temp, 0, 255);
- if (red != old_red) {
- old_red = red;
- leds.set_color(
- MakeLEDColor(red, 0, 255, 0, pixels.getBrightness())
- #if ENABLED(NEOPIXEL_IS_SEQUENTIAL)
- , true
- #endif
- );
- }
- }
- #endif
-
- #if TEMP_BED_RESIDENCY_TIME > 0
-
- const float temp_diff = ABS(target_temp - temp);
-
- if (!residency_start_ms) {
- // Start the TEMP_BED_RESIDENCY_TIME timer when we reach target temp for the first time.
- if (temp_diff < TEMP_BED_WINDOW) residency_start_ms = now;
- }
- else if (temp_diff > TEMP_BED_HYSTERESIS) {
- // Restart the timer whenever the temperature falls outside the hysteresis.
- residency_start_ms = now;
- }
-
- #endif // TEMP_BED_RESIDENCY_TIME > 0
-
- // Prevent a wait-forever situation if R is misused i.e. M190 R0
- if (wants_to_cool) {
- // Break after MIN_COOLING_SLOPE_TIME_BED seconds
- // if the temperature did not drop at least MIN_COOLING_SLOPE_DEG_BED
- if (!next_cool_check_ms || ELAPSED(now, next_cool_check_ms)) {
- if (old_temp - temp < float(MIN_COOLING_SLOPE_DEG_BED)) break;
- next_cool_check_ms = now + 1000UL * MIN_COOLING_SLOPE_TIME_BED;
- old_temp = temp;
- }
- }
-
- } while (wait_for_heatup && TEMP_BED_CONDITIONS);
-
- if (wait_for_heatup) lcd_reset_status();
- #if DISABLED(BUSY_WHILE_HEATING)
- KEEPALIVE_STATE(IN_HANDLER);
- #endif
- }
-
-#endif // HAS_HEATED_BED
-
-/**
- * M110: Set Current Line Number
- */
-inline void gcode_M110() {
- if (parser.seenval('N')) gcode_LastN = parser.value_long();
-}
-
-/**
- * M111: Set the debug level
- */
-inline void gcode_M111() {
- if (parser.seen('S')) marlin_debug_flags = parser.byteval('S');
-
- static const char str_debug_1[] PROGMEM = MSG_DEBUG_ECHO,
- str_debug_2[] PROGMEM = MSG_DEBUG_INFO,
- str_debug_4[] PROGMEM = MSG_DEBUG_ERRORS,
- str_debug_8[] PROGMEM = MSG_DEBUG_DRYRUN,
- str_debug_16[] PROGMEM = MSG_DEBUG_COMMUNICATION
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- , str_debug_32[] PROGMEM = MSG_DEBUG_LEVELING
- #endif
- ;
-
- static const char* const debug_strings[] PROGMEM = {
- str_debug_1, str_debug_2, str_debug_4, str_debug_8, str_debug_16
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- , str_debug_32
- #endif
- };
-
- SERIAL_ECHO_START();
- SERIAL_ECHOPGM(MSG_DEBUG_PREFIX);
- if (marlin_debug_flags) {
- uint8_t comma = 0;
- for (uint8_t i = 0; i < COUNT(debug_strings); i++) {
- if (TEST(marlin_debug_flags, i)) {
- if (comma++) SERIAL_CHAR(',');
- serialprintPGM((char*)pgm_read_ptr(&debug_strings[i]));
- }
- }
- }
- else {
- SERIAL_ECHOPGM(MSG_DEBUG_OFF);
- #if !defined(__AVR__) || !defined(USBCON)
- #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS)
- SERIAL_ECHOPAIR("\nBuffer Overruns: ", customizedSerial.buffer_overruns());
- #endif
-
- #if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS)
- SERIAL_ECHOPAIR("\nFraming Errors: ", customizedSerial.framing_errors());
- #endif
-
- #if ENABLED(SERIAL_STATS_DROPPED_RX)
- SERIAL_ECHOPAIR("\nDropped bytes: ", customizedSerial.dropped());
- #endif
-
- #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
- SERIAL_ECHOPAIR("\nMax RX Queue Size: ", customizedSerial.rxMaxEnqueued());
- #endif
- #endif // !__AVR__ || !USBCON
- }
- SERIAL_EOL();
-}
-
-#if ENABLED(HOST_KEEPALIVE_FEATURE)
-
- /**
- * M113: Get or set Host Keepalive interval (0 to disable)
- *
- * S Optional. Set the keepalive interval.
- */
- inline void gcode_M113() {
- if (parser.seenval('S')) {
- host_keepalive_interval = parser.value_byte();
- NOMORE(host_keepalive_interval, 60);
- }
- else {
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR("M113 S", (unsigned long)host_keepalive_interval);
- }
- }
-
-#endif
-
-#if ENABLED(BARICUDA)
-
- #if HAS_HEATER_1
- /**
- * M126: Heater 1 valve open
- */
- inline void gcode_M126() { baricuda_valve_pressure = parser.byteval('S', 255); }
- /**
- * M127: Heater 1 valve close
- */
- inline void gcode_M127() { baricuda_valve_pressure = 0; }
- #endif
-
- #if HAS_HEATER_2
- /**
- * M128: Heater 2 valve open
- */
- inline void gcode_M128() { baricuda_e_to_p_pressure = parser.byteval('S', 255); }
- /**
- * M129: Heater 2 valve close
- */
- inline void gcode_M129() { baricuda_e_to_p_pressure = 0; }
- #endif
-
-#endif // BARICUDA
-
-#if ENABLED(ULTIPANEL)
-
- /**
- * M145: Set the heatup state for a material in the LCD menu
- *
- * S (0=PLA, 1=ABS)
- * H
- * B
- * F
- */
- inline void gcode_M145() {
- const uint8_t material = (uint8_t)parser.intval('S');
- if (material >= COUNT(lcd_preheat_hotend_temp)) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_MATERIAL_INDEX);
- }
- else {
- int v;
- if (parser.seenval('H')) {
- v = parser.value_int();
- lcd_preheat_hotend_temp[material] = constrain(v, EXTRUDE_MINTEMP, HEATER_0_MAXTEMP - 15);
- }
- if (parser.seenval('F')) {
- v = parser.value_int();
- lcd_preheat_fan_speed[material] = constrain(v, 0, 255);
- }
- #if TEMP_SENSOR_BED != 0
- if (parser.seenval('B')) {
- v = parser.value_int();
- lcd_preheat_bed_temp[material] = constrain(v, BED_MINTEMP, BED_MAXTEMP - 15);
- }
- #endif
- }
- }
-
-#endif // ULTIPANEL
-
-#if ENABLED(TEMPERATURE_UNITS_SUPPORT)
- /**
- * M149: Set temperature units
- */
- inline void gcode_M149() {
- if (parser.seenval('C')) parser.set_input_temp_units(TEMPUNIT_C);
- else if (parser.seenval('K')) parser.set_input_temp_units(TEMPUNIT_K);
- else if (parser.seenval('F')) parser.set_input_temp_units(TEMPUNIT_F);
- }
-#endif
-
-#if HAS_POWER_SWITCH
-
- /**
- * M80 : Turn on the Power Supply
- * M80 S : Report the current state and exit
- */
- inline void gcode_M80() {
-
- // S: Report the current power supply state and exit
- if (parser.seen('S')) {
- serialprintPGM(powersupply_on ? PSTR("PS:1\n") : PSTR("PS:0\n"));
- return;
- }
-
- PSU_ON();
-
- /**
- * If you have a switch on suicide pin, this is useful
- * if you want to start another print with suicide feature after
- * a print without suicide...
- */
- #if HAS_SUICIDE
- OUT_WRITE(SUICIDE_PIN, HIGH);
- #endif
-
- #if DISABLED(AUTO_POWER_CONTROL)
- delay(100); // Wait for power to settle
- restore_stepper_drivers();
- #endif
-
- #if ENABLED(ULTIPANEL)
- lcd_reset_status();
- #endif
- }
-
-#endif // HAS_POWER_SWITCH
-
-/**
- * M81: Turn off Power, including Power Supply, if there is one.
- *
- * This code should ALWAYS be available for EMERGENCY SHUTDOWN!
- */
-inline void gcode_M81() {
- thermalManager.disable_all_heaters();
- planner.finish_and_disable();
-
- #if FAN_COUNT > 0
- for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0;
- #if ENABLED(PROBING_FANS_OFF)
- fans_paused = false;
- ZERO(paused_fanSpeeds);
- #endif
- #endif
-
- safe_delay(1000); // Wait 1 second before switching off
-
- #if HAS_SUICIDE
- suicide();
- #elif HAS_POWER_SWITCH
- PSU_OFF();
- #endif
-
- #if ENABLED(ULTIPANEL)
- LCD_MESSAGEPGM(MACHINE_NAME " " MSG_OFF ".");
- #endif
-}
-
-/**
- * M82: Set E codes absolute (default)
- */
-inline void gcode_M82() { axis_relative_modes[E_AXIS] = false; }
-
-/**
- * M83: Set E codes relative while in Absolute Coordinates (G90) mode
- */
-inline void gcode_M83() { axis_relative_modes[E_AXIS] = true; }
-
-/**
- * M18, M84: Disable stepper motors
- */
-inline void gcode_M18_M84() {
- if (parser.seenval('S')) {
- stepper_inactive_time = parser.value_millis_from_seconds();
- }
- else {
- bool all_axis = !(parser.seen('X') || parser.seen('Y') || parser.seen('Z') || parser.seen('E'));
- if (all_axis) {
- planner.finish_and_disable();
- }
- else {
- planner.synchronize();
- if (parser.seen('X')) disable_X();
- if (parser.seen('Y')) disable_Y();
- if (parser.seen('Z')) disable_Z();
- #if E0_ENABLE_PIN != X_ENABLE_PIN && E1_ENABLE_PIN != Y_ENABLE_PIN // Only disable on boards that have separate ENABLE_PINS
- if (parser.seen('E')) disable_e_steppers();
- #endif
- }
-
- #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTIPANEL) // Only needed with an LCD
- if (ubl.lcd_map_control) ubl.lcd_map_control = defer_return_to_status = false;
- #endif
- }
-}
-
-/**
- * M85: Set inactivity shutdown timer with parameter S. To disable set zero (default)
- */
-inline void gcode_M85() {
- if (parser.seen('S')) max_inactive_time = parser.value_millis_from_seconds();
-}
-
-/**
- * Multi-stepper support for M92, M201, M203
- */
-#if ENABLED(DISTINCT_E_FACTORS)
- #define GET_TARGET_EXTRUDER(CMD) if (get_target_extruder_from_command(CMD)) return
- #define TARGET_EXTRUDER target_extruder
-#else
- #define GET_TARGET_EXTRUDER(CMD) NOOP
- #define TARGET_EXTRUDER 0
-#endif
-
-/**
- * M92: Set axis steps-per-unit for one or more axes, X, Y, Z, and E.
- * (Follows the same syntax as G92)
- *
- * With multiple extruders use T to specify which one.
- */
-inline void gcode_M92() {
-
- GET_TARGET_EXTRUDER(92);
-
- LOOP_XYZE(i) {
- if (parser.seen(axis_codes[i])) {
- if (i == E_AXIS) {
- const float value = parser.value_per_axis_unit((AxisEnum)(E_AXIS + TARGET_EXTRUDER));
- if (value < 20) {
- float factor = planner.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] / value; // increase e constants if M92 E14 is given for netfab.
- #if DISABLED(JUNCTION_DEVIATION)
- planner.max_jerk[E_AXIS] *= factor;
- #endif
- planner.max_feedrate_mm_s[E_AXIS + TARGET_EXTRUDER] *= factor;
- planner.max_acceleration_steps_per_s2[E_AXIS + TARGET_EXTRUDER] *= factor;
- }
- planner.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] = value;
- }
- else {
- planner.axis_steps_per_mm[i] = parser.value_per_axis_unit((AxisEnum)i);
- }
- }
- }
- planner.refresh_positioning();
-}
-
-/**
- * Output the current position to serial
- */
-void report_current_position() {
- SERIAL_PROTOCOLPGM("X:");
- SERIAL_PROTOCOL(LOGICAL_X_POSITION(current_position[X_AXIS]));
- SERIAL_PROTOCOLPGM(" Y:");
- SERIAL_PROTOCOL(LOGICAL_Y_POSITION(current_position[Y_AXIS]));
- SERIAL_PROTOCOLPGM(" Z:");
- SERIAL_PROTOCOL(LOGICAL_Z_POSITION(current_position[Z_AXIS]));
- SERIAL_PROTOCOLPGM(" E:");
- SERIAL_PROTOCOL(current_position[E_AXIS]);
-
- stepper.report_positions();
-
- #if IS_SCARA
- SERIAL_PROTOCOLPAIR("SCARA Theta:", planner.get_axis_position_degrees(A_AXIS));
- SERIAL_PROTOCOLLNPAIR(" Psi+Theta:", planner.get_axis_position_degrees(B_AXIS));
- SERIAL_EOL();
- #endif
-}
-
-#ifdef M114_DETAIL
-
- void report_xyze(const float pos[], const uint8_t n = 4, const uint8_t precision = 3) {
- char str[12];
- for (uint8_t i = 0; i < n; i++) {
- SERIAL_CHAR(' ');
- SERIAL_CHAR(axis_codes[i]);
- SERIAL_CHAR(':');
- SERIAL_PROTOCOL(dtostrf(pos[i], 8, precision, str));
- }
- SERIAL_EOL();
- }
-
- inline void report_xyz(const float pos[]) { report_xyze(pos, 3); }
-
- void report_current_position_detail() {
-
- SERIAL_PROTOCOLPGM("\nLogical:");
- const float logical[XYZ] = {
- LOGICAL_X_POSITION(current_position[X_AXIS]),
- LOGICAL_Y_POSITION(current_position[Y_AXIS]),
- LOGICAL_Z_POSITION(current_position[Z_AXIS])
- };
- report_xyz(logical);
-
- SERIAL_PROTOCOLPGM("Raw: ");
- report_xyz(current_position);
-
- float leveled[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] };
-
- #if PLANNER_LEVELING
- SERIAL_PROTOCOLPGM("Leveled:");
- planner.apply_leveling(leveled);
- report_xyz(leveled);
-
- SERIAL_PROTOCOLPGM("UnLevel:");
- float unleveled[XYZ] = { leveled[X_AXIS], leveled[Y_AXIS], leveled[Z_AXIS] };
- planner.unapply_leveling(unleveled);
- report_xyz(unleveled);
- #endif
-
- #if IS_KINEMATIC
- #if IS_SCARA
- SERIAL_PROTOCOLPGM("ScaraK: ");
- #else
- SERIAL_PROTOCOLPGM("DeltaK: ");
- #endif
- inverse_kinematics(leveled); // writes delta[]
- report_xyz(delta);
- #endif
-
- planner.synchronize();
-
- SERIAL_PROTOCOLPGM("Stepper:");
- LOOP_XYZE(i) {
- SERIAL_CHAR(' ');
- SERIAL_CHAR(axis_codes[i]);
- SERIAL_CHAR(':');
- SERIAL_PROTOCOL(stepper.position((AxisEnum)i));
- }
- SERIAL_EOL();
-
- #if IS_SCARA
- const float deg[XYZ] = {
- planner.get_axis_position_degrees(A_AXIS),
- planner.get_axis_position_degrees(B_AXIS)
- };
- SERIAL_PROTOCOLPGM("Degrees:");
- report_xyze(deg, 2);
- #endif
-
- SERIAL_PROTOCOLPGM("FromStp:");
- get_cartesian_from_steppers(); // writes cartes[XYZ] (with forward kinematics)
- const float from_steppers[XYZE] = { cartes[X_AXIS], cartes[Y_AXIS], cartes[Z_AXIS], planner.get_axis_position_mm(E_AXIS) };
- report_xyze(from_steppers);
-
- const float diff[XYZE] = {
- from_steppers[X_AXIS] - leveled[X_AXIS],
- from_steppers[Y_AXIS] - leveled[Y_AXIS],
- from_steppers[Z_AXIS] - leveled[Z_AXIS],
- from_steppers[E_AXIS] - current_position[E_AXIS]
- };
- SERIAL_PROTOCOLPGM("Differ: ");
- report_xyze(diff);
- }
-#endif // M114_DETAIL
-
-/**
- * M114: Report current position to host
- */
-inline void gcode_M114() {
-
- #ifdef M114_DETAIL
- if (parser.seen('D')) {
- report_current_position_detail();
- return;
- }
- #endif
-
- planner.synchronize();
- report_current_position();
-}
-
-/**
- * M115: Capabilities string
- */
-
-#if ENABLED(EXTENDED_CAPABILITIES_REPORT)
- static void cap_line(const char * const name, bool ena=false) {
- SERIAL_PROTOCOLPGM("Cap:");
- serialprintPGM(name);
- SERIAL_PROTOCOLPGM(":");
- SERIAL_PROTOCOLLN(int(ena ? 1 : 0));
- }
-#endif
-
-inline void gcode_M115() {
- SERIAL_PROTOCOLLNPGM(MSG_M115_REPORT);
-
- #if ENABLED(EXTENDED_CAPABILITIES_REPORT)
-
- // SERIAL_XON_XOFF
- cap_line(PSTR("SERIAL_XON_XOFF")
- #if ENABLED(SERIAL_XON_XOFF)
- , true
- #endif
- );
-
- // EEPROM (M500, M501)
- cap_line(PSTR("EEPROM")
- #if ENABLED(EEPROM_SETTINGS)
- , true
- #endif
- );
-
- // Volumetric Extrusion (M200)
- cap_line(PSTR("VOLUMETRIC")
- #if DISABLED(NO_VOLUMETRICS)
- , true
- #endif
- );
-
- // AUTOREPORT_TEMP (M155)
- cap_line(PSTR("AUTOREPORT_TEMP")
- #if ENABLED(AUTO_REPORT_TEMPERATURES)
- , true
- #endif
- );
-
- // PROGRESS (M530 S L, M531 , M532 X L)
- cap_line(PSTR("PROGRESS"));
-
- // Print Job timer M75, M76, M77
- cap_line(PSTR("PRINT_JOB"), true);
-
- // AUTOLEVEL (G29)
- cap_line(PSTR("AUTOLEVEL")
- #if HAS_AUTOLEVEL
- , true
- #endif
- );
-
- // Z_PROBE (G30)
- cap_line(PSTR("Z_PROBE")
- #if HAS_BED_PROBE
- , true
- #endif
- );
-
- // MESH_REPORT (M420 V)
- cap_line(PSTR("LEVELING_DATA")
- #if HAS_LEVELING
- , true
- #endif
- );
-
- // BUILD_PERCENT (M73)
- cap_line(PSTR("BUILD_PERCENT")
- #if ENABLED(LCD_SET_PROGRESS_MANUALLY)
- , true
- #endif
- );
-
- // SOFTWARE_POWER (M80, M81)
- cap_line(PSTR("SOFTWARE_POWER")
- #if HAS_POWER_SWITCH
- , true
- #endif
- );
-
- // CASE LIGHTS (M355)
- cap_line(PSTR("TOGGLE_LIGHTS")
- #if HAS_CASE_LIGHT
- , true
- #endif
- );
- cap_line(PSTR("CASE_LIGHT_BRIGHTNESS")
- #if HAS_CASE_LIGHT
- , USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)
- #endif
- );
-
- // EMERGENCY_PARSER (M108, M112, M410)
- cap_line(PSTR("EMERGENCY_PARSER")
- #if ENABLED(EMERGENCY_PARSER)
- , true
- #endif
- );
-
- // AUTOREPORT_SD_STATUS (M27 extension)
- cap_line(PSTR("AUTOREPORT_SD_STATUS")
- #if ENABLED(AUTO_REPORT_SD_STATUS)
- , true
- #endif
- );
-
- // THERMAL_PROTECTION
- cap_line(PSTR("THERMAL_PROTECTION")
- #if ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(THERMAL_PROTECTION_BED)
- , true
- #endif
- );
-
- #endif // EXTENDED_CAPABILITIES_REPORT
-}
-
-/**
- * M117: Set LCD Status Message
- */
-inline void gcode_M117() {
- if (parser.string_arg[0])
- lcd_setstatus(parser.string_arg);
- else
- lcd_reset_status();
-}
-
-/**
- * M118: Display a message in the host console.
- *
- * A1 Prepend '// ' for an action command, as in OctoPrint
- * E1 Have the host 'echo:' the text
- */
-inline void gcode_M118() {
- bool hasE = false, hasA = false;
- char *p = parser.string_arg;
- for (uint8_t i = 2; i--;)
- if ((p[0] == 'A' || p[0] == 'E') && p[1] == '1') {
- if (p[0] == 'A') hasA = true;
- if (p[0] == 'E') hasE = true;
- p += 2;
- while (*p == ' ') ++p;
- }
- if (hasE) SERIAL_ECHO_START();
- if (hasA) SERIAL_ECHOPGM("// ");
- SERIAL_ECHOLN(p);
-}
-
-/**
- * M119: Output endstop states to serial output
- */
-inline void gcode_M119() { endstops.M119(); }
-
-/**
- * M120: Enable endstops and set non-homing endstop state to "enabled"
- */
-inline void gcode_M120() { endstops.enable_globally(true); }
-
-/**
- * M121: Disable endstops and set non-homing endstop state to "disabled"
- */
-inline void gcode_M121() { endstops.enable_globally(false); }
-
-#if ENABLED(PARK_HEAD_ON_PAUSE)
-
- /**
- * M125: Store current position and move to filament change position.
- * Called on pause (by M25) to prevent material leaking onto the
- * object. On resume (M24) the head will be moved back and the
- * print will resume.
- *
- * If Marlin is compiled without SD Card support, M125 can be
- * used directly to pause the print and move to park position,
- * resuming with a button click or M108.
- *
- * L = override retract length
- * X = override X
- * Y = override Y
- * Z = override Z raise
- */
- inline void gcode_M125() {
-
- // Initial retract before move to filament change position
- const float retract = -ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS) : 0
- #ifdef PAUSE_PARK_RETRACT_LENGTH
- + (PAUSE_PARK_RETRACT_LENGTH)
- #endif
- );
-
- point_t park_point = NOZZLE_PARK_POINT;
-
- // Move XY axes to filament change position or given position
- if (parser.seenval('X')) park_point.x = parser.linearval('X');
- if (parser.seenval('Y')) park_point.y = parser.linearval('Y');
-
- // Lift Z axis
- if (parser.seenval('Z')) park_point.z = parser.linearval('Z');
-
- #if HOTENDS > 1 && DISABLED(DUAL_X_CARRIAGE) && DISABLED(DELTA)
- park_point.x += (active_extruder ? hotend_offset[X_AXIS][active_extruder] : 0);
- park_point.y += (active_extruder ? hotend_offset[Y_AXIS][active_extruder] : 0);
- #endif
-
- #if DISABLED(SDSUPPORT)
- const bool job_running = print_job_timer.isRunning();
- #endif
-
- if (pause_print(retract, park_point)) {
- #if DISABLED(SDSUPPORT)
- // Wait for lcd click or M108
- wait_for_filament_reload();
-
- // Return to print position and continue
- resume_print();
-
- if (job_running) print_job_timer.start();
- #endif
- }
- }
-
-#endif // PARK_HEAD_ON_PAUSE
-
-#if HAS_COLOR_LEDS
-
- /**
- * M150: Set Status LED Color - Use R-U-B-W for R-G-B-W
- * and Brightness - Use P (for NEOPIXEL only)
- *
- * Always sets all 3 or 4 components. If a component is left out, set to 0.
- * If brightness is left out, no value changed
- *
- * Examples:
- *
- * M150 R255 ; Turn LED red
- * M150 R255 U127 ; Turn LED orange (PWM only)
- * M150 ; Turn LED off
- * M150 R U B ; Turn LED white
- * M150 W ; Turn LED white using a white LED
- * M150 P127 ; Set LED 50% brightness
- * M150 P ; Set LED full brightness
- */
- inline void gcode_M150() {
- leds.set_color(MakeLEDColor(
- parser.seen('R') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
- parser.seen('U') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
- parser.seen('B') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
- parser.seen('W') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
- parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : pixels.getBrightness()
- ));
- }
-
-#endif // HAS_COLOR_LEDS
-
-#if DISABLED(NO_VOLUMETRICS)
-
- /**
- * M200: Set filament diameter and set E axis units to cubic units
- *
- * T - Optional extruder number. Current extruder if omitted.
- * D - Diameter of the filament. Use "D0" to switch back to linear units on the E axis.
- */
- inline void gcode_M200() {
-
- if (get_target_extruder_from_command(200)) return;
-
- if (parser.seen('D')) {
- // setting any extruder filament size disables volumetric on the assumption that
- // slicers either generate in extruder values as cubic mm or as as filament feeds
- // for all extruders
- if ( (parser.volumetric_enabled = (parser.value_linear_units() != 0)) )
- planner.set_filament_size(target_extruder, parser.value_linear_units());
- }
- planner.calculate_volumetric_multipliers();
- }
-
-#endif // !NO_VOLUMETRICS
-
-/**
- * M201: Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000)
- *
- * With multiple extruders use T to specify which one.
- */
-inline void gcode_M201() {
-
- GET_TARGET_EXTRUDER(201);
-
- LOOP_XYZE(i) {
- if (parser.seen(axis_codes[i])) {
- const uint8_t a = i + (i == E_AXIS ? TARGET_EXTRUDER : 0);
- planner.max_acceleration_mm_per_s2[a] = parser.value_axis_units((AxisEnum)a);
- }
- }
- // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
- planner.reset_acceleration_rates();
-}
-
-#if 0 // Not used for Sprinter/grbl gen6
- inline void gcode_M202() {
- LOOP_XYZE(i) {
- if (parser.seen(axis_codes[i])) axis_travel_steps_per_sqr_second[i] = parser.value_axis_units((AxisEnum)i) * planner.axis_steps_per_mm[i];
- }
- }
-#endif
-
-
-/**
- * M203: Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in units/sec
- *
- * With multiple extruders use T to specify which one.
- */
-inline void gcode_M203() {
-
- GET_TARGET_EXTRUDER(203);
-
- LOOP_XYZE(i)
- if (parser.seen(axis_codes[i])) {
- const uint8_t a = i + (i == E_AXIS ? TARGET_EXTRUDER : 0);
- planner.max_feedrate_mm_s[a] = parser.value_axis_units((AxisEnum)a);
- }
-}
-
-/**
- * M204: Set Accelerations in units/sec^2 (M204 P1200 R3000 T3000)
- *
- * P = Printing moves
- * R = Retract only (no X, Y, Z) moves
- * T = Travel (non printing) moves
- */
-inline void gcode_M204() {
- bool report = true;
- if (parser.seenval('S')) { // Kept for legacy compatibility. Should NOT BE USED for new developments.
- planner.travel_acceleration = planner.acceleration = parser.value_linear_units();
- report = false;
- }
- if (parser.seenval('P')) {
- planner.acceleration = parser.value_linear_units();
- report = false;
- }
- if (parser.seenval('R')) {
- planner.retract_acceleration = parser.value_linear_units();
- report = false;
- }
- if (parser.seenval('T')) {
- planner.travel_acceleration = parser.value_linear_units();
- report = false;
- }
- if (report) {
- SERIAL_ECHOPAIR("Acceleration: P", planner.acceleration);
- SERIAL_ECHOPAIR(" R", planner.retract_acceleration);
- SERIAL_ECHOLNPAIR(" T", planner.travel_acceleration);
- }
-}
-
-/**
- * M205: Set Advanced Settings
- *
- * B = Min Segment Time (µs)
- * S = Min Feed Rate (units/s)
- * T = Min Travel Feed Rate (units/s)
- * X = Max X Jerk (units/sec^2)
- * Y = Max Y Jerk (units/sec^2)
- * Z = Max Z Jerk (units/sec^2)
- * E = Max E Jerk (units/sec^2)
- * J = Junction Deviation (mm) (Requires JUNCTION_DEVIATION)
- */
-inline void gcode_M205() {
- if (parser.seen('B')) planner.min_segment_time_us = parser.value_ulong();
- if (parser.seen('S')) planner.min_feedrate_mm_s = parser.value_linear_units();
- if (parser.seen('T')) planner.min_travel_feedrate_mm_s = parser.value_linear_units();
- #if ENABLED(JUNCTION_DEVIATION)
- if (parser.seen('J')) {
- const float junc_dev = parser.value_linear_units();
- if (WITHIN(junc_dev, 0.01f, 0.3f)) {
- planner.junction_deviation_mm = junc_dev;
- planner.recalculate_max_e_jerk();
- }
- else {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM("?J out of range (0.01 to 0.3)");
- }
- }
- #else
- if (parser.seen('X')) planner.max_jerk[X_AXIS] = parser.value_linear_units();
- if (parser.seen('Y')) planner.max_jerk[Y_AXIS] = parser.value_linear_units();
- if (parser.seen('Z')) {
- planner.max_jerk[Z_AXIS] = parser.value_linear_units();
- #if HAS_MESH
- if (planner.max_jerk[Z_AXIS] <= 0.1f)
- SERIAL_ECHOLNPGM("WARNING! Low Z Jerk may lead to unwanted pauses.");
- #endif
- }
- if (parser.seen('E')) planner.max_jerk[E_AXIS] = parser.value_linear_units();
- #endif
-}
-
-#if HAS_M206_COMMAND
-
- /**
- * M206: Set Additional Homing Offset (X Y Z). SCARA aliases T=X, P=Y
- *
- * *** @thinkyhead: I recommend deprecating M206 for SCARA in favor of M665.
- * *** M206 for SCARA will remain enabled in 1.1.x for compatibility.
- * *** In the next 1.2 release, it will simply be disabled by default.
- */
- inline void gcode_M206() {
- LOOP_XYZ(i)
- if (parser.seen(axis_codes[i]))
- set_home_offset((AxisEnum)i, parser.value_linear_units());
-
- #if ENABLED(MORGAN_SCARA)
- if (parser.seen('T')) set_home_offset(A_AXIS, parser.value_float()); // Theta
- if (parser.seen('P')) set_home_offset(B_AXIS, parser.value_float()); // Psi
- #endif
-
- report_current_position();
- }
-
-#endif // HAS_M206_COMMAND
-
-#if ENABLED(DELTA)
- /**
- * M665: Set delta configurations
- *
- * H = delta height
- * L = diagonal rod
- * R = delta radius
- * S = segments per second
- * B = delta calibration radius
- * X = Alpha (Tower 1) angle trim
- * Y = Beta (Tower 2) angle trim
- * Z = Gamma (Tower 3) angle trim
- */
- inline void gcode_M665() {
- if (parser.seen('H')) delta_height = parser.value_linear_units();
- if (parser.seen('L')) delta_diagonal_rod = parser.value_linear_units();
- if (parser.seen('R')) delta_radius = parser.value_linear_units();
- if (parser.seen('S')) delta_segments_per_second = parser.value_float();
- if (parser.seen('B')) delta_calibration_radius = parser.value_float();
- if (parser.seen('X')) delta_tower_angle_trim[A_AXIS] = parser.value_float();
- if (parser.seen('Y')) delta_tower_angle_trim[B_AXIS] = parser.value_float();
- if (parser.seen('Z')) delta_tower_angle_trim[C_AXIS] = parser.value_float();
- recalc_delta_settings();
- }
- /**
- * M666: Set delta endstop adjustment
- */
- inline void gcode_M666() {
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) {
- SERIAL_ECHOLNPGM(">>> gcode_M666");
- }
- #endif
- LOOP_XYZ(i) {
- if (parser.seen(axis_codes[i])) {
- if (parser.value_linear_units() * Z_HOME_DIR <= 0)
- delta_endstop_adj[i] = parser.value_linear_units();
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) {
- SERIAL_ECHOPAIR("delta_endstop_adj[", axis_codes[i]);
- SERIAL_ECHOLNPAIR("] = ", delta_endstop_adj[i]);
- }
- #endif
- }
- }
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) {
- SERIAL_ECHOLNPGM("<<< gcode_M666");
- }
- #endif
- }
-
-#elif IS_SCARA
-
- /**
- * M665: Set SCARA settings
- *
- * Parameters:
- *
- * S[segments-per-second] - Segments-per-second
- * P[theta-psi-offset] - Theta-Psi offset, added to the shoulder (A/X) angle
- * T[theta-offset] - Theta offset, added to the elbow (B/Y) angle
- *
- * A, P, and X are all aliases for the shoulder angle
- * B, T, and Y are all aliases for the elbow angle
- */
- inline void gcode_M665() {
- if (parser.seen('S')) delta_segments_per_second = parser.value_float();
-
- const bool hasA = parser.seen('A'), hasP = parser.seen('P'), hasX = parser.seen('X');
- const uint8_t sumAPX = hasA + hasP + hasX;
- if (sumAPX == 1)
- home_offset[A_AXIS] = parser.value_float();
- else if (sumAPX > 1) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM("Only one of A, P, or X is allowed.");
- return;
- }
-
- const bool hasB = parser.seen('B'), hasT = parser.seen('T'), hasY = parser.seen('Y');
- const uint8_t sumBTY = hasB + hasT + hasY;
- if (sumBTY == 1)
- home_offset[B_AXIS] = parser.value_float();
- else if (sumBTY > 1) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM("Only one of B, T, or Y is allowed.");
- return;
- }
- }
-
-#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
-
- /**
- * M666: Set Dual Endstops offsets for X, Y, and/or Z.
- * With no parameters report current offsets.
- */
- inline void gcode_M666() {
- bool report = true;
- #if ENABLED(X_DUAL_ENDSTOPS)
- if (parser.seenval('X')) {
- endstops.x_endstop_adj = parser.value_linear_units();
- report = false;
- }
- #endif
- #if ENABLED(Y_DUAL_ENDSTOPS)
- if (parser.seenval('Y')) {
- endstops.y_endstop_adj = parser.value_linear_units();
- report = false;
- }
- #endif
- #if ENABLED(Z_DUAL_ENDSTOPS)
- if (parser.seenval('Z')) {
- endstops.z_endstop_adj = parser.value_linear_units();
- report = false;
- }
- #endif
- if (report) {
- SERIAL_ECHOPGM("Dual Endstop Adjustment (mm): ");
- #if ENABLED(X_DUAL_ENDSTOPS)
- SERIAL_ECHOPAIR(" X", endstops.x_endstop_adj);
- #endif
- #if ENABLED(Y_DUAL_ENDSTOPS)
- SERIAL_ECHOPAIR(" Y", endstops.y_endstop_adj);
- #endif
- #if ENABLED(Z_DUAL_ENDSTOPS)
- SERIAL_ECHOPAIR(" Z", endstops.z_endstop_adj);
- #endif
- SERIAL_EOL();
- }
- }
-
-#endif // X_DUAL_ENDSTOPS || Y_DUAL_ENDSTOPS || Z_DUAL_ENDSTOPS
-
-#if ENABLED(FWRETRACT)
-
- /**
- * M207: Set firmware retraction values
- *
- * S[+units] retract_length
- * W[+units] swap_retract_length (multi-extruder)
- * F[units/min] retract_feedrate_mm_s
- * Z[units] retract_zlift
- */
- inline void gcode_M207() {
- if (parser.seen('S')) fwretract.retract_length = parser.value_axis_units(E_AXIS);
- if (parser.seen('F')) fwretract.retract_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
- if (parser.seen('Z')) fwretract.retract_zlift = parser.value_linear_units();
- if (parser.seen('W')) fwretract.swap_retract_length = parser.value_axis_units(E_AXIS);
- }
-
- /**
- * M208: Set firmware un-retraction values
- *
- * S[+units] retract_recover_length (in addition to M207 S*)
- * W[+units] swap_retract_recover_length (multi-extruder)
- * F[units/min] retract_recover_feedrate_mm_s
- * R[units/min] swap_retract_recover_feedrate_mm_s
- */
- inline void gcode_M208() {
- if (parser.seen('S')) fwretract.retract_recover_length = parser.value_axis_units(E_AXIS);
- if (parser.seen('F')) fwretract.retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
- if (parser.seen('R')) fwretract.swap_retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
- if (parser.seen('W')) fwretract.swap_retract_recover_length = parser.value_axis_units(E_AXIS);
- }
-
- /**
- * M209: Enable automatic retract (M209 S1)
- * For slicers that don't support G10/11, reversed extrude-only
- * moves will be classified as retraction.
- */
- inline void gcode_M209() {
- if (MIN_AUTORETRACT <= MAX_AUTORETRACT) {
- if (parser.seen('S')) {
- fwretract.autoretract_enabled = parser.value_bool();
- for (uint8_t i = 0; i < EXTRUDERS; i++) fwretract.retracted[i] = false;
- }
- }
- }
-
-#endif // FWRETRACT
-
-/**
- * M211: Enable, Disable, and/or Report software endstops
- *
- * Usage: M211 S1 to enable, M211 S0 to disable, M211 alone for report
- */
-inline void gcode_M211() {
- SERIAL_ECHO_START();
- #if HAS_SOFTWARE_ENDSTOPS
- if (parser.seen('S')) soft_endstops_enabled = parser.value_bool();
- SERIAL_ECHOPGM(MSG_SOFT_ENDSTOPS);
- serialprintPGM(soft_endstops_enabled ? PSTR(MSG_ON) : PSTR(MSG_OFF));
- #else
- SERIAL_ECHOPGM(MSG_SOFT_ENDSTOPS);
- SERIAL_ECHOPGM(MSG_OFF);
- #endif
- SERIAL_ECHOPGM(MSG_SOFT_MIN);
- SERIAL_ECHOPAIR( MSG_X, LOGICAL_X_POSITION(soft_endstop_min[X_AXIS]));
- SERIAL_ECHOPAIR(" " MSG_Y, LOGICAL_Y_POSITION(soft_endstop_min[Y_AXIS]));
- SERIAL_ECHOPAIR(" " MSG_Z, LOGICAL_Z_POSITION(soft_endstop_min[Z_AXIS]));
- SERIAL_ECHOPGM(MSG_SOFT_MAX);
- SERIAL_ECHOPAIR( MSG_X, LOGICAL_X_POSITION(soft_endstop_max[X_AXIS]));
- SERIAL_ECHOPAIR(" " MSG_Y, LOGICAL_Y_POSITION(soft_endstop_max[Y_AXIS]));
- SERIAL_ECHOLNPAIR(" " MSG_Z, LOGICAL_Z_POSITION(soft_endstop_max[Z_AXIS]));
-}
-
-#if HOTENDS > 1
-
- /**
- * M218 - Set/get hotend offset (in linear units)
- *
- * T
- * X
- * Y
- * Z - Available with DUAL_X_CARRIAGE, SWITCHING_NOZZLE, and PARKING_EXTRUDER
- */
- inline void gcode_M218() {
- if (get_target_extruder_from_command(218) || target_extruder == 0) return;
-
- bool report = true;
- if (parser.seenval('X')) {
- hotend_offset[X_AXIS][target_extruder] = parser.value_linear_units();
- report = false;
- }
- if (parser.seenval('Y')) {
- hotend_offset[Y_AXIS][target_extruder] = parser.value_linear_units();
- report = false;
- }
-
- #if HAS_HOTEND_OFFSET_Z
- if (parser.seenval('Z')) {
- hotend_offset[Z_AXIS][target_extruder] = parser.value_linear_units();
- report = false;
- }
- #endif
-
- if (report) {
- SERIAL_ECHO_START();
- SERIAL_ECHOPGM(MSG_HOTEND_OFFSET);
- HOTEND_LOOP() {
- SERIAL_CHAR(' ');
- SERIAL_ECHO(hotend_offset[X_AXIS][e]);
- SERIAL_CHAR(',');
- SERIAL_ECHO(hotend_offset[Y_AXIS][e]);
- #if HAS_HOTEND_OFFSET_Z
- SERIAL_CHAR(',');
- SERIAL_ECHO(hotend_offset[Z_AXIS][e]);
- #endif
- }
- SERIAL_EOL();
- }
-
- #if ENABLED(DELTA)
- if (target_extruder == active_extruder)
- do_blocking_move_to_xy(current_position[X_AXIS], current_position[Y_AXIS], planner.max_feedrate_mm_s[X_AXIS]);
- #endif
- }
-
-#endif // HOTENDS > 1
-
-/**
- * M220: Set speed percentage factor, aka "Feed Rate" (M220 S95)
- */
-inline void gcode_M220() {
- if (parser.seenval('S')) feedrate_percentage = parser.value_int();
-}
-
-/**
- * M221: Set extrusion percentage (M221 T0 S95)
- */
-inline void gcode_M221() {
- if (get_target_extruder_from_command(221)) return;
- if (parser.seenval('S')) {
- planner.flow_percentage[target_extruder] = parser.value_int();
- planner.refresh_e_factor(target_extruder);
- }
- else {
- SERIAL_ECHO_START();
- SERIAL_CHAR('E');
- SERIAL_CHAR('0' + target_extruder);
- SERIAL_ECHOPAIR(" Flow: ", planner.flow_percentage[target_extruder]);
- SERIAL_CHAR('%');
- SERIAL_EOL();
- }
-}
-
-/**
- * M226: Wait until the specified pin reaches the state required (M226 P S)
- */
-inline void gcode_M226() {
- if (parser.seen('P')) {
- const int pin = parser.value_int(), pin_state = parser.intval('S', -1);
- if (WITHIN(pin_state, -1, 1) && pin > -1) {
- if (pin_is_protected(pin))
- protected_pin_err();
- else {
- int target = LOW;
- planner.synchronize();
- pinMode(pin, INPUT);
- switch (pin_state) {
- case 1: target = HIGH; break;
- case 0: target = LOW; break;
- case -1: target = !digitalRead(pin); break;
- }
- while (digitalRead(pin) != target) idle();
- }
- } // pin_state -1 0 1 && pin > -1
- } // parser.seen('P')
-}
-
-#if ENABLED(EXPERIMENTAL_I2CBUS)
-
- /**
- * M260: Send data to a I2C slave device
- *
- * This is a PoC, the formating and arguments for the GCODE will
- * change to be more compatible, the current proposal is:
- *
- * M260 A ; Sets the I2C slave address the data will be sent to
- *
- * M260 B
- * M260 B
- * M260 B
- *
- * M260 S1 ; Send the buffered data and reset the buffer
- * M260 R1 ; Reset the buffer without sending data
- *
- */
- inline void gcode_M260() {
- // Set the target address
- if (parser.seen('A')) i2c.address(parser.value_byte());
-
- // Add a new byte to the buffer
- if (parser.seen('B')) i2c.addbyte(parser.value_byte());
-
- // Flush the buffer to the bus
- if (parser.seen('S')) i2c.send();
-
- // Reset and rewind the buffer
- else if (parser.seen('R')) i2c.reset();
- }
-
- /**
- * M261: Request X bytes from I2C slave device
- *
- * Usage: M261 A B
- */
- inline void gcode_M261() {
- if (parser.seen('A')) i2c.address(parser.value_byte());
-
- uint8_t bytes = parser.byteval('B', 1);
-
- if (i2c.addr && bytes && bytes <= TWIBUS_BUFFER_SIZE) {
- i2c.relay(bytes);
- }
- else {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM("Bad i2c request");
- }
- }
-
-#endif // EXPERIMENTAL_I2CBUS
-
-#if HAS_SERVOS
-
- /**
- * M280: Get or set servo position. P [S]
- */
- inline void gcode_M280() {
- if (!parser.seen('P')) return;
- const int servo_index = parser.value_int();
- if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) {
- if (parser.seen('S'))
- MOVE_SERVO(servo_index, parser.value_int());
- else {
- SERIAL_ECHO_START();
- SERIAL_ECHOPAIR(" Servo ", servo_index);
- SERIAL_ECHOLNPAIR(": ", servo[servo_index].read());
- }
- }
- else {
- SERIAL_ERROR_START();
- SERIAL_ECHOPAIR("Servo ", servo_index);
- SERIAL_ECHOLNPGM(" out of range");
- }
- }
-
-#endif // HAS_SERVOS
-
-#if ENABLED(BABYSTEPPING)
-
- #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
- FORCE_INLINE void mod_zprobe_zoffset(const float &offs) {
- zprobe_zoffset += offs;
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR(MSG_PROBE_Z_OFFSET ": ", zprobe_zoffset);
- }
- #endif
-
- /**
- * M290: Babystepping
- */
- inline void gcode_M290() {
- #if ENABLED(BABYSTEP_XY)
- for (uint8_t a = X_AXIS; a <= Z_AXIS; a++)
- if (parser.seenval(axis_codes[a]) || (a == Z_AXIS && parser.seenval('S'))) {
- const float offs = constrain(parser.value_axis_units((AxisEnum)a), -2, 2);
- thermalManager.babystep_axis((AxisEnum)a, offs * planner.axis_steps_per_mm[a]);
- #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
- if (a == Z_AXIS && (!parser.seen('P') || parser.value_bool())) mod_zprobe_zoffset(offs);
- #endif
- }
- #else
- if (parser.seenval('Z') || parser.seenval('S')) {
- const float offs = constrain(parser.value_axis_units(Z_AXIS), -2, 2);
- thermalManager.babystep_axis(Z_AXIS, offs * planner.axis_steps_per_mm[Z_AXIS]);
- #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
- if (!parser.seen('P') || parser.value_bool()) mod_zprobe_zoffset(offs);
- #endif
- }
- #endif
- }
-
-#endif // BABYSTEPPING
-
-#if HAS_BUZZER
-
- /**
- * M300: Play beep sound S P
- */
- inline void gcode_M300() {
- uint16_t const frequency = parser.ushortval('S', 260);
- uint16_t duration = parser.ushortval('P', 1000);
-
- // Limits the tone duration to 0-5 seconds.
- NOMORE(duration, 5000);
-
- BUZZ(duration, frequency);
- }
-
-#endif // HAS_BUZZER
-
-#if ENABLED(PIDTEMP)
-
- /**
- * M301: Set PID parameters P I D (and optionally C, L)
- *
- * P[float] Kp term
- * I[float] Ki term (unscaled)
- * D[float] Kd term (unscaled)
- *
- * With PID_EXTRUSION_SCALING:
- *
- * C[float] Kc term
- * L[int] LPQ length
- */
- inline void gcode_M301() {
-
- // multi-extruder PID patch: M301 updates or prints a single extruder's PID values
- // default behaviour (omitting E parameter) is to update for extruder 0 only
- const uint8_t e = parser.byteval('E'); // extruder being updated
-
- if (e < HOTENDS) { // catch bad input value
- if (parser.seen('P')) PID_PARAM(Kp, e) = parser.value_float();
- if (parser.seen('I')) PID_PARAM(Ki, e) = scalePID_i(parser.value_float());
- if (parser.seen('D')) PID_PARAM(Kd, e) = scalePID_d(parser.value_float());
- #if ENABLED(PID_EXTRUSION_SCALING)
- if (parser.seen('C')) PID_PARAM(Kc, e) = parser.value_float();
- if (parser.seen('L')) thermalManager.lpq_len = parser.value_float();
- NOMORE(thermalManager.lpq_len, LPQ_MAX_LEN);
- NOLESS(thermalManager.lpq_len, 0);
- #endif
-
- thermalManager.updatePID();
- SERIAL_ECHO_START();
- #if ENABLED(PID_PARAMS_PER_HOTEND)
- SERIAL_ECHOPAIR(" e:", e); // specify extruder in serial output
- #endif // PID_PARAMS_PER_HOTEND
- SERIAL_ECHOPAIR(" p:", PID_PARAM(Kp, e));
- SERIAL_ECHOPAIR(" i:", unscalePID_i(PID_PARAM(Ki, e)));
- SERIAL_ECHOPAIR(" d:", unscalePID_d(PID_PARAM(Kd, e)));
- #if ENABLED(PID_EXTRUSION_SCALING)
- //Kc does not have scaling applied above, or in resetting defaults
- SERIAL_ECHOPAIR(" c:", PID_PARAM(Kc, e));
- #endif
- SERIAL_EOL();
- }
- else {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_INVALID_EXTRUDER);
- }
- }
-
-#endif // PIDTEMP
-
-#if ENABLED(PIDTEMPBED)
-
- inline void gcode_M304() {
- if (parser.seen('P')) thermalManager.bedKp = parser.value_float();
- if (parser.seen('I')) thermalManager.bedKi = scalePID_i(parser.value_float());
- if (parser.seen('D')) thermalManager.bedKd = scalePID_d(parser.value_float());
-
- SERIAL_ECHO_START();
- SERIAL_ECHOPAIR(" p:", thermalManager.bedKp);
- SERIAL_ECHOPAIR(" i:", unscalePID_i(thermalManager.bedKi));
- SERIAL_ECHOLNPAIR(" d:", unscalePID_d(thermalManager.bedKd));
- }
-
-#endif // PIDTEMPBED
-
-#if defined(CHDK) || HAS_PHOTOGRAPH
-
- /**
- * M240: Trigger a camera by emulating a Canon RC-1
- * See http://www.doc-diy.net/photo/rc-1_hacked/
- */
- inline void gcode_M240() {
- #ifdef CHDK
-
- OUT_WRITE(CHDK, HIGH);
- chdkHigh = millis();
- chdkActive = true;
-
- #elif HAS_PHOTOGRAPH
-
- const uint8_t NUM_PULSES = 16;
- const float PULSE_LENGTH = 0.01524;
- for (int i = 0; i < NUM_PULSES; i++) {
- WRITE(PHOTOGRAPH_PIN, HIGH);
- _delay_ms(PULSE_LENGTH);
- WRITE(PHOTOGRAPH_PIN, LOW);
- _delay_ms(PULSE_LENGTH);
- }
- delay(7.33);
- for (int i = 0; i < NUM_PULSES; i++) {
- WRITE(PHOTOGRAPH_PIN, HIGH);
- _delay_ms(PULSE_LENGTH);
- WRITE(PHOTOGRAPH_PIN, LOW);
- _delay_ms(PULSE_LENGTH);
- }
-
- #endif // !CHDK && HAS_PHOTOGRAPH
- }
-
-#endif // CHDK || PHOTOGRAPH_PIN
-
-#if HAS_LCD_CONTRAST
-
- /**
- * M250: Read and optionally set the LCD contrast
- */
- inline void gcode_M250() {
- if (parser.seen('C')) set_lcd_contrast(parser.value_int());
- SERIAL_PROTOCOLPGM("lcd contrast value: ");
- SERIAL_PROTOCOL(lcd_contrast);
- SERIAL_EOL();
- }
-
-#endif // HAS_LCD_CONTRAST
-
-#if ENABLED(PREVENT_COLD_EXTRUSION)
-
- /**
- * M302: Allow cold extrudes, or set the minimum extrude temperature
- *
- * S sets the minimum extrude temperature
- * P enables (1) or disables (0) cold extrusion
- *
- * Examples:
- *
- * M302 ; report current cold extrusion state
- * M302 P0 ; enable cold extrusion checking
- * M302 P1 ; disables cold extrusion checking
- * M302 S0 ; always allow extrusion (disables checking)
- * M302 S170 ; only allow extrusion above 170
- * M302 S170 P1 ; set min extrude temp to 170 but leave disabled
- */
- inline void gcode_M302() {
- const bool seen_S = parser.seen('S');
- if (seen_S) {
- thermalManager.extrude_min_temp = parser.value_celsius();
- thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0);
- }
-
- if (parser.seen('P'))
- thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0) || parser.value_bool();
- else if (!seen_S) {
- // Report current state
- SERIAL_ECHO_START();
- SERIAL_ECHOPAIR("Cold extrudes are ", (thermalManager.allow_cold_extrude ? "en" : "dis"));
- SERIAL_ECHOPAIR("abled (min temp ", thermalManager.extrude_min_temp);
- SERIAL_ECHOLNPGM("C)");
- }
- }
-
-#endif // PREVENT_COLD_EXTRUSION
-
-/**
- * M303: PID relay autotune
- *
- * S sets the target temperature. (default 150C / 70C)
- * E (-1 for the bed) (default 0)
- * C
- * U with a non-zero value will apply the result to current settings
- */
-inline void gcode_M303() {
- #if HAS_PID_HEATING
- const int e = parser.intval('E'), c = parser.intval('C', 5);
- const bool u = parser.boolval('U');
-
- int16_t temp = parser.celsiusval('S', e < 0 ? 70 : 150);
-
- if (WITHIN(e, 0, HOTENDS - 1))
- target_extruder = e;
-
- #if DISABLED(BUSY_WHILE_HEATING)
- KEEPALIVE_STATE(NOT_BUSY);
- #endif
-
- thermalManager.PID_autotune(temp, e, c, u);
-
- #if DISABLED(BUSY_WHILE_HEATING)
- KEEPALIVE_STATE(IN_HANDLER);
- #endif
- #else
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_M303_DISABLED);
- #endif
-}
-
-#if ENABLED(MORGAN_SCARA)
-
- bool SCARA_move_to_cal(const uint8_t delta_a, const uint8_t delta_b) {
- if (IsRunning()) {
- forward_kinematics_SCARA(delta_a, delta_b);
- destination[X_AXIS] = cartes[X_AXIS];
- destination[Y_AXIS] = cartes[Y_AXIS];
- destination[Z_AXIS] = current_position[Z_AXIS];
- prepare_move_to_destination();
- return true;
- }
- return false;
- }
-
- /**
- * M360: SCARA calibration: Move to cal-position ThetaA (0 deg calibration)
- */
- inline bool gcode_M360() {
- SERIAL_ECHOLNPGM(" Cal: Theta 0");
- return SCARA_move_to_cal(0, 120);
- }
-
- /**
- * M361: SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree)
- */
- inline bool gcode_M361() {
- SERIAL_ECHOLNPGM(" Cal: Theta 90");
- return SCARA_move_to_cal(90, 130);
- }
-
- /**
- * M362: SCARA calibration: Move to cal-position PsiA (0 deg calibration)
- */
- inline bool gcode_M362() {
- SERIAL_ECHOLNPGM(" Cal: Psi 0");
- return SCARA_move_to_cal(60, 180);
- }
-
- /**
- * M363: SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree)
- */
- inline bool gcode_M363() {
- SERIAL_ECHOLNPGM(" Cal: Psi 90");
- return SCARA_move_to_cal(50, 90);
- }
-
- /**
- * M364: SCARA calibration: Move to cal-position PsiC (90 deg to Theta calibration position)
- */
- inline bool gcode_M364() {
- SERIAL_ECHOLNPGM(" Cal: Theta-Psi 90");
- return SCARA_move_to_cal(45, 135);
- }
-
-#endif // SCARA
-
-#if ENABLED(EXT_SOLENOID)
-
- void enable_solenoid(const uint8_t num) {
- switch (num) {
- case 0:
- OUT_WRITE(SOL0_PIN, HIGH);
- break;
- #if HAS_SOLENOID_1 && EXTRUDERS > 1
- case 1:
- OUT_WRITE(SOL1_PIN, HIGH);
- break;
- #endif
- #if HAS_SOLENOID_2 && EXTRUDERS > 2
- case 2:
- OUT_WRITE(SOL2_PIN, HIGH);
- break;
- #endif
- #if HAS_SOLENOID_3 && EXTRUDERS > 3
- case 3:
- OUT_WRITE(SOL3_PIN, HIGH);
- break;
- #endif
- #if HAS_SOLENOID_4 && EXTRUDERS > 4
- case 4:
- OUT_WRITE(SOL4_PIN, HIGH);
- break;
- #endif
- default:
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPGM(MSG_INVALID_SOLENOID);
- break;
- }
- }
-
- void enable_solenoid_on_active_extruder() { enable_solenoid(active_extruder); }
-
- void disable_all_solenoids() {
- OUT_WRITE(SOL0_PIN, LOW);
- #if HAS_SOLENOID_1 && EXTRUDERS > 1
- OUT_WRITE(SOL1_PIN, LOW);
- #endif
- #if HAS_SOLENOID_2 && EXTRUDERS > 2
- OUT_WRITE(SOL2_PIN, LOW);
- #endif
- #if HAS_SOLENOID_3 && EXTRUDERS > 3
- OUT_WRITE(SOL3_PIN, LOW);
- #endif
- #if HAS_SOLENOID_4 && EXTRUDERS > 4
- OUT_WRITE(SOL4_PIN, LOW);
- #endif
- }
-
- /**
- * M380: Enable solenoid on the active extruder
- */
- inline void gcode_M380() { enable_solenoid_on_active_extruder(); }
-
- /**
- * M381: Disable all solenoids
- */
- inline void gcode_M381() { disable_all_solenoids(); }
-
-#endif // EXT_SOLENOID
-
-/**
- * M400: Finish all moves
- */
-inline void gcode_M400() { planner.synchronize(); }
-
-#if HAS_BED_PROBE
-
- /**
- * M401: Deploy and activate the Z probe
- */
- inline void gcode_M401() {
- DEPLOY_PROBE();
- report_current_position();
- }
-
- /**
- * M402: Deactivate and stow the Z probe
- */
- inline void gcode_M402() {
- STOW_PROBE();
- #ifdef Z_AFTER_PROBING
- move_z_after_probing();
- #endif
- report_current_position();
- }
-
-#endif // HAS_BED_PROBE
-
-#if ENABLED(FILAMENT_WIDTH_SENSOR)
-
- /**
- * M404: Display or set (in current units) the nominal filament width (3mm, 1.75mm ) W<3.0>
- */
- inline void gcode_M404() {
- if (parser.seen('W')) {
- filament_width_nominal = parser.value_linear_units();
- planner.volumetric_area_nominal = CIRCLE_AREA(filament_width_nominal * 0.5);
- }
- else {
- SERIAL_PROTOCOLPGM("Filament dia (nominal mm):");
- SERIAL_PROTOCOLLN(filament_width_nominal);
- }
- }
-
- /**
- * M405: Turn on filament sensor for control
- */
- inline void gcode_M405() {
- // This is technically a linear measurement, but since it's quantized to centimeters and is a different
- // unit than everything else, it uses parser.value_byte() instead of parser.value_linear_units().
- if (parser.seen('D')) {
- meas_delay_cm = parser.value_byte();
- NOMORE(meas_delay_cm, MAX_MEASUREMENT_DELAY);
- }
-
- if (filwidth_delay_index[1] == -1) { // Initialize the ring buffer if not done since startup
- const int8_t temp_ratio = thermalManager.widthFil_to_size_ratio();
-
- for (uint8_t i = 0; i < COUNT(measurement_delay); ++i)
- measurement_delay[i] = temp_ratio;
-
- filwidth_delay_index[0] = filwidth_delay_index[1] = 0;
- }
-
- filament_sensor = true;
- }
-
- /**
- * M406: Turn off filament sensor for control
- */
- inline void gcode_M406() {
- filament_sensor = false;
- planner.calculate_volumetric_multipliers(); // Restore correct 'volumetric_multiplier' value
- }
-
- /**
- * M407: Get measured filament diameter on serial output
- */
- inline void gcode_M407() {
- SERIAL_PROTOCOLPGM("Filament dia (measured mm):");
- SERIAL_PROTOCOLLN(filament_width_meas);
- }
-
-#endif // FILAMENT_WIDTH_SENSOR
-
-void quickstop_stepper() {
- planner.quick_stop();
- planner.synchronize();
- set_current_from_steppers_for_axis(ALL_AXES);
- SYNC_PLAN_POSITION_KINEMATIC();
-}
-
-#if HAS_LEVELING
-
- //#define M420_C_USE_MEAN
-
- /**
- * M420: Enable/Disable Bed Leveling and/or set the Z fade height.
- *
- * S[bool] Turns leveling on or off
- * Z[height] Sets the Z fade height (0 or none to disable)
- * V[bool] Verbose - Print the leveling grid
- *
- * With AUTO_BED_LEVELING_UBL only:
- *
- * L[index] Load UBL mesh from index (0 is default)
- * T[map] 0:Human-readable 1:CSV 2:"LCD" 4:Compact
- *
- * With mesh-based leveling only:
- *
- * C Center mesh on the mean of the lowest and highest
- */
- inline void gcode_M420() {
- const bool seen_S = parser.seen('S');
- bool to_enable = seen_S ? parser.value_bool() : planner.leveling_active;
-
- // If disabling leveling do it right away
- // (Don't disable for just M420 or M420 V)
- if (seen_S && !to_enable) set_bed_leveling_enabled(false);
-
- const float oldpos[] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] };
-
- #if ENABLED(AUTO_BED_LEVELING_UBL)
-
- // L to load a mesh from the EEPROM
- if (parser.seen('L')) {
-
- set_bed_leveling_enabled(false);
-
- #if ENABLED(EEPROM_SETTINGS)
- const int8_t storage_slot = parser.has_value() ? parser.value_int() : ubl.storage_slot;
- const int16_t a = settings.calc_num_meshes();
-
- if (!a) {
- SERIAL_PROTOCOLLNPGM("?EEPROM storage not available.");
- return;
- }
-
- if (!WITHIN(storage_slot, 0, a - 1)) {
- SERIAL_PROTOCOLLNPGM("?Invalid storage slot.");
- SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1);
- return;
- }
-
- settings.load_mesh(storage_slot);
- ubl.storage_slot = storage_slot;
-
- #else
-
- SERIAL_PROTOCOLLNPGM("?EEPROM storage not available.");
- return;
-
- #endif
- }
-
- // L or V display the map info
- if (parser.seen('L') || parser.seen('V')) {
- ubl.display_map(parser.byteval('T'));
- SERIAL_ECHOPGM("Mesh is ");
- if (!ubl.mesh_is_valid()) SERIAL_ECHOPGM("in");
- SERIAL_ECHOLNPAIR("valid\nStorage slot: ", ubl.storage_slot);
- }
-
- #endif // AUTO_BED_LEVELING_UBL
-
- #if HAS_MESH
-
- #if ENABLED(MESH_BED_LEVELING)
- #define Z_VALUES(X,Y) mbl.z_values[X][Y]
- #else
- #define Z_VALUES(X,Y) z_values[X][Y]
- #endif
-
- // Subtract the given value or the mean from all mesh values
- if (leveling_is_valid() && parser.seen('C')) {
- const float cval = parser.value_float();
- #if ENABLED(AUTO_BED_LEVELING_UBL)
-
- set_bed_leveling_enabled(false);
- ubl.adjust_mesh_to_mean(true, cval);
-
- #else
-
- #if ENABLED(M420_C_USE_MEAN)
-
- // Get the sum and average of all mesh values
- float mesh_sum = 0;
- for (uint8_t x = GRID_MAX_POINTS_X; x--;)
- for (uint8_t y = GRID_MAX_POINTS_Y; y--;)
- mesh_sum += Z_VALUES(x, y);
- const float zmean = mesh_sum / float(GRID_MAX_POINTS);
-
- #else
-
- // Find the low and high mesh values
- float lo_val = 100, hi_val = -100;
- for (uint8_t x = GRID_MAX_POINTS_X; x--;)
- for (uint8_t y = GRID_MAX_POINTS_Y; y--;) {
- const float z = Z_VALUES(x, y);
- NOMORE(lo_val, z);
- NOLESS(hi_val, z);
- }
- // Take the mean of the lowest and highest
- const float zmean = (lo_val + hi_val) / 2.0 + cval;
-
- #endif
-
- // If not very close to 0, adjust the mesh
- if (!NEAR_ZERO(zmean)) {
- set_bed_leveling_enabled(false);
- // Subtract the mean from all values
- for (uint8_t x = GRID_MAX_POINTS_X; x--;)
- for (uint8_t y = GRID_MAX_POINTS_Y; y--;)
- Z_VALUES(x, y) -= zmean;
- #if ENABLED(ABL_BILINEAR_SUBDIVISION)
- bed_level_virt_interpolate();
- #endif
- }
-
- #endif
- }
-
- #endif // HAS_MESH
-
- // V to print the matrix or mesh
- if (parser.seen('V')) {
- #if ABL_PLANAR
- planner.bed_level_matrix.debug(PSTR("Bed Level Correction Matrix:"));
- #else
- if (leveling_is_valid()) {
- #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
- print_bilinear_leveling_grid();
- #if ENABLED(ABL_BILINEAR_SUBDIVISION)
- print_bilinear_leveling_grid_virt();
- #endif
- #elif ENABLED(MESH_BED_LEVELING)
- SERIAL_ECHOLNPGM("Mesh Bed Level data:");
- mbl.report_mesh();
- #endif
- }
- #endif
- }
-
- #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
- if (parser.seen('Z')) set_z_fade_height(parser.value_linear_units(), false);
- #endif
-
- // Enable leveling if specified, or if previously active
- set_bed_leveling_enabled(to_enable);
-
- // Error if leveling failed to enable or reenable
- if (to_enable && !planner.leveling_active) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_M420_FAILED);
- }
-
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR("Bed Leveling ", planner.leveling_active ? MSG_ON : MSG_OFF);
-
- #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
- SERIAL_ECHO_START();
- SERIAL_ECHOPGM("Fade Height ");
- if (planner.z_fade_height > 0.0)
- SERIAL_ECHOLN(planner.z_fade_height);
- else
- SERIAL_ECHOLNPGM(MSG_OFF);
- #endif
-
- // Report change in position
- if (memcmp(oldpos, current_position, sizeof(oldpos)))
- report_current_position();
- }
-
-#endif // HAS_LEVELING
-
-#if ENABLED(MESH_BED_LEVELING)
-
- /**
- * M421: Set a single Mesh Bed Leveling Z coordinate
- *
- * Usage:
- * M421 X Y Z
- * M421 X Y Q
- * M421 I J Z
- * M421 I J Q
- */
- inline void gcode_M421() {
- const bool hasX = parser.seen('X'), hasI = parser.seen('I');
- const int8_t ix = hasI ? parser.value_int() : hasX ? mbl.probe_index_x(parser.value_linear_units()) : -1;
- const bool hasY = parser.seen('Y'), hasJ = parser.seen('J');
- const int8_t iy = hasJ ? parser.value_int() : hasY ? mbl.probe_index_y(parser.value_linear_units()) : -1;
- const bool hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q');
-
- if (int(hasI && hasJ) + int(hasX && hasY) != 1 || !(hasZ || hasQ)) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS);
- }
- else if (ix < 0 || iy < 0) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY);
- }
- else
- mbl.set_z(ix, iy, parser.value_linear_units() + (hasQ ? mbl.z_values[ix][iy] : 0));
- }
-
-#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
-
- /**
- * M421: Set a single Mesh Bed Leveling Z coordinate
- *
- * Usage:
- * M421 I J Z
- * M421 I J Q
- */
- inline void gcode_M421() {
- int8_t ix = parser.intval('I', -1), iy = parser.intval('J', -1);
- const bool hasI = ix >= 0,
- hasJ = iy >= 0,
- hasZ = parser.seen('Z'),
- hasQ = !hasZ && parser.seen('Q');
-
- if (!hasI || !hasJ || !(hasZ || hasQ)) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS);
- }
- else if (!WITHIN(ix, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1)) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY);
- }
- else {
- z_values[ix][iy] = parser.value_linear_units() + (hasQ ? z_values[ix][iy] : 0);
- #if ENABLED(ABL_BILINEAR_SUBDIVISION)
- bed_level_virt_interpolate();
- #endif
- }
- }
-
-#elif ENABLED(AUTO_BED_LEVELING_UBL)
-
- /**
- * M421: Set a single Mesh Bed Leveling Z coordinate
- *
- * Usage:
- * M421 I J Z
- * M421 I J Q
- * M421 I J N
- * M421 C Z
- * M421 C Q
- */
- inline void gcode_M421() {
- int8_t ix = parser.intval('I', -1), iy = parser.intval('J', -1);
- const bool hasI = ix >= 0,
- hasJ = iy >= 0,
- hasC = parser.seen('C'),
- hasN = parser.seen('N'),
- hasZ = parser.seen('Z'),
- hasQ = !hasZ && parser.seen('Q');
-
- if (hasC) {
- const mesh_index_pair location = ubl.find_closest_mesh_point_of_type(REAL, current_position[X_AXIS], current_position[Y_AXIS], USE_NOZZLE_AS_REFERENCE, NULL);
- ix = location.x_index;
- iy = location.y_index;
- }
-
- if (int(hasC) + int(hasI && hasJ) != 1 || !(hasZ || hasQ || hasN)) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS);
- }
- else if (!WITHIN(ix, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1)) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY);
- }
- else
- ubl.z_values[ix][iy] = hasN ? NAN : parser.value_linear_units() + (hasQ ? ubl.z_values[ix][iy] : 0);
- }
-
-#endif // AUTO_BED_LEVELING_UBL
-
-#if HAS_M206_COMMAND
-
- /**
- * M428: Set home_offset based on the distance between the
- * current_position and the nearest "reference point."
- * If an axis is past center its endstop position
- * is the reference-point. Otherwise it uses 0. This allows
- * the Z offset to be set near the bed when using a max endstop.
- *
- * M428 can't be used more than 2cm away from 0 or an endstop.
- *
- * Use M206 to set these values directly.
- */
- inline void gcode_M428() {
- if (axis_unhomed_error()) return;
-
- float diff[XYZ];
- LOOP_XYZ(i) {
- diff[i] = base_home_pos((AxisEnum)i) - current_position[i];
- if (!WITHIN(diff[i], -20, 20) && home_dir((AxisEnum)i) > 0)
- diff[i] = -current_position[i];
- if (!WITHIN(diff[i], -20, 20)) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR);
- LCD_ALERTMESSAGEPGM("Err: Too far!");
- BUZZ(200, 40);
- return;
- }
- }
-
- LOOP_XYZ(i) set_home_offset((AxisEnum)i, diff[i]);
- report_current_position();
- LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED);
- BUZZ(100, 659);
- BUZZ(100, 698);
- }
-
-#endif // HAS_M206_COMMAND
-
-/**
- * M500: Store settings in EEPROM
- */
-inline void gcode_M500() {
- (void)settings.save();
-}
-
-/**
- * M501: Read settings from EEPROM
- */
-inline void gcode_M501() {
- (void)settings.load();
-}
-
-/**
- * M502: Revert to default settings
- */
-inline void gcode_M502() {
- (void)settings.reset();
-}
-
-#if DISABLED(DISABLE_M503)
- /**
- * M503: print settings currently in memory
- */
- inline void gcode_M503() {
- (void)settings.report(parser.seen('S') && !parser.value_bool());
- }
-#endif
-
-#if ENABLED(EEPROM_SETTINGS)
- /**
- * M504: Validate EEPROM Contents
- */
- inline void gcode_M504() {
- if (settings.validate()) {
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPGM("EEPROM OK");
- }
- }
-#endif
-
-#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
-
- /**
- * M540: Set whether SD card print should abort on endstop hit (M540 S<0|1>)
- */
- inline void gcode_M540() {
- if (parser.seen('S')) planner.abort_on_endstop_hit = parser.value_bool();
- }
-
-#endif // ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
-
-#if HAS_BED_PROBE
-
- inline void gcode_M851() {
- if (parser.seenval('Z')) {
- const float value = parser.value_linear_units();
- if (WITHIN(value, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX))
- zprobe_zoffset = value;
- else {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM("?Z out of range (" STRINGIFY(Z_PROBE_OFFSET_RANGE_MIN) " to " STRINGIFY(Z_PROBE_OFFSET_RANGE_MAX) ")");
- }
- return;
- }
- SERIAL_ECHO_START();
- SERIAL_ECHOPGM(MSG_PROBE_Z_OFFSET);
- SERIAL_ECHOLNPAIR(": ", zprobe_zoffset);
- }
-
-#endif // HAS_BED_PROBE
-
-#if ENABLED(SKEW_CORRECTION_GCODE)
-
- /**
- * M852: Get or set the machine skew factors. Reports current values with no arguments.
- *
- * S[xy_factor] - Alias for 'I'
- * I[xy_factor] - New XY skew factor
- * J[xz_factor] - New XZ skew factor
- * K[yz_factor] - New YZ skew factor
- */
- inline void gcode_M852() {
- uint8_t ijk = 0, badval = 0, setval = 0;
-
- if (parser.seen('I') || parser.seen('S')) {
- ++ijk;
- const float value = parser.value_linear_units();
- if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
- if (planner.xy_skew_factor != value) {
- planner.xy_skew_factor = value;
- ++setval;
- }
- }
- else
- ++badval;
- }
-
- #if ENABLED(SKEW_CORRECTION_FOR_Z)
-
- if (parser.seen('J')) {
- ++ijk;
- const float value = parser.value_linear_units();
- if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
- if (planner.xz_skew_factor != value) {
- planner.xz_skew_factor = value;
- ++setval;
- }
- }
- else
- ++badval;
- }
-
- if (parser.seen('K')) {
- ++ijk;
- const float value = parser.value_linear_units();
- if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
- if (planner.yz_skew_factor != value) {
- planner.yz_skew_factor = value;
- ++setval;
- }
- }
- else
- ++badval;
- }
-
- #endif
-
- if (badval)
- SERIAL_ECHOLNPGM(MSG_SKEW_MIN " " STRINGIFY(SKEW_FACTOR_MIN) " " MSG_SKEW_MAX " " STRINGIFY(SKEW_FACTOR_MAX));
-
- // When skew is changed the current position changes
- if (setval) {
- set_current_from_steppers_for_axis(ALL_AXES);
- SYNC_PLAN_POSITION_KINEMATIC();
- report_current_position();
- }
-
- if (!ijk) {
- SERIAL_ECHO_START();
- SERIAL_ECHOPGM(MSG_SKEW_FACTOR " XY: ");
- SERIAL_ECHO_F(planner.xy_skew_factor, 6);
- SERIAL_EOL();
- #if ENABLED(SKEW_CORRECTION_FOR_Z)
- SERIAL_ECHOPAIR(" XZ: ", planner.xz_skew_factor);
- SERIAL_ECHOLNPAIR(" YZ: ", planner.yz_skew_factor);
- #else
- SERIAL_EOL();
- #endif
- }
- }
-
-#endif // SKEW_CORRECTION_GCODE
-
-#if ENABLED(ADVANCED_PAUSE_FEATURE)
-
- /**
- * M600: Pause for filament change
- *
- * E[distance] - Retract the filament this far
- * Z[distance] - Move the Z axis by this distance
- * X[position] - Move to this X position, with Y
- * Y[position] - Move to this Y position, with X
- * U[distance] - Retract distance for removal (manual reload)
- * L[distance] - Extrude distance for insertion (manual reload)
- * B[count] - Number of times to beep, -1 for indefinite (if equipped with a buzzer)
- * T[toolhead] - Select extruder for filament change
- *
- * Default values are used for omitted arguments.
- */
- inline void gcode_M600() {
- point_t park_point = NOZZLE_PARK_POINT;
-
- if (get_target_extruder_from_command(600)) return;
-
- // Show initial message
- #if ENABLED(ULTIPANEL)
- lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INIT, ADVANCED_PAUSE_MODE_PAUSE_PRINT, target_extruder);
- #endif
-
- #if ENABLED(HOME_BEFORE_FILAMENT_CHANGE)
- // Don't allow filament change without homing first
- if (axis_unhomed_error()) home_all_axes();
- #endif
-
- #if EXTRUDERS > 1
- // Change toolhead if specified
- uint8_t active_extruder_before_filament_change = active_extruder;
- if (active_extruder != target_extruder)
- tool_change(target_extruder, 0, true);
- #endif
-
- // Initial retract before move to filament change position
- const float retract = -ABS(parser.seen('E') ? parser.value_axis_units(E_AXIS) : 0
- #ifdef PAUSE_PARK_RETRACT_LENGTH
- + (PAUSE_PARK_RETRACT_LENGTH)
- #endif
- );
-
- // Lift Z axis
- if (parser.seenval('Z')) park_point.z = parser.linearval('Z');
-
- // Move XY axes to filament change position or given position
- if (parser.seenval('X')) park_point.x = parser.linearval('X');
- if (parser.seenval('Y')) park_point.y = parser.linearval('Y');
-
- #if HOTENDS > 1 && DISABLED(DUAL_X_CARRIAGE) && DISABLED(DELTA)
- park_point.x += (active_extruder ? hotend_offset[X_AXIS][active_extruder] : 0);
- park_point.y += (active_extruder ? hotend_offset[Y_AXIS][active_extruder] : 0);
- #endif
-
- // Unload filament
- const float unload_length = -ABS(parser.seen('U') ? parser.value_axis_units(E_AXIS) :
- filament_change_unload_length[active_extruder]);
-
- // Slow load filament
- constexpr float slow_load_length = FILAMENT_CHANGE_SLOW_LOAD_LENGTH;
-
- // Fast load filament
- const float fast_load_length = ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS) :
- filament_change_load_length[active_extruder]);
-
- const int beep_count = parser.intval('B',
- #ifdef FILAMENT_CHANGE_ALERT_BEEPS
- FILAMENT_CHANGE_ALERT_BEEPS
- #else
- -1
- #endif
- );
-
- const bool job_running = print_job_timer.isRunning();
-
- if (pause_print(retract, park_point, unload_length, true)) {
- wait_for_filament_reload(beep_count);
- resume_print(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, beep_count);
- }
-
- #if EXTRUDERS > 1
- // Restore toolhead if it was changed
- if (active_extruder_before_filament_change != active_extruder)
- tool_change(active_extruder_before_filament_change, 0, true);
- #endif
-
- // Resume the print job timer if it was running
- if (job_running) print_job_timer.start();
- }
-
- /**
- * M603: Configure filament change
- *
- * T[toolhead] - Select extruder to configure, active extruder if not specified
- * U[distance] - Retract distance for removal, for the specified extruder
- * L[distance] - Extrude distance for insertion, for the specified extruder
- *
- */
- inline void gcode_M603() {
-
- if (get_target_extruder_from_command(603)) return;
-
- // Unload length
- if (parser.seen('U')) {
- filament_change_unload_length[target_extruder] = ABS(parser.value_axis_units(E_AXIS));
- #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
- NOMORE(filament_change_unload_length[target_extruder], EXTRUDE_MAXLENGTH);
- #endif
- }
-
- // Load length
- if (parser.seen('L')) {
- filament_change_load_length[target_extruder] = ABS(parser.value_axis_units(E_AXIS));
- #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
- NOMORE(filament_change_load_length[target_extruder], EXTRUDE_MAXLENGTH);
- #endif
- }
- }
-
-#endif // ADVANCED_PAUSE_FEATURE
-
-#if ENABLED(MK2_MULTIPLEXER)
-
- inline void select_multiplexed_stepper(const uint8_t e) {
- planner.synchronize();
- disable_e_steppers();
- WRITE(E_MUX0_PIN, TEST(e, 0) ? HIGH : LOW);
- WRITE(E_MUX1_PIN, TEST(e, 1) ? HIGH : LOW);
- WRITE(E_MUX2_PIN, TEST(e, 2) ? HIGH : LOW);
- safe_delay(100);
- }
-
-#endif // MK2_MULTIPLEXER
-
-#if ENABLED(DUAL_X_CARRIAGE)
-
- /**
- * M605: Set dual x-carriage movement mode
- *
- * M605 S0: Full control mode. The slicer has full control over x-carriage movement
- * M605 S1: Auto-park mode. The inactive head will auto park/unpark without slicer involvement
- * M605 S2 [Xnnn] [Rmmm]: Duplication mode. The second extruder will duplicate the first with nnn
- * units x-offset and an optional differential hotend temperature of
- * mmm degrees. E.g., with "M605 S2 X100 R2" the second extruder will duplicate
- * the first with a spacing of 100mm in the x direction and 2 degrees hotter.
- *
- * Note: the X axis should be homed after changing dual x-carriage mode.
- */
- inline void gcode_M605() {
- planner.synchronize();
- if (parser.seen('S')) dual_x_carriage_mode = (DualXMode)parser.value_byte();
- switch (dual_x_carriage_mode) {
- case DXC_FULL_CONTROL_MODE:
- case DXC_AUTO_PARK_MODE:
- break;
- case DXC_DUPLICATION_MODE:
- if (parser.seen('X')) duplicate_extruder_x_offset = MAX(parser.value_linear_units(), X2_MIN_POS - x_home_pos(0));
- if (parser.seen('R')) duplicate_extruder_temp_offset = parser.value_celsius_diff();
- SERIAL_ECHO_START();
- SERIAL_ECHOPGM(MSG_HOTEND_OFFSET);
- SERIAL_CHAR(' ');
- SERIAL_ECHO(hotend_offset[X_AXIS][0]);
- SERIAL_CHAR(',');
- SERIAL_ECHO(hotend_offset[Y_AXIS][0]);
- SERIAL_CHAR(' ');
- SERIAL_ECHO(duplicate_extruder_x_offset);
- SERIAL_CHAR(',');
- SERIAL_ECHOLN(hotend_offset[Y_AXIS][1]);
- break;
- default:
- dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
- break;
- }
- active_extruder_parked = false;
- extruder_duplication_enabled = false;
- delayed_move_time = 0;
- }
-
-#elif ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
-
- inline void gcode_M605() {
- planner.synchronize();
- extruder_duplication_enabled = parser.intval('S') == (int)DXC_DUPLICATION_MODE;
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR(MSG_DUPLICATION_MODE, extruder_duplication_enabled ? MSG_ON : MSG_OFF);
- }
-
-#endif // DUAL_NOZZLE_DUPLICATION_MODE
-
-#if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)
-
- /**
- * M701: Load filament
- *
- * T - Optional extruder number. Current extruder if omitted.
- * Z - Move the Z axis by this distance
- * L - Extrude distance for insertion (positive value) (manual reload)
- *
- * Default values are used for omitted arguments.
- */
- inline void gcode_M701() {
- point_t park_point = NOZZLE_PARK_POINT;
-
- #if ENABLED(NO_MOTION_BEFORE_HOMING)
- // Only raise Z if the machine is homed
- if (axis_unhomed_error()) park_point.z = 0;
- #endif
-
- if (get_target_extruder_from_command(701)) return;
-
- // Z axis lift
- if (parser.seenval('Z')) park_point.z = parser.linearval('Z');
-
- // Show initial "wait for load" message
- #if ENABLED(ULTIPANEL)
- lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_LOAD, ADVANCED_PAUSE_MODE_LOAD_FILAMENT, target_extruder);
- #endif
-
- #if EXTRUDERS > 1
- // Change toolhead if specified
- uint8_t active_extruder_before_filament_change = active_extruder;
- if (active_extruder != target_extruder)
- tool_change(target_extruder, 0, true);
- #endif
-
- // Lift Z axis
- if (park_point.z > 0)
- do_blocking_move_to_z(MIN(current_position[Z_AXIS] + park_point.z, Z_MAX_POS), NOZZLE_PARK_Z_FEEDRATE);
-
- constexpr float slow_load_length = FILAMENT_CHANGE_SLOW_LOAD_LENGTH;
- const float fast_load_length = ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS) : filament_change_load_length[active_extruder]);
- load_filament(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, FILAMENT_CHANGE_ALERT_BEEPS,
- true, thermalManager.wait_for_heating(target_extruder), ADVANCED_PAUSE_MODE_LOAD_FILAMENT);
-
- // Restore Z axis
- if (park_point.z > 0)
- do_blocking_move_to_z(MAX(current_position[Z_AXIS] - park_point.z, 0), NOZZLE_PARK_Z_FEEDRATE);
-
- #if EXTRUDERS > 1
- // Restore toolhead if it was changed
- if (active_extruder_before_filament_change != active_extruder)
- tool_change(active_extruder_before_filament_change, 0, true);
- #endif
-
- // Show status screen
- #if ENABLED(ULTIPANEL)
- lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_STATUS);
- #endif
- }
-
- /**
- * M702: Unload filament
- *
- * T - Optional extruder number. If omitted, current extruder
- * (or ALL extruders with FILAMENT_UNLOAD_ALL_EXTRUDERS).
- * Z - Move the Z axis by this distance
- * U - Retract distance for removal (manual reload)
- *
- * Default values are used for omitted arguments.
- */
- inline void gcode_M702() {
- point_t park_point = NOZZLE_PARK_POINT;
-
- #if ENABLED(NO_MOTION_BEFORE_HOMING)
- // Only raise Z if the machine is homed
- if (axis_unhomed_error()) park_point.z = 0;
- #endif
-
- if (get_target_extruder_from_command(702)) return;
-
- // Z axis lift
- if (parser.seenval('Z')) park_point.z = parser.linearval('Z');
-
- // Show initial message
- #if ENABLED(ULTIPANEL)
- lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_UNLOAD, ADVANCED_PAUSE_MODE_UNLOAD_FILAMENT, target_extruder);
- #endif
-
- #if EXTRUDERS > 1
- // Change toolhead if specified
- uint8_t active_extruder_before_filament_change = active_extruder;
- if (active_extruder != target_extruder)
- tool_change(target_extruder, 0, true);
- #endif
-
- // Lift Z axis
- if (park_point.z > 0)
- do_blocking_move_to_z(MIN(current_position[Z_AXIS] + park_point.z, Z_MAX_POS), NOZZLE_PARK_Z_FEEDRATE);
-
- // Unload filament
- #if EXTRUDERS > 1 && ENABLED(FILAMENT_UNLOAD_ALL_EXTRUDERS)
- if (!parser.seenval('T')) {
- HOTEND_LOOP() {
- if (e != active_extruder) tool_change(e, 0, true);
- unload_filament(-filament_change_unload_length[e], true, ADVANCED_PAUSE_MODE_UNLOAD_FILAMENT);
- }
- }
- else
- #endif
- {
- // Unload length
- const float unload_length = -ABS(parser.seen('U') ? parser.value_axis_units(E_AXIS) :
- filament_change_unload_length[target_extruder]);
-
- unload_filament(unload_length, true, ADVANCED_PAUSE_MODE_UNLOAD_FILAMENT);
- }
-
- // Restore Z axis
- if (park_point.z > 0)
- do_blocking_move_to_z(MAX(current_position[Z_AXIS] - park_point.z, 0), NOZZLE_PARK_Z_FEEDRATE);
-
- #if EXTRUDERS > 1
- // Restore toolhead if it was changed
- if (active_extruder_before_filament_change != active_extruder)
- tool_change(active_extruder_before_filament_change, 0, true);
- #endif
-
- // Show status screen
- #if ENABLED(ULTIPANEL)
- lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_STATUS);
- #endif
- }
-
-#endif // FILAMENT_LOAD_UNLOAD_GCODES
-
-#if ENABLED(MAX7219_GCODE)
- /**
- * M7219: Control the Max7219 LED matrix
- *
- * I - Initialize (clear) the matrix
- * C - Set a column to the 8-bit value V
- * R - Set a row to the 8-bit value V
- * X - X position of an LED to set or toggle
- * Y - Y position of an LED to set or toggle
- * V - The 8-bit value or on/off state to set
- */
- inline void gcode_M7219() {
- if (parser.seen('I'))
- Max7219_Clear();
- else if (parser.seenval('R')) {
- const uint8_t r = parser.value_int();
- Max7219_Set_Row(r, parser.byteval('V'));
- }
- else if (parser.seenval('C')) {
- const uint8_t c = parser.value_int();
- Max7219_Set_Column(c, parser.byteval('V'));
- }
- else if (parser.seenval('X') || parser.seenval('Y')) {
- const uint8_t x = parser.byteval('X'), y = parser.byteval('Y');
- if (parser.seenval('V'))
- Max7219_LED_Set(x, y, parser.boolval('V'));
- else
- Max7219_LED_Toggle(x, y);
- }
- }
-#endif // MAX7219_GCODE
-
-#if ENABLED(LIN_ADVANCE)
- /**
- * M900: Get or Set Linear Advance K-factor
- *
- * K Set advance K factor
- */
- inline void gcode_M900() {
- if (parser.seenval('K')) {
- const float newK = parser.floatval('K');
- if (WITHIN(newK, 0, 10)) {
- planner.synchronize();
- planner.extruder_advance_K = newK;
- }
- else
- SERIAL_PROTOCOLLNPGM("?K value out of range (0-10).");
- }
- else {
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR("Advance K=", planner.extruder_advance_K);
- }
- }
-#endif // LIN_ADVANCE
-
-#if HAS_TRINAMIC
- #if ENABLED(TMC_DEBUG)
- inline void gcode_M122() {
- if (parser.seen('S'))
- tmc_set_report_status(parser.value_bool());
- else
- tmc_report_all();
- }
- #endif // TMC_DEBUG
-
- /**
- * M906: Set motor current in milliamps using axis codes X, Y, Z, E
- * Report driver currents when no axis specified
- */
- inline void gcode_M906() {
- #define TMC_SAY_CURRENT(Q) tmc_get_current(stepper##Q, TMC_##Q)
- #define TMC_SET_CURRENT(Q) tmc_set_current(stepper##Q, value)
-
- bool report = true;
- const uint8_t index = parser.byteval('I');
- LOOP_XYZE(i) if (uint16_t value = parser.intval(axis_codes[i])) {
- report = false;
- switch (i) {
- case X_AXIS:
- #if X_IS_TRINAMIC
- if (index == 0) TMC_SET_CURRENT(X);
- #endif
- #if X2_IS_TRINAMIC
- if (index == 1) TMC_SET_CURRENT(X2);
- #endif
- break;
- case Y_AXIS:
- #if Y_IS_TRINAMIC
- if (index == 0) TMC_SET_CURRENT(Y);
- #endif
- #if Y2_IS_TRINAMIC
- if (index == 1) TMC_SET_CURRENT(Y2);
- #endif
- break;
- case Z_AXIS:
- #if Z_IS_TRINAMIC
- if (index == 0) TMC_SET_CURRENT(Z);
- #endif
- #if Z2_IS_TRINAMIC
- if (index == 1) TMC_SET_CURRENT(Z2);
- #endif
- break;
- case E_AXIS: {
- if (get_target_extruder_from_command(906)) return;
- switch (target_extruder) {
- #if E0_IS_TRINAMIC
- case 0: TMC_SET_CURRENT(E0); break;
- #endif
- #if E1_IS_TRINAMIC
- case 1: TMC_SET_CURRENT(E1); break;
- #endif
- #if E2_IS_TRINAMIC
- case 2: TMC_SET_CURRENT(E2); break;
- #endif
- #if E3_IS_TRINAMIC
- case 3: TMC_SET_CURRENT(E3); break;
- #endif
- #if E4_IS_TRINAMIC
- case 4: TMC_SET_CURRENT(E4); break;
- #endif
- }
- } break;
- }
- }
-
- if (report) LOOP_XYZE(i) switch (i) {
- case X_AXIS:
- #if X_IS_TRINAMIC
- TMC_SAY_CURRENT(X);
- #endif
- #if X2_IS_TRINAMIC
- TMC_SAY_CURRENT(X2);
- #endif
- break;
- case Y_AXIS:
- #if Y_IS_TRINAMIC
- TMC_SAY_CURRENT(Y);
- #endif
- #if Y2_IS_TRINAMIC
- TMC_SAY_CURRENT(Y2);
- #endif
- break;
- case Z_AXIS:
- #if Z_IS_TRINAMIC
- TMC_SAY_CURRENT(Z);
- #endif
- #if Z2_IS_TRINAMIC
- TMC_SAY_CURRENT(Z2);
- #endif
- break;
- case E_AXIS:
- #if E0_IS_TRINAMIC
- TMC_SAY_CURRENT(E0);
- #endif
- #if E1_IS_TRINAMIC
- TMC_SAY_CURRENT(E1);
- #endif
- #if E2_IS_TRINAMIC
- TMC_SAY_CURRENT(E2);
- #endif
- #if E3_IS_TRINAMIC
- TMC_SAY_CURRENT(E3);
- #endif
- #if E4_IS_TRINAMIC
- TMC_SAY_CURRENT(E4);
- #endif
- break;
- }
- }
-
- #define M91x_USE(A) (ENABLED(A##_IS_TMC2130) || (ENABLED(A##_IS_TMC2208) && PIN_EXISTS(A##_SERIAL_RX)))
- #define M91x_USE_E(N) (E_STEPPERS > N && M91x_USE(E##N))
- #define M91x_USE_X (ENABLED(IS_TRAMS) || M91x_USE(X))
- #define M91x_USE_Y (ENABLED(IS_TRAMS) || M91x_USE(Y))
- #define M91x_USE_Z (ENABLED(IS_TRAMS) || M91x_USE(Z))
- #define M91x_USE_E0 (ENABLED(IS_TRAMS) || M91x_USE_E(0))
-
- /**
- * M911: Report TMC stepper driver overtemperature pre-warn flag
- * This flag is held by the library, persisting until cleared by M912
- */
- inline void gcode_M911() {
- #if M91x_USE_X
- tmc_report_otpw(stepperX, TMC_X);
- #endif
- #if M91x_USE(X2)
- tmc_report_otpw(stepperX2, TMC_X2);
- #endif
- #if M91x_USE_Y
- tmc_report_otpw(stepperY, TMC_Y);
- #endif
- #if M91x_USE(Y2)
- tmc_report_otpw(stepperY2, TMC_Y2);
- #endif
- #if M91x_USE_Z
- tmc_report_otpw(stepperZ, TMC_Z);
- #endif
- #if M91x_USE(Z2)
- tmc_report_otpw(stepperZ2, TMC_Z2);
- #endif
- #if M91x_USE_E0
- tmc_report_otpw(stepperE0, TMC_E0);
- #endif
- #if M91x_USE_E(1)
- tmc_report_otpw(stepperE1, TMC_E1);
- #endif
- #if M91x_USE_E(2)
- tmc_report_otpw(stepperE2, TMC_E2);
- #endif
- #if M91x_USE_E(3)
- tmc_report_otpw(stepperE3, TMC_E3);
- #endif
- #if M91x_USE_E(4)
- tmc_report_otpw(stepperE4, TMC_E4);
- #endif
- }
-
- /**
- * M912: Clear TMC stepper driver overtemperature pre-warn flag held by the library
- * Specify one or more axes with X, Y, Z, X1, Y1, Z1, X2, Y2, Z2, and E[index].
- * If no axes are given, clear all.
- *
- * Examples:
- * M912 X ; clear X and X2
- * M912 X1 ; clear X1 only
- * M912 X2 ; clear X2 only
- * M912 X E ; clear X, X2, and all E
- * M912 E1 ; clear E1 only
- */
- inline void gcode_M912() {
- const bool hasX = parser.seen(axis_codes[X_AXIS]),
- hasY = parser.seen(axis_codes[Y_AXIS]),
- hasZ = parser.seen(axis_codes[Z_AXIS]),
- hasE = parser.seen(axis_codes[E_AXIS]),
- hasNone = !hasX && !hasY && !hasZ && !hasE;
-
- #if M91x_USE_X || M91x_USE(X2)
- const uint8_t xval = parser.byteval(axis_codes[X_AXIS], 10);
- #if M91x_USE_X
- if (hasNone || xval == 1 || (hasX && xval == 10)) tmc_clear_otpw(stepperX, TMC_X);
- #endif
- #if M91x_USE(X2)
- if (hasNone || xval == 2 || (hasX && xval == 10)) tmc_clear_otpw(stepperX2, TMC_X2);
- #endif
- #endif
-
- #if M91x_USE_Y || M91x_USE(Y2)
- const uint8_t yval = parser.byteval(axis_codes[Y_AXIS], 10);
- #if M91x_USE_Y
- if (hasNone || yval == 1 || (hasY && yval == 10)) tmc_clear_otpw(stepperY, TMC_Y);
- #endif
- #if M91x_USE(Y2)
- if (hasNone || yval == 2 || (hasY && yval == 10)) tmc_clear_otpw(stepperY2, TMC_Y2);
- #endif
- #endif
-
- #if M91x_USE_Z || M91x_USE(Z2)
- const uint8_t zval = parser.byteval(axis_codes[Z_AXIS], 10);
- #if M91x_USE_Z
- if (hasNone || zval == 1 || (hasZ && zval == 10)) tmc_clear_otpw(stepperZ, TMC_Z);
- #endif
- #if M91x_USE(Z2)
- if (hasNone || zval == 2 || (hasZ && zval == 10)) tmc_clear_otpw(stepperZ2, TMC_Z2);
- #endif
- #endif
-
- #if M91x_USE_E0 || M91x_USE_E(1) || M91x_USE_E(2) || M91x_USE_E(3) || M91x_USE_E(4)
- const uint8_t eval = parser.byteval(axis_codes[E_AXIS], 10);
- #if M91x_USE_E0
- if (hasNone || eval == 0 || (hasE && eval == 10)) tmc_clear_otpw(stepperE0, TMC_E0);
- #endif
- #if M91x_USE_E(1)
- if (hasNone || eval == 1 || (hasE && eval == 10)) tmc_clear_otpw(stepperE1, TMC_E1);
- #endif
- #if M91x_USE_E(2)
- if (hasNone || eval == 2 || (hasE && eval == 10)) tmc_clear_otpw(stepperE2, TMC_E2);
- #endif
- #if M91x_USE_E(3)
- if (hasNone || eval == 3 || (hasE && eval == 10)) tmc_clear_otpw(stepperE3, TMC_E3);
- #endif
- #if M91x_USE_E(4)
- if (hasNone || eval == 4 || (hasE && eval == 10)) tmc_clear_otpw(stepperE4, TMC_E4);
- #endif
- #endif
- }
-
- /**
- * M913: Set HYBRID_THRESHOLD speed.
- */
- #if ENABLED(HYBRID_THRESHOLD)
- inline void gcode_M913() {
- #define TMC_SAY_PWMTHRS(A,Q) tmc_get_pwmthrs(stepper##Q, TMC_##Q, planner.axis_steps_per_mm[_AXIS(A)])
- #define TMC_SET_PWMTHRS(A,Q) tmc_set_pwmthrs(stepper##Q, value, planner.axis_steps_per_mm[_AXIS(A)])
- #define TMC_SAY_PWMTHRS_E(E) do{ const uint8_t extruder = E; tmc_get_pwmthrs(stepperE##E, TMC_E##E, planner.axis_steps_per_mm[E_AXIS_N]); }while(0)
- #define TMC_SET_PWMTHRS_E(E) do{ const uint8_t extruder = E; tmc_set_pwmthrs(stepperE##E, value, planner.axis_steps_per_mm[E_AXIS_N]); }while(0)
-
- bool report = true;
- const uint8_t index = parser.byteval('I');
- LOOP_XYZE(i) if (int32_t value = parser.longval(axis_codes[i])) {
- report = false;
- switch (i) {
- case X_AXIS:
- #if X_IS_TRINAMIC
- if (index == 0) TMC_SET_PWMTHRS(X,X);
- #endif
- #if X2_IS_TRINAMIC
- if (index == 1) TMC_SET_PWMTHRS(X,X2);
- #endif
- break;
- case Y_AXIS:
- #if Y_IS_TRINAMIC
- if (index == 0) TMC_SET_PWMTHRS(Y,Y);
- #endif
- #if Y2_IS_TRINAMIC
- if (index == 1) TMC_SET_PWMTHRS(Y,Y2);
- #endif
- break;
- case Z_AXIS:
- #if Z_IS_TRINAMIC
- if (index == 0) TMC_SET_PWMTHRS(Z,Z);
- #endif
- #if Z2_IS_TRINAMIC
- if (index == 1) TMC_SET_PWMTHRS(Z,Z2);
- #endif
- break;
- case E_AXIS: {
- if (get_target_extruder_from_command(913)) return;
- switch (target_extruder) {
- #if E0_IS_TRINAMIC
- case 0: TMC_SET_PWMTHRS_E(0); break;
- #endif
- #if E_STEPPERS > 1 && E1_IS_TRINAMIC
- case 1: TMC_SET_PWMTHRS_E(1); break;
- #endif
- #if E_STEPPERS > 2 && E2_IS_TRINAMIC
- case 2: TMC_SET_PWMTHRS_E(2); break;
- #endif
- #if E_STEPPERS > 3 && E3_IS_TRINAMIC
- case 3: TMC_SET_PWMTHRS_E(3); break;
- #endif
- #if E_STEPPERS > 4 && E4_IS_TRINAMIC
- case 4: TMC_SET_PWMTHRS_E(4); break;
- #endif
- }
- } break;
- }
- }
-
- if (report) LOOP_XYZE(i) switch (i) {
- case X_AXIS:
- #if X_IS_TRINAMIC
- TMC_SAY_PWMTHRS(X,X);
- #endif
- #if X2_IS_TRINAMIC
- TMC_SAY_PWMTHRS(X,X2);
- #endif
- break;
- case Y_AXIS:
- #if Y_IS_TRINAMIC
- TMC_SAY_PWMTHRS(Y,Y);
- #endif
- #if Y2_IS_TRINAMIC
- TMC_SAY_PWMTHRS(Y,Y2);
- #endif
- break;
- case Z_AXIS:
- #if Z_IS_TRINAMIC
- TMC_SAY_PWMTHRS(Z,Z);
- #endif
- #if Z2_IS_TRINAMIC
- TMC_SAY_PWMTHRS(Z,Z2);
- #endif
- break;
- case E_AXIS:
- #if E0_IS_TRINAMIC
- TMC_SAY_PWMTHRS_E(0);
- #endif
- #if E_STEPPERS > 1 && E1_IS_TRINAMIC
- TMC_SAY_PWMTHRS_E(1);
- #endif
- #if E_STEPPERS > 2 && E2_IS_TRINAMIC
- TMC_SAY_PWMTHRS_E(2);
- #endif
- #if E_STEPPERS > 3 && E3_IS_TRINAMIC
- TMC_SAY_PWMTHRS_E(3);
- #endif
- #if E_STEPPERS > 4 && E4_IS_TRINAMIC
- TMC_SAY_PWMTHRS_E(4);
- #endif
- break;
- }
- }
- #endif // HYBRID_THRESHOLD
-
- /**
- * M914: Set SENSORLESS_HOMING sensitivity.
- */
- #if ENABLED(SENSORLESS_HOMING)
- inline void gcode_M914() {
- #define TMC_SAY_SGT(Q) tmc_get_sgt(stepper##Q, TMC_##Q)
- #define TMC_SET_SGT(Q) tmc_set_sgt(stepper##Q, value)
-
- bool report = true;
- const uint8_t index = parser.byteval('I');
- LOOP_XYZ(i) if (parser.seen(axis_codes[i])) {
- const int8_t value = (int8_t)constrain(parser.value_int(), -64, 63);
- report = false;
- switch (i) {
- #if X_SENSORLESS
- case X_AXIS:
- #if ENABLED(X_IS_TMC2130) || ENABLED(IS_TRAMS)
- if (index == 0) TMC_SET_SGT(X);
- #endif
- #if ENABLED(X2_IS_TMC2130)
- if (index == 1) TMC_SET_SGT(X2);
- #endif
- break;
- #endif
- #if Y_SENSORLESS
- case Y_AXIS:
- #if ENABLED(Y_IS_TMC2130) || ENABLED(IS_TRAMS)
- if (index == 0) TMC_SET_SGT(Y);
- #endif
- #if ENABLED(Y2_IS_TMC2130)
- if (index == 1) TMC_SET_SGT(Y2);
- #endif
- break;
- #endif
- #if Z_SENSORLESS
- case Z_AXIS:
- #if ENABLED(Z_IS_TMC2130) || ENABLED(IS_TRAMS)
- if (index == 0) TMC_SET_SGT(Z);
- #endif
- #if ENABLED(Z2_IS_TMC2130)
- if (index == 1) TMC_SET_SGT(Z2);
- #endif
- break;
- #endif
- }
- }
-
- if (report) LOOP_XYZ(i) switch (i) {
- #if X_SENSORLESS
- case X_AXIS:
- #if ENABLED(X_IS_TMC2130) || ENABLED(IS_TRAMS)
- TMC_SAY_SGT(X);
- #endif
- #if ENABLED(X2_IS_TMC2130)
- TMC_SAY_SGT(X2);
- #endif
- break;
- #endif
- #if Y_SENSORLESS
- case Y_AXIS:
- #if ENABLED(Y_IS_TMC2130) || ENABLED(IS_TRAMS)
- TMC_SAY_SGT(Y);
- #endif
- #if ENABLED(Y2_IS_TMC2130)
- TMC_SAY_SGT(Y2);
- #endif
- break;
- #endif
- #if Z_SENSORLESS
- case Z_AXIS:
- #if ENABLED(Z_IS_TMC2130) || ENABLED(IS_TRAMS)
- TMC_SAY_SGT(Z);
- #endif
- #if ENABLED(Z2_IS_TMC2130)
- TMC_SAY_SGT(Z2);
- #endif
- break;
- #endif
- }
- }
- #endif // SENSORLESS_HOMING
-
- /**
- * TMC Z axis calibration routine
- */
- #if ENABLED(TMC_Z_CALIBRATION)
- inline void gcode_M915() {
- const uint16_t _rms = parser.seenval('S') ? parser.value_int() : CALIBRATION_CURRENT,
- _z = parser.seenval('Z') ? parser.value_linear_units() : CALIBRATION_EXTRA_HEIGHT;
-
- if (!TEST(axis_known_position, Z_AXIS)) {
- SERIAL_ECHOLNPGM("\nPlease home Z axis first");
- return;
- }
-
- #if Z_IS_TRINAMIC
- const uint16_t Z_current_1 = stepperZ.getCurrent();
- stepperZ.setCurrent(_rms, R_SENSE, HOLD_MULTIPLIER);
- #endif
- #if Z2_IS_TRINAMIC
- const uint16_t Z2_current_1 = stepperZ2.getCurrent();
- stepperZ2.setCurrent(_rms, R_SENSE, HOLD_MULTIPLIER);
- #endif
-
- SERIAL_ECHOPAIR("\nCalibration current: Z", _rms);
-
- soft_endstops_enabled = false;
-
- do_blocking_move_to_z(Z_MAX_POS+_z);
-
- #if Z_IS_TRINAMIC
- stepperZ.setCurrent(Z_current_1, R_SENSE, HOLD_MULTIPLIER);
- #endif
- #if Z2_IS_TRINAMIC
- stepperZ2.setCurrent(Z2_current_1, R_SENSE, HOLD_MULTIPLIER);
- #endif
-
- do_blocking_move_to_z(Z_MAX_POS);
- soft_endstops_enabled = true;
-
- SERIAL_ECHOLNPGM("\nHoming Z due to lost steps");
- enqueue_and_echo_commands_P(PSTR("G28 Z"));
- }
- #endif
-
-#endif // HAS_TRINAMIC
-
-/**
- * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S
- */
-inline void gcode_M907() {
- #if HAS_DIGIPOTSS
-
- LOOP_XYZE(i) if (parser.seen(axis_codes[i])) stepper.digipot_current(i, parser.value_int());
- if (parser.seen('B')) stepper.digipot_current(4, parser.value_int());
- if (parser.seen('S')) for (uint8_t i = 0; i <= 4; i++) stepper.digipot_current(i, parser.value_int());
-
- #elif HAS_MOTOR_CURRENT_PWM
-
- #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
- if (parser.seen('X')) stepper.digipot_current(0, parser.value_int());
- #endif
- #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
- if (parser.seen('Z')) stepper.digipot_current(1, parser.value_int());
- #endif
- #if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
- if (parser.seen('E')) stepper.digipot_current(2, parser.value_int());
- #endif
-
- #endif
-
- #if ENABLED(DIGIPOT_I2C)
- // this one uses actual amps in floating point
- LOOP_XYZE(i) if (parser.seen(axis_codes[i])) digipot_i2c_set_current(i, parser.value_float());
- // for each additional extruder (named B,C,D,E..., channels 4,5,6,7...)
- for (uint8_t i = NUM_AXIS; i < DIGIPOT_I2C_NUM_CHANNELS; i++) if (parser.seen('B' + i - (NUM_AXIS))) digipot_i2c_set_current(i, parser.value_float());
- #endif
-
- #if ENABLED(DAC_STEPPER_CURRENT)
- if (parser.seen('S')) {
- const float dac_percent = parser.value_float();
- for (uint8_t i = 0; i <= 4; i++) dac_current_percent(i, dac_percent);
- }
- LOOP_XYZE(i) if (parser.seen(axis_codes[i])) dac_current_percent(i, parser.value_float());
- #endif
-}
-
-#if HAS_DIGIPOTSS || ENABLED(DAC_STEPPER_CURRENT)
-
- /**
- * M908: Control digital trimpot directly (M908 P S)
- */
- inline void gcode_M908() {
- #if HAS_DIGIPOTSS
- stepper.digitalPotWrite(
- parser.intval('P'),
- parser.intval('S')
- );
- #endif
- #ifdef DAC_STEPPER_CURRENT
- dac_current_raw(
- parser.byteval('P', -1),
- parser.ushortval('S', 0)
- );
- #endif
- }
-
- #if ENABLED(DAC_STEPPER_CURRENT) // As with Printrbot RevF
-
- inline void gcode_M909() { dac_print_values(); }
-
- inline void gcode_M910() { dac_commit_eeprom(); }
-
- #endif
-
-#endif // HAS_DIGIPOTSS || DAC_STEPPER_CURRENT
-
-#if HAS_MICROSTEPS
-
- // M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers.
- inline void gcode_M350() {
- if (parser.seen('S')) for (int i = 0; i <= 4; i++) stepper.microstep_mode(i, parser.value_byte());
- LOOP_XYZE(i) if (parser.seen(axis_codes[i])) stepper.microstep_mode(i, parser.value_byte());
- if (parser.seen('B')) stepper.microstep_mode(4, parser.value_byte());
- stepper.microstep_readings();
- }
-
- /**
- * M351: Toggle MS1 MS2 pins directly with axis codes X Y Z E B
- * S# determines MS1 or MS2, X# sets the pin high/low.
- */
- inline void gcode_M351() {
- if (parser.seenval('S')) switch (parser.value_byte()) {
- case 1:
- LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, parser.value_byte(), -1);
- if (parser.seenval('B')) stepper.microstep_ms(4, parser.value_byte(), -1);
- break;
- case 2:
- LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, -1, parser.value_byte());
- if (parser.seenval('B')) stepper.microstep_ms(4, -1, parser.value_byte());
- break;
- }
- stepper.microstep_readings();
- }
-
-#endif // HAS_MICROSTEPS
-
-#if HAS_CASE_LIGHT
-
- #ifndef INVERT_CASE_LIGHT
- #define INVERT_CASE_LIGHT false
- #endif
- uint8_t case_light_brightness; // LCD routine wants INT
- bool case_light_on;
-
- #if ENABLED(CASE_LIGHT_USE_NEOPIXEL)
- LEDColor case_light_color =
- #ifdef CASE_LIGHT_NEOPIXEL_COLOR
- CASE_LIGHT_NEOPIXEL_COLOR
- #else
- { 255, 255, 255, 255 }
- #endif
- ;
- #endif
-
- void update_case_light() {
- const uint8_t i = case_light_on ? case_light_brightness : 0, n10ct = INVERT_CASE_LIGHT ? 255 - i : i;
-
- #if ENABLED(CASE_LIGHT_USE_NEOPIXEL)
-
- leds.set_color(
- MakeLEDColor(case_light_color.r, case_light_color.g, case_light_color.b, case_light_color.w, n10ct),
- false
- );
-
- #else // !CASE_LIGHT_USE_NEOPIXEL
-
- SET_OUTPUT(CASE_LIGHT_PIN);
- if (USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN))
- analogWrite(CASE_LIGHT_PIN, n10ct);
- else {
- const bool s = case_light_on ? !INVERT_CASE_LIGHT : INVERT_CASE_LIGHT;
- WRITE(CASE_LIGHT_PIN, s ? HIGH : LOW);
- }
-
- #endif // !CASE_LIGHT_USE_NEOPIXEL
- }
-#endif // HAS_CASE_LIGHT
-
-/**
- * M355: Turn case light on/off and set brightness
- *
- * P Set case light brightness (PWM pin required - ignored otherwise)
- *
- * S Set case light on/off
- *
- * When S turns on the light on a PWM pin then the current brightness level is used/restored
- *
- * M355 P200 S0 turns off the light & sets the brightness level
- * M355 S1 turns on the light with a brightness of 200 (assuming a PWM pin)
- */
-inline void gcode_M355() {
- #if HAS_CASE_LIGHT
- uint8_t args = 0;
- if (parser.seenval('P')) ++args, case_light_brightness = parser.value_byte();
- if (parser.seenval('S')) ++args, case_light_on = parser.value_bool();
- if (args) update_case_light();
-
- // always report case light status
- SERIAL_ECHO_START();
- if (!case_light_on) {
- SERIAL_ECHOLNPGM("Case light: off");
- }
- else {
- if (!USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)) SERIAL_ECHOLNPGM("Case light: on");
- else SERIAL_ECHOLNPAIR("Case light: ", (int)case_light_brightness);
- }
-
- #else
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_M355_NONE);
- #endif // HAS_CASE_LIGHT
-}
-
-#if ENABLED(MIXING_EXTRUDER)
-
- /**
- * M163: Set a single mix factor for a mixing extruder
- * This is called "weight" by some systems.
- *
- * S[index] The channel index to set
- * P[float] The mix value
- *
- */
- inline void gcode_M163() {
- const int mix_index = parser.intval('S');
- if (mix_index < MIXING_STEPPERS) {
- float mix_value = parser.floatval('P');
- NOLESS(mix_value, 0.0);
- mixing_factor[mix_index] = RECIPROCAL(mix_value);
- }
- }
-
- #if MIXING_VIRTUAL_TOOLS > 1
-
- /**
- * M164: Store the current mix factors as a virtual tool.
- *
- * S[index] The virtual tool to store
- *
- */
- inline void gcode_M164() {
- const int tool_index = parser.intval('S');
- if (tool_index < MIXING_VIRTUAL_TOOLS) {
- normalize_mix();
- for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
- mixing_virtual_tool_mix[tool_index][i] = mixing_factor[i];
- }
- }
-
- #endif
-
- #if ENABLED(DIRECT_MIXING_IN_G1)
- /**
- * M165: Set multiple mix factors for a mixing extruder.
- * Factors that are left out will be set to 0.
- * All factors together must add up to 1.0.
- *
- * A[factor] Mix factor for extruder stepper 1
- * B[factor] Mix factor for extruder stepper 2
- * C[factor] Mix factor for extruder stepper 3
- * D[factor] Mix factor for extruder stepper 4
- * H[factor] Mix factor for extruder stepper 5
- * I[factor] Mix factor for extruder stepper 6
- *
- */
- inline void gcode_M165() { gcode_get_mix(); }
- #endif
-
-#endif // MIXING_EXTRUDER
-
-/**
- * M999: Restart after being stopped
- *
- * Default behaviour is to flush the serial buffer and request
- * a resend to the host starting on the last N line received.
- *
- * Sending "M999 S1" will resume printing without flushing the
- * existing command buffer.
- *
- */
-inline void gcode_M999() {
- Running = true;
- lcd_reset_alert_level();
-
- if (parser.boolval('S')) return;
-
- // gcode_LastN = Stopped_gcode_LastN;
- flush_and_request_resend();
-}
-
-#if DO_SWITCH_EXTRUDER
- #if EXTRUDERS > 3
- #define REQ_ANGLES 4
- #define _SERVO_NR (e < 2 ? SWITCHING_EXTRUDER_SERVO_NR : SWITCHING_EXTRUDER_E23_SERVO_NR)
- #else
- #define REQ_ANGLES 2
- #define _SERVO_NR SWITCHING_EXTRUDER_SERVO_NR
- #endif
- inline void move_extruder_servo(const uint8_t e) {
- constexpr int16_t angles[] = SWITCHING_EXTRUDER_SERVO_ANGLES;
- static_assert(COUNT(angles) == REQ_ANGLES, "SWITCHING_EXTRUDER_SERVO_ANGLES needs " STRINGIFY(REQ_ANGLES) " angles.");
- planner.synchronize();
- #if EXTRUDERS & 1
- if (e < EXTRUDERS - 1)
- #endif
- {
- MOVE_SERVO(_SERVO_NR, angles[e]);
- safe_delay(500);
- }
- }
-#endif // DO_SWITCH_EXTRUDER
-
-#if ENABLED(SWITCHING_NOZZLE)
- inline void move_nozzle_servo(const uint8_t e) {
- const int16_t angles[2] = SWITCHING_NOZZLE_SERVO_ANGLES;
- planner.synchronize();
- MOVE_SERVO(SWITCHING_NOZZLE_SERVO_NR, angles[e]);
- safe_delay(500);
- }
-#endif
-
-inline void invalid_extruder_error(const uint8_t e) {
- SERIAL_ECHO_START();
- SERIAL_CHAR('T');
- SERIAL_ECHO_F(e, DEC);
- SERIAL_CHAR(' ');
- SERIAL_ECHOLNPGM(MSG_INVALID_EXTRUDER);
-}
-
-#if ENABLED(PARKING_EXTRUDER)
-
- #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT)
- #define PE_MAGNET_ON_STATE !PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE
- #else
- #define PE_MAGNET_ON_STATE PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE
- #endif
-
- void pe_set_magnet(const uint8_t extruder_num, const uint8_t state) {
- switch (extruder_num) {
- case 1: OUT_WRITE(SOL1_PIN, state); break;
- default: OUT_WRITE(SOL0_PIN, state); break;
- }
- #if PARKING_EXTRUDER_SOLENOIDS_DELAY > 0
- dwell(PARKING_EXTRUDER_SOLENOIDS_DELAY);
- #endif
- }
-
- inline void pe_activate_magnet(const uint8_t extruder_num) { pe_set_magnet(extruder_num, PE_MAGNET_ON_STATE); }
- inline void pe_deactivate_magnet(const uint8_t extruder_num) { pe_set_magnet(extruder_num, !PE_MAGNET_ON_STATE); }
-
-#endif // PARKING_EXTRUDER
-
-#if HAS_FANMUX
-
- void fanmux_switch(const uint8_t e) {
- WRITE(FANMUX0_PIN, TEST(e, 0) ? HIGH : LOW);
- #if PIN_EXISTS(FANMUX1)
- WRITE(FANMUX1_PIN, TEST(e, 1) ? HIGH : LOW);
- #if PIN_EXISTS(FANMUX2)
- WRITE(FANMUX2, TEST(e, 2) ? HIGH : LOW);
- #endif
- #endif
- }
-
- FORCE_INLINE void fanmux_init(void) {
- SET_OUTPUT(FANMUX0_PIN);
- #if PIN_EXISTS(FANMUX1)
- SET_OUTPUT(FANMUX1_PIN);
- #if PIN_EXISTS(FANMUX2)
- SET_OUTPUT(FANMUX2_PIN);
- #endif
- #endif
- fanmux_switch(0);
- }
-
-#endif // HAS_FANMUX
-
-/**
- * Tool Change functions
- */
-
-#if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1
-
- inline void mixing_tool_change(const uint8_t tmp_extruder) {
- if (tmp_extruder >= MIXING_VIRTUAL_TOOLS)
- return invalid_extruder_error(tmp_extruder);
-
- // T0-Tnnn: Switch virtual tool by changing the mix
- for (uint8_t j = 0; j < MIXING_STEPPERS; j++)
- mixing_factor[j] = mixing_virtual_tool_mix[tmp_extruder][j];
- }
-
-#endif // MIXING_EXTRUDER && MIXING_VIRTUAL_TOOLS > 1
-
-#if ENABLED(DUAL_X_CARRIAGE)
-
- inline void dualx_tool_change(const uint8_t tmp_extruder, bool &no_move) {
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) {
- SERIAL_ECHOPGM("Dual X Carriage Mode ");
- switch (dual_x_carriage_mode) {
- case DXC_FULL_CONTROL_MODE: SERIAL_ECHOLNPGM("DXC_FULL_CONTROL_MODE"); break;
- case DXC_AUTO_PARK_MODE: SERIAL_ECHOLNPGM("DXC_AUTO_PARK_MODE"); break;
- case DXC_DUPLICATION_MODE: SERIAL_ECHOLNPGM("DXC_DUPLICATION_MODE"); break;
- }
- }
- #endif
-
- const float xhome = x_home_pos(active_extruder);
- if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE
- && IsRunning()
- && (delayed_move_time || current_position[X_AXIS] != xhome)
- ) {
- float raised_z = current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT;
- #if ENABLED(MAX_SOFTWARE_ENDSTOPS)
- NOMORE(raised_z, soft_endstop_max[Z_AXIS]);
- #endif
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) {
- SERIAL_ECHOLNPAIR("Raise to ", raised_z);
- SERIAL_ECHOLNPAIR("MoveX to ", xhome);
- SERIAL_ECHOLNPAIR("Lower to ", current_position[Z_AXIS]);
- }
- #endif
- // Park old head: 1) raise 2) move to park position 3) lower
- for (uint8_t i = 0; i < 3; i++)
- planner.buffer_line(
- i == 0 ? current_position[X_AXIS] : xhome,
- current_position[Y_AXIS],
- i == 2 ? current_position[Z_AXIS] : raised_z,
- current_position[E_AXIS],
- planner.max_feedrate_mm_s[i == 1 ? X_AXIS : Z_AXIS],
- active_extruder
- );
- planner.synchronize();
- }
-
- // Apply Y & Z extruder offset (X offset is used as home pos with Dual X)
- current_position[Y_AXIS] -= hotend_offset[Y_AXIS][active_extruder] - hotend_offset[Y_AXIS][tmp_extruder];
- current_position[Z_AXIS] -= hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder];
-
- // Activate the new extruder ahead of calling set_axis_is_at_home!
- active_extruder = tmp_extruder;
-
- // This function resets the max/min values - the current position may be overwritten below.
- set_axis_is_at_home(X_AXIS);
-
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) DEBUG_POS("New Extruder", current_position);
- #endif
-
- // Only when auto-parking are carriages safe to move
- if (dual_x_carriage_mode != DXC_AUTO_PARK_MODE) no_move = true;
-
- switch (dual_x_carriage_mode) {
- case DXC_FULL_CONTROL_MODE:
- // New current position is the position of the activated extruder
- current_position[X_AXIS] = inactive_extruder_x_pos;
- // Save the inactive extruder's position (from the old current_position)
- inactive_extruder_x_pos = destination[X_AXIS];
- break;
- case DXC_AUTO_PARK_MODE:
- // record raised toolhead position for use by unpark
- COPY(raised_parked_position, current_position);
- raised_parked_position[Z_AXIS] += TOOLCHANGE_UNPARK_ZLIFT;
- #if ENABLED(MAX_SOFTWARE_ENDSTOPS)
- NOMORE(raised_parked_position[Z_AXIS], soft_endstop_max[Z_AXIS]);
- #endif
- active_extruder_parked = true;
- delayed_move_time = 0;
- break;
- case DXC_DUPLICATION_MODE:
- // If the new extruder is the left one, set it "parked"
- // This triggers the second extruder to move into the duplication position
- active_extruder_parked = (active_extruder == 0);
- current_position[X_AXIS] = active_extruder_parked ? inactive_extruder_x_pos : destination[X_AXIS] + duplicate_extruder_x_offset;
- inactive_extruder_x_pos = destination[X_AXIS];
- extruder_duplication_enabled = false;
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) {
- SERIAL_ECHOLNPAIR("Set inactive_extruder_x_pos=", inactive_extruder_x_pos);
- SERIAL_ECHOLNPGM("Clear extruder_duplication_enabled");
- }
- #endif
- break;
- }
-
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) {
- SERIAL_ECHOLNPAIR("Active extruder parked: ", active_extruder_parked ? "yes" : "no");
- DEBUG_POS("New extruder (parked)", current_position);
- }
- #endif
-
- // No extra case for HAS_ABL in DUAL_X_CARRIAGE. Does that mean they don't work together?
- }
-
-#endif // DUAL_X_CARRIAGE
-
-#if ENABLED(PARKING_EXTRUDER)
-
- inline void parking_extruder_tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool no_move/*=false*/) {
- constexpr float z_raise = PARKING_EXTRUDER_SECURITY_RAISE;
-
- if (!no_move) {
-
- const float parkingposx[] = PARKING_EXTRUDER_PARKING_X,
- midpos = (parkingposx[0] + parkingposx[1]) * 0.5 + hotend_offset[X_AXIS][active_extruder],
- grabpos = parkingposx[tmp_extruder] + hotend_offset[X_AXIS][active_extruder]
- + (tmp_extruder == 0 ? -(PARKING_EXTRUDER_GRAB_DISTANCE) : PARKING_EXTRUDER_GRAB_DISTANCE);
- /**
- * Steps:
- * 1. Raise Z-Axis to give enough clearance
- * 2. Move to park position of old extruder
- * 3. Disengage magnetic field, wait for delay
- * 4. Move near new extruder
- * 5. Engage magnetic field for new extruder
- * 6. Move to parking incl. offset of new extruder
- * 7. Lower Z-Axis
- */
-
- // STEP 1
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- SERIAL_ECHOLNPGM("Starting Autopark");
- if (DEBUGGING(LEVELING)) DEBUG_POS("current position:", current_position);
- #endif
- current_position[Z_AXIS] += z_raise;
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- SERIAL_ECHOLNPGM("(1) Raise Z-Axis ");
- if (DEBUGGING(LEVELING)) DEBUG_POS("Moving to Raised Z-Position", current_position);
- #endif
- planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
- planner.synchronize();
-
- // STEP 2
- current_position[X_AXIS] = parkingposx[active_extruder] + hotend_offset[X_AXIS][active_extruder];
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- SERIAL_ECHOLNPAIR("(2) Park extruder ", active_extruder);
- if (DEBUGGING(LEVELING)) DEBUG_POS("Moving ParkPos", current_position);
- #endif
- planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
- planner.synchronize();
-
- // STEP 3
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- SERIAL_ECHOLNPGM("(3) Disengage magnet ");
- #endif
- pe_deactivate_magnet(active_extruder);
-
- // STEP 4
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- SERIAL_ECHOLNPGM("(4) Move to position near new extruder");
- #endif
- current_position[X_AXIS] += (active_extruder == 0 ? 10 : -10); // move 10mm away from parked extruder
-
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) DEBUG_POS("Moving away from parked extruder", current_position);
- #endif
- planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
- planner.synchronize();
-
- // STEP 5
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- SERIAL_ECHOLNPGM("(5) Engage magnetic field");
- #endif
-
- #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT)
- pe_activate_magnet(active_extruder); //just save power for inverted magnets
- #endif
- pe_activate_magnet(tmp_extruder);
-
- // STEP 6
- current_position[X_AXIS] = grabpos + (tmp_extruder == 0 ? (+10) : (-10));
- planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
- current_position[X_AXIS] = grabpos;
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- SERIAL_ECHOLNPAIR("(6) Unpark extruder ", tmp_extruder);
- if (DEBUGGING(LEVELING)) DEBUG_POS("Move UnparkPos", current_position);
- #endif
- planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS]/2, active_extruder);
- planner.synchronize();
-
- // Step 7
- current_position[X_AXIS] = midpos - hotend_offset[X_AXIS][tmp_extruder];
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- SERIAL_ECHOLNPGM("(7) Move midway between hotends");
- if (DEBUGGING(LEVELING)) DEBUG_POS("Move midway to new extruder", current_position);
- #endif
- planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
- planner.synchronize();
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- SERIAL_ECHOLNPGM("Autopark done.");
- #endif
- }
- else { // nomove == true
- // Only engage magnetic field for new extruder
- pe_activate_magnet(tmp_extruder);
- #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT)
- pe_activate_magnet(active_extruder); // Just save power for inverted magnets
- #endif
- }
- current_position[Z_AXIS] += hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder];
-
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) DEBUG_POS("Applying Z-offset", current_position);
- #endif
- }
-
-#endif // PARKING_EXTRUDER
-
-/**
- * Perform a tool-change, which may result in moving the
- * previous tool out of the way and the new tool into place.
- */
-void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool no_move/*=false*/) {
- #if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1
-
- mixing_tool_change(tmp_extruder);
-
- #else // !MIXING_EXTRUDER || MIXING_VIRTUAL_TOOLS <= 1
-
- if (tmp_extruder >= EXTRUDERS)
- return invalid_extruder_error(tmp_extruder);
-
- #if HOTENDS > 1
-
- const float old_feedrate_mm_s = fr_mm_s > 0.0 ? fr_mm_s : feedrate_mm_s;
-
- feedrate_mm_s = fr_mm_s > 0.0 ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S;
-
- if (tmp_extruder != active_extruder) {
- if (!no_move && axis_unhomed_error()) {
- no_move = true;
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("No move on toolchange");
- #endif
- }
-
- // Save current position to destination, for use later
- set_destination_from_current();
-
- #if HAS_LEVELING
- // Set current position to the physical position
- const bool leveling_was_active = planner.leveling_active;
- set_bed_leveling_enabled(false);
- #endif
-
- #if ENABLED(DUAL_X_CARRIAGE)
-
- dualx_tool_change(tmp_extruder, no_move); // Can modify no_move
-
- #else // !DUAL_X_CARRIAGE
-
- #if ENABLED(PARKING_EXTRUDER) // Dual Parking extruder
- parking_extruder_tool_change(tmp_extruder, no_move);
- #endif
-
- #if ENABLED(SWITCHING_NOZZLE)
- // Always raise by at least 1 to avoid workpiece
- const float zdiff = hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder];
- current_position[Z_AXIS] += (zdiff > 0.0 ? zdiff : 0.0) + 1;
- planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
- move_nozzle_servo(tmp_extruder);
- #endif
-
- const float xdiff = hotend_offset[X_AXIS][tmp_extruder] - hotend_offset[X_AXIS][active_extruder],
- ydiff = hotend_offset[Y_AXIS][tmp_extruder] - hotend_offset[Y_AXIS][active_extruder];
-
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) {
- SERIAL_ECHOPAIR("Offset Tool XY by { ", xdiff);
- SERIAL_ECHOPAIR(", ", ydiff);
- SERIAL_ECHOLNPGM(" }");
- }
- #endif
-
- // The newly-selected extruder XY is actually at...
- current_position[X_AXIS] += xdiff;
- current_position[Y_AXIS] += ydiff;
-
- // Set the new active extruder
- active_extruder = tmp_extruder;
-
- #endif // !DUAL_X_CARRIAGE
-
- #if ENABLED(SWITCHING_NOZZLE)
- // The newly-selected extruder Z is actually at...
- current_position[Z_AXIS] -= zdiff;
- #endif
-
- #if HAS_LEVELING
- // Restore leveling to re-establish the logical position
- set_bed_leveling_enabled(leveling_was_active);
- #endif
-
- // Tell the planner the new "current position"
- SYNC_PLAN_POSITION_KINEMATIC();
-
- #if ENABLED(DELTA)
- //LOOP_XYZ(i) update_software_endstops(i); // or modify the constrain function
- const bool safe_to_move = current_position[Z_AXIS] < delta_clip_start_height - 1;
- #else
- constexpr bool safe_to_move = true;
- #endif
-
- // Raise, move, and lower again
- if (safe_to_move && !no_move && IsRunning()) {
- #if DISABLED(SWITCHING_NOZZLE)
- // Do a small lift to avoid the workpiece in the move back (below)
- current_position[Z_AXIS] += 1.0;
- planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
- #endif
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) DEBUG_POS("Move back", destination);
- #endif
- // Move back to the original (or tweaked) position
- do_blocking_move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS]);
- #if ENABLED(DUAL_X_CARRIAGE)
- active_extruder_parked = false;
- #endif
- }
- #if ENABLED(SWITCHING_NOZZLE)
- else {
- // Move back down. (Including when the new tool is higher.)
- do_blocking_move_to_z(destination[Z_AXIS], planner.max_feedrate_mm_s[Z_AXIS]);
- }
- #endif
- } // (tmp_extruder != active_extruder)
-
- planner.synchronize();
-
- #if ENABLED(EXT_SOLENOID) && !ENABLED(PARKING_EXTRUDER)
- disable_all_solenoids();
- enable_solenoid_on_active_extruder();
- #endif
-
- feedrate_mm_s = old_feedrate_mm_s;
-
- #else // HOTENDS <= 1
-
- UNUSED(fr_mm_s);
- UNUSED(no_move);
-
- #if ENABLED(MK2_MULTIPLEXER)
- if (tmp_extruder >= E_STEPPERS)
- return invalid_extruder_error(tmp_extruder);
-
- select_multiplexed_stepper(tmp_extruder);
- #endif
-
- // Set the new active extruder
- active_extruder = tmp_extruder;
-
- #endif // HOTENDS <= 1
-
- #if DO_SWITCH_EXTRUDER
- planner.synchronize();
- move_extruder_servo(active_extruder);
- #endif
-
- #if HAS_FANMUX
- fanmux_switch(active_extruder);
- #endif
-
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR(MSG_ACTIVE_EXTRUDER, (int)active_extruder);
-
- #endif // !MIXING_EXTRUDER || MIXING_VIRTUAL_TOOLS <= 1
-}
-
-/**
- * T0-T3: Switch tool, usually switching extruders
- *
- * F[units/min] Set the movement feedrate
- * S1 Don't move the tool in XY after change
- */
-inline void gcode_T(const uint8_t tmp_extruder) {
-
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) {
- SERIAL_ECHOPAIR(">>> gcode_T(", tmp_extruder);
- SERIAL_CHAR(')');
- SERIAL_EOL();
- DEBUG_POS("BEFORE", current_position);
- }
- #endif
-
- #if HOTENDS == 1 || (ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1)
-
- tool_change(tmp_extruder);
-
- #elif HOTENDS > 1
-
- tool_change(
- tmp_extruder,
- MMM_TO_MMS(parser.linearval('F')),
- (tmp_extruder == active_extruder) || parser.boolval('S')
- );
-
- #endif
-
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) {
- DEBUG_POS("AFTER", current_position);
- SERIAL_ECHOLNPGM("<<< gcode_T");
- }
- #endif
-}
-
-/**
- * Process the parsed command and dispatch it to its handler
- */
-void process_parsed_command() {
- KEEPALIVE_STATE(IN_HANDLER);
-
- // Handle a known G, M, or T
- switch (parser.command_letter) {
- case 'G': switch (parser.codenum) {
-
- case 0: case 1: gcode_G0_G1( // G0: Fast Move, G1: Linear Move
- #if IS_SCARA
- parser.codenum == 0
- #endif
- ); break;
-
- #if ENABLED(ARC_SUPPORT) && DISABLED(SCARA)
- case 2: case 3: gcode_G2_G3(parser.codenum == 2); break; // G2: CW ARC, G3: CCW ARC
- #endif
-
- case 4: gcode_G4(); break; // G4: Dwell
-
- #if ENABLED(BEZIER_CURVE_SUPPORT)
- case 5: gcode_G5(); break; // G5: Cubic B_spline
- #endif
-
- #if ENABLED(FWRETRACT)
- case 10: gcode_G10(); break; // G10: Retract
- case 11: gcode_G11(); break; // G11: Prime
- #endif
-
- #if ENABLED(NOZZLE_CLEAN_FEATURE)
- case 12: gcode_G12(); break; // G12: Clean Nozzle
- #endif
-
- #if ENABLED(CNC_WORKSPACE_PLANES)
- case 17: gcode_G17(); break; // G17: Select Plane XY
- case 18: gcode_G18(); break; // G18: Select Plane ZX
- case 19: gcode_G19(); break; // G19: Select Plane YZ
- #endif
-
- #if ENABLED(INCH_MODE_SUPPORT)
- case 20: gcode_G20(); break; // G20: Inch Units
- case 21: gcode_G21(); break; // G21: Millimeter Units
- #endif
-
- #if ENABLED(G26_MESH_VALIDATION)
- case 26: gcode_G26(); break; // G26: Mesh Validation Pattern
- #endif
-
- #if ENABLED(NOZZLE_PARK_FEATURE)
- case 27: gcode_G27(); break; // G27: Park Nozzle
- #endif
-
- case 28: gcode_G28(false); break; // G28: Home one or more axes
-
- #if HAS_LEVELING
- case 29: gcode_G29(); break; // G29: Detailed Z probe
- #endif
-
- #if HAS_BED_PROBE
- case 30: gcode_G30(); break; // G30: Single Z probe
- #endif
-
- #if ENABLED(Z_PROBE_SLED)
- case 31: gcode_G31(); break; // G31: Dock sled
- case 32: gcode_G32(); break; // G32: Undock sled
- #endif
-
- #if ENABLED(DELTA_AUTO_CALIBRATION)
- case 33: gcode_G33(); break; // G33: Delta Auto-Calibration
- #endif
-
- #if ENABLED(G38_PROBE_TARGET)
- case 38:
- if (parser.subcode == 2 || parser.subcode == 3)
- gcode_G38(parser.subcode == 2); // G38.2, G38.3: Probe towards object
- break;
- #endif
-
- #if HAS_MESH
- case 42: gcode_G42(); break; // G42: Move to mesh point
- #endif
-
- case 90: relative_mode = false; break; // G90: Absolute coordinates
- case 91: relative_mode = true; break; // G91: Relative coordinates
-
- case 92: gcode_G92(); break; // G92: Set Position
-
- #if ENABLED(DEBUG_GCODE_PARSER)
- case 800: parser.debug(); break; // G800: GCode Parser Test for G
- #endif
-
- default: parser.unknown_command_error();
- }
- break;
-
- case 'M': switch (parser.codenum) {
- #if HAS_RESUME_CONTINUE
- case 0: case 1: gcode_M0_M1(); break; // M0: Unconditional stop, M1: Conditional stop
- #endif
-
- #if ENABLED(SPINDLE_LASER_ENABLE)
- case 3: gcode_M3_M4(true); break; // M3: Laser/CW-Spindle Power
- case 4: gcode_M3_M4(false); break; // M4: Laser/CCW-Spindle Power
- case 5: gcode_M5(); break; // M5: Laser/Spindle OFF
- #endif
-
- case 17: gcode_M17(); break; // M17: Enable all steppers
-
- #if ENABLED(SDSUPPORT)
- case 20: gcode_M20(); break; // M20: List SD Card
- case 21: gcode_M21(); break; // M21: Init SD Card
- case 22: gcode_M22(); break; // M22: Release SD Card
- case 23: gcode_M23(); break; // M23: Select File
- case 24: gcode_M24(); break; // M24: Start SD Print
- case 25: gcode_M25(); break; // M25: Pause SD Print
- case 26: gcode_M26(); break; // M26: Set SD Index
- case 27: gcode_M27(); break; // M27: Get SD Status
- case 28: gcode_M28(); break; // M28: Start SD Write
- case 29: gcode_M29(); break; // M29: Stop SD Write
- case 30: gcode_M30(); break; // M30: Delete File
- case 32: gcode_M32(); break; // M32: Select file, Start SD Print
- #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
- case 33: gcode_M33(); break; // M33: Report longname path
- #endif
- #if ENABLED(SDCARD_SORT_ALPHA) && ENABLED(SDSORT_GCODE)
- case 34: gcode_M34(); break; // M34: Set SD card sorting options
- #endif
- case 928: gcode_M928(); break; // M928: Start SD write
- #endif // SDSUPPORT
-
- case 31: gcode_M31(); break; // M31: Report print job elapsed time
-
- case 42: gcode_M42(); break; // M42: Change pin state
- #if ENABLED(PINS_DEBUGGING)
- case 43: gcode_M43(); break; // M43: Read/monitor pin and endstop states
- #endif
-
- #if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST)
- case 48: gcode_M48(); break; // M48: Z probe repeatability test
- #endif
- #if ENABLED(G26_MESH_VALIDATION)
- case 49: gcode_M49(); break; // M49: Toggle the G26 Debug Flag
- #endif
-
- #if ENABLED(ULTRA_LCD) && ENABLED(LCD_SET_PROGRESS_MANUALLY)
- case 73: gcode_M73(); break; // M73: Set Print Progress %
- #endif
- case 75: gcode_M75(); break; // M75: Start Print Job Timer
- case 76: gcode_M76(); break; // M76: Pause Print Job Timer
- case 77: gcode_M77(); break; // M77: Stop Print Job Timer
- #if ENABLED(PRINTCOUNTER)
- case 78: gcode_M78(); break; // M78: Report Print Statistics
- #endif
-
- #if ENABLED(M100_FREE_MEMORY_WATCHER)
- case 100: gcode_M100(); break; // M100: Free Memory Report
- #endif
-
- case 104: gcode_M104(); break; // M104: Set Hotend Temperature
- case 110: gcode_M110(); break; // M110: Set Current Line Number
- case 111: gcode_M111(); break; // M111: Set Debug Flags
-
- #if DISABLED(EMERGENCY_PARSER)
- case 108: gcode_M108(); break; // M108: Cancel Waiting
- case 112: gcode_M112(); break; // M112: Emergency Stop
- case 410: gcode_M410(); break; // M410: Quickstop. Abort all planned moves
- #endif
-
- #if ENABLED(HOST_KEEPALIVE_FEATURE)
- case 113: gcode_M113(); break; // M113: Set Host Keepalive Interval
- #endif
-
- case 105: gcode_M105(); KEEPALIVE_STATE(NOT_BUSY); return; // M105: Report Temperatures (and say "ok")
-
- #if ENABLED(AUTO_REPORT_TEMPERATURES)
- case 155: gcode_M155(); break; // M155: Set Temperature Auto-report Interval
- #endif
-
- case 109: gcode_M109(); break; // M109: Set Hotend Temperature. Wait for target.
-
- #if HAS_HEATED_BED
- case 140: gcode_M140(); break; // M140: Set Bed Temperature
- case 190: gcode_M190(); break; // M190: Set Bed Temperature. Wait for target.
- #endif
-
- #if FAN_COUNT > 0
- case 106: gcode_M106(); break; // M106: Set Fan Speed
- case 107: gcode_M107(); break; // M107: Fan Off
- #endif
-
- #if ENABLED(PARK_HEAD_ON_PAUSE)
- case 125: gcode_M125(); break; // M125: Park (for Filament Change)
- #endif
-
- #if ENABLED(BARICUDA)
- #if HAS_HEATER_1
- case 126: gcode_M126(); break; // M126: Valve 1 Open
- case 127: gcode_M127(); break; // M127: Valve 1 Closed
- #endif
- #if HAS_HEATER_2
- case 128: gcode_M128(); break; // M128: Valve 2 Open
- case 129: gcode_M129(); break; // M129: Valve 2 Closed
- #endif
- #endif
-
- #if HAS_POWER_SWITCH
- case 80: gcode_M80(); break; // M80: Turn on Power Supply
- #endif
- case 81: gcode_M81(); break; // M81: Turn off Power and Power Supply
-
- case 82: gcode_M82(); break; // M82: Disable Relative E-Axis
- case 83: gcode_M83(); break; // M83: Set Relative E-Axis
- case 18: case 84: gcode_M18_M84(); break; // M18/M84: Disable Steppers / Set Timeout
- case 85: gcode_M85(); break; // M85: Set inactivity stepper shutdown timeout
- case 92: gcode_M92(); break; // M92: Set steps-per-unit
- case 114: gcode_M114(); break; // M114: Report Current Position
- case 115: gcode_M115(); break; // M115: Capabilities Report
- case 117: gcode_M117(); break; // M117: Set LCD message text
- case 118: gcode_M118(); break; // M118: Print a message in the host console
- case 119: gcode_M119(); break; // M119: Report Endstop states
- case 120: gcode_M120(); break; // M120: Enable Endstops
- case 121: gcode_M121(); break; // M121: Disable Endstops
-
- #if ENABLED(ULTIPANEL)
- case 145: gcode_M145(); break; // M145: Set material heatup parameters
- #endif
-
- #if ENABLED(TEMPERATURE_UNITS_SUPPORT)
- case 149: gcode_M149(); break; // M149: Set Temperature Units, C F K
- #endif
-
- #if HAS_COLOR_LEDS
- case 150: gcode_M150(); break; // M150: Set Status LED Color
- #endif
-
- #if ENABLED(MIXING_EXTRUDER)
- case 163: gcode_M163(); break; // M163: Set Mixing Component
- #if MIXING_VIRTUAL_TOOLS > 1
- case 164: gcode_M164(); break; // M164: Save Current Mix
- #endif
- #if ENABLED(DIRECT_MIXING_IN_G1)
- case 165: gcode_M165(); break; // M165: Set Multiple Mixing Components
- #endif
- #endif
-
- #if DISABLED(NO_VOLUMETRICS)
- case 200: gcode_M200(); break; // M200: Set Filament Diameter, Volumetric Extrusion
- #endif
-
- case 201: gcode_M201(); break; // M201: Set Max Printing Acceleration (units/sec^2)
- #if 0
- case 202: gcode_M202(); break; // M202: Not used for Sprinter/grbl gen6
- #endif
- case 203: gcode_M203(); break; // M203: Set Max Feedrate (units/sec)
- case 204: gcode_M204(); break; // M204: Set Acceleration
- case 205: gcode_M205(); break; // M205: Set Advanced settings
-
- #if HAS_M206_COMMAND
- case 206: gcode_M206(); break; // M206: Set Home Offsets
- case 428: gcode_M428(); break; // M428: Set Home Offsets based on current position
- #endif
-
- #if ENABLED(FWRETRACT)
- case 207: gcode_M207(); break; // M207: Set Retract Length, Feedrate, Z lift
- case 208: gcode_M208(); break; // M208: Set Additional Prime Length and Feedrate
- case 209:
- if (MIN_AUTORETRACT <= MAX_AUTORETRACT) gcode_M209(); // M209: Turn Auto-Retract on/off
- break;
- #endif
-
- case 211: gcode_M211(); break; // M211: Enable/Disable/Report Software Endstops
-
- #if HOTENDS > 1
- case 218: gcode_M218(); break; // M218: Set Tool Offset
- #endif
-
- case 220: gcode_M220(); break; // M220: Set Feedrate Percentage
- case 221: gcode_M221(); break; // M221: Set Flow Percentage
- case 226: gcode_M226(); break; // M226: Wait for Pin State
-
- #if defined(CHDK) || HAS_PHOTOGRAPH
- case 240: gcode_M240(); break; // M240: Trigger Camera
- #endif
-
- #if HAS_LCD_CONTRAST
- case 250: gcode_M250(); break; // M250: Set LCD Contrast
- #endif
-
- #if ENABLED(EXPERIMENTAL_I2CBUS)
- case 260: gcode_M260(); break; // M260: Send Data to i2c slave
- case 261: gcode_M261(); break; // M261: Request Data from i2c slave
- #endif
-
- #if HAS_SERVOS
- case 280: gcode_M280(); break; // M280: Set Servo Position
- #endif
-
- #if ENABLED(BABYSTEPPING)
- case 290: gcode_M290(); break; // M290: Babystepping
- #endif
-
- #if HAS_BUZZER
- case 300: gcode_M300(); break; // M300: Add Tone/Buzz to Queue
- #endif
-
- #if ENABLED(PIDTEMP)
- case 301: gcode_M301(); break; // M301: Set Hotend PID parameters
- #endif
-
- #if ENABLED(PREVENT_COLD_EXTRUSION)
- case 302: gcode_M302(); break; // M302: Set Minimum Extrusion Temp
- #endif
-
- case 303: gcode_M303(); break; // M303: PID Autotune
-
- #if ENABLED(PIDTEMPBED)
- case 304: gcode_M304(); break; // M304: Set Bed PID parameters
- #endif
-
- #if HAS_MICROSTEPS
- case 350: gcode_M350(); break; // M350: Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers.
- case 351: gcode_M351(); break; // M351: Toggle MS1 MS2 pins directly, S# determines MS1 or MS2, X# sets the pin high/low.
- #endif
-
- case 355: gcode_M355(); break; // M355: Set Case Light brightness
-
- #if ENABLED(MORGAN_SCARA)
- case 360: if (gcode_M360()) return; break; // M360: SCARA Theta pos1
- case 361: if (gcode_M361()) return; break; // M361: SCARA Theta pos2
- case 362: if (gcode_M362()) return; break; // M362: SCARA Psi pos1
- case 363: if (gcode_M363()) return; break; // M363: SCARA Psi pos2
- case 364: if (gcode_M364()) return; break; // M364: SCARA Psi pos3 (90 deg to Theta)
- #endif
-
- case 400: gcode_M400(); break; // M400: Synchronize. Wait for moves to finish.
-
- #if HAS_BED_PROBE
- case 401: gcode_M401(); break; // M401: Deploy Probe
- case 402: gcode_M402(); break; // M402: Stow Probe
- #endif
-
- #if ENABLED(FILAMENT_WIDTH_SENSOR)
- case 404: gcode_M404(); break; // M404: Set/Report Nominal Filament Width
- case 405: gcode_M405(); break; // M405: Enable Filament Width Sensor
- case 406: gcode_M406(); break; // M406: Disable Filament Width Sensor
- case 407: gcode_M407(); break; // M407: Report Measured Filament Width
- #endif
-
- #if HAS_LEVELING
- case 420: gcode_M420(); break; // M420: Set Bed Leveling Enabled / Fade
- #endif
-
- #if HAS_MESH
- case 421: gcode_M421(); break; // M421: Set a Mesh Z value
- #endif
-
- case 500: gcode_M500(); break; // M500: Store Settings in EEPROM
- case 501: gcode_M501(); break; // M501: Read Settings from EEPROM
- case 502: gcode_M502(); break; // M502: Revert Settings to defaults
- #if DISABLED(DISABLE_M503)
- case 503: gcode_M503(); break; // M503: Report Settings (in SRAM)
- #endif
- #if ENABLED(EEPROM_SETTINGS)
- case 504: gcode_M504(); break; // M504: Validate EEPROM
- #endif
-
- #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
- case 540: gcode_M540(); break; // M540: Set Abort on Endstop Hit for SD Printing
- #endif
-
- #if ENABLED(ADVANCED_PAUSE_FEATURE)
- case 600: gcode_M600(); break; // M600: Pause for Filament Change
- case 603: gcode_M603(); break; // M603: Configure Filament Change
- #endif
-
- #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
- case 605: gcode_M605(); break; // M605: Set Dual X Carriage movement mode
- #endif
-
- #if ENABLED(DELTA)
- case 665: gcode_M665(); break; // M665: Delta Configuration
- #endif
- #if ENABLED(DELTA) || ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
- case 666: gcode_M666(); break; // M666: DELTA/Dual Endstop Adjustment
- #endif
-
- #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)
- case 701: gcode_M701(); break; // M701: Load Filament
- case 702: gcode_M702(); break; // M702: Unload Filament
- #endif
-
- #if ENABLED(MAX7219_GCODE)
- case 7219: gcode_M7219(); break; // M7219: Set LEDs, columns, and rows
- #endif
-
- #if ENABLED(DEBUG_GCODE_PARSER)
- case 800: parser.debug(); break; // M800: GCode Parser Test for M
- #endif
-
- #if HAS_BED_PROBE
- case 851: gcode_M851(); break; // M851: Set Z Probe Z Offset
- #endif
-
- #if ENABLED(SKEW_CORRECTION_GCODE)
- case 852: gcode_M852(); break; // M852: Set Skew factors
- #endif
-
- #if ENABLED(I2C_POSITION_ENCODERS)
- case 860: gcode_M860(); break; // M860: Report encoder module position
- case 861: gcode_M861(); break; // M861: Report encoder module status
- case 862: gcode_M862(); break; // M862: Perform axis test
- case 863: gcode_M863(); break; // M863: Calibrate steps/mm
- case 864: gcode_M864(); break; // M864: Change module address
- case 865: gcode_M865(); break; // M865: Check module firmware version
- case 866: gcode_M866(); break; // M866: Report axis error count
- case 867: gcode_M867(); break; // M867: Toggle error correction
- case 868: gcode_M868(); break; // M868: Set error correction threshold
- case 869: gcode_M869(); break; // M869: Report axis error
- #endif
-
- #if ENABLED(LIN_ADVANCE)
- case 900: gcode_M900(); break; // M900: Set Linear Advance K factor
- #endif
-
- case 907: gcode_M907(); break; // M907: Set Digital Trimpot Motor Current using axis codes.
-
- #if HAS_DIGIPOTSS || ENABLED(DAC_STEPPER_CURRENT)
- case 908: gcode_M908(); break; // M908: Direct Control Digital Trimpot
- #if ENABLED(DAC_STEPPER_CURRENT)
- case 909: gcode_M909(); break; // M909: Print Digipot/DAC current value (As with Printrbot RevF)
- case 910: gcode_M910(); break; // M910: Commit Digipot/DAC value to External EEPROM (As with Printrbot RevF)
- #endif
- #endif
-
- #if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208)
- #if ENABLED(TMC_DEBUG)
- case 122: gcode_M122(); break; // M122: Debug TMC steppers
- #endif
- case 906: gcode_M906(); break; // M906: Set motor current in milliamps using axis codes X, Y, Z, E
- case 911: gcode_M911(); break; // M911: Report TMC prewarn triggered flags
- case 912: gcode_M912(); break; // M911: Clear TMC prewarn triggered flags
- #if ENABLED(HYBRID_THRESHOLD)
- case 913: gcode_M913(); break; // M913: Set HYBRID_THRESHOLD speed.
- #endif
- #if ENABLED(SENSORLESS_HOMING)
- case 914: gcode_M914(); break; // M914: Set SENSORLESS_HOMING sensitivity.
- #endif
- #if ENABLED(TMC_Z_CALIBRATION)
- case 915: gcode_M915(); break; // M915: TMC Z axis calibration routine
- #endif
- #endif
-
- case 999: gcode_M999(); break; // M999: Restart after being Stopped
-
- default: parser.unknown_command_error();
- }
- break;
-
- case 'T': gcode_T(parser.codenum); break; // T: Tool Select
-
- default: parser.unknown_command_error();
- }
-
- KEEPALIVE_STATE(NOT_BUSY);
- ok_to_send();
-}
-
-void process_next_command() {
- char * const current_command = command_queue[cmd_queue_index_r];
-
- if (DEBUGGING(ECHO)) {
- SERIAL_ECHO_START();
- SERIAL_ECHOLN(current_command);
- #if ENABLED(M100_FREE_MEMORY_WATCHER)
- SERIAL_ECHOPAIR("slot:", cmd_queue_index_r);
- M100_dump_routine(" Command Queue:", (const char*)command_queue, (const char*)(command_queue + sizeof(command_queue)));
- #endif
- }
-
- // Parse the next command in the queue
- parser.parse(current_command);
- process_parsed_command();
-}
-
-/**
- * Send a "Resend: nnn" message to the host to
- * indicate that a command needs to be re-sent.
- */
-void flush_and_request_resend() {
- //char command_queue[cmd_queue_index_r][100]="Resend:";
- SERIAL_FLUSH();
- SERIAL_PROTOCOLPGM(MSG_RESEND);
- SERIAL_PROTOCOLLN(gcode_LastN + 1);
- ok_to_send();
-}
-
-/**
- * Send an "ok" message to the host, indicating
- * that a command was successfully processed.
- *
- * If ADVANCED_OK is enabled also include:
- * N Line number of the command, if any
- * P Planner space remaining
- * B Block queue space remaining
- */
-void ok_to_send() {
- if (!send_ok[cmd_queue_index_r]) return;
- SERIAL_PROTOCOLPGM(MSG_OK);
- #if ENABLED(ADVANCED_OK)
- char* p = command_queue[cmd_queue_index_r];
- if (*p == 'N') {
- SERIAL_PROTOCOL(' ');
- SERIAL_ECHO(*p++);
- while (NUMERIC_SIGNED(*p))
- SERIAL_ECHO(*p++);
- }
- SERIAL_PROTOCOLPGM(" P"); SERIAL_PROTOCOL(int(BLOCK_BUFFER_SIZE - planner.movesplanned() - 1));
- SERIAL_PROTOCOLPGM(" B"); SERIAL_PROTOCOL(BUFSIZE - commands_in_queue);
- #endif
- SERIAL_EOL();
-}
-
-#if HAS_SOFTWARE_ENDSTOPS
-
- /**
- * Constrain the given coordinates to the software endstops.
- *
- * For DELTA/SCARA the XY constraint is based on the smallest
- * radius within the set software endstops.
- */
- void clamp_to_software_endstops(float target[XYZ]) {
- if (!soft_endstops_enabled) return;
- #if IS_KINEMATIC
- const float dist_2 = HYPOT2(target[X_AXIS], target[Y_AXIS]);
- if (dist_2 > soft_endstop_radius_2) {
- const float ratio = soft_endstop_radius / SQRT(dist_2); // 200 / 300 = 0.66
- target[X_AXIS] *= ratio;
- target[Y_AXIS] *= ratio;
- }
- #else
- #if ENABLED(MIN_SOFTWARE_ENDSTOP_X)
- NOLESS(target[X_AXIS], soft_endstop_min[X_AXIS]);
- #endif
- #if ENABLED(MIN_SOFTWARE_ENDSTOP_Y)
- NOLESS(target[Y_AXIS], soft_endstop_min[Y_AXIS]);
- #endif
- #if ENABLED(MAX_SOFTWARE_ENDSTOP_X)
- NOMORE(target[X_AXIS], soft_endstop_max[X_AXIS]);
- #endif
- #if ENABLED(MAX_SOFTWARE_ENDSTOP_Y)
- NOMORE(target[Y_AXIS], soft_endstop_max[Y_AXIS]);
- #endif
- #endif
- #if ENABLED(MIN_SOFTWARE_ENDSTOP_Z)
- NOLESS(target[Z_AXIS], soft_endstop_min[Z_AXIS]);
- #endif
- #if ENABLED(MAX_SOFTWARE_ENDSTOP_Z)
- NOMORE(target[Z_AXIS], soft_endstop_max[Z_AXIS]);
- #endif
- }
-
-#endif
-
-#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
-
- // Get the Z adjustment for non-linear bed leveling
- float bilinear_z_offset(const float raw[XYZ]) {
-
- static float z1, d2, z3, d4, L, D, ratio_x, ratio_y,
- last_x = -999.999, last_y = -999.999;
-
- // Whole units for the grid line indices. Constrained within bounds.
- static int8_t gridx, gridy, nextx, nexty,
- last_gridx = -99, last_gridy = -99;
-
- // XY relative to the probed area
- const float rx = raw[X_AXIS] - bilinear_start[X_AXIS],
- ry = raw[Y_AXIS] - bilinear_start[Y_AXIS];
-
- #if ENABLED(EXTRAPOLATE_BEYOND_GRID)
- // Keep using the last grid box
- #define FAR_EDGE_OR_BOX 2
- #else
- // Just use the grid far edge
- #define FAR_EDGE_OR_BOX 1
- #endif
-
- if (last_x != rx) {
- last_x = rx;
- ratio_x = rx * ABL_BG_FACTOR(X_AXIS);
- const float gx = constrain(FLOOR(ratio_x), 0, ABL_BG_POINTS_X - FAR_EDGE_OR_BOX);
- ratio_x -= gx; // Subtract whole to get the ratio within the grid box
-
- #if DISABLED(EXTRAPOLATE_BEYOND_GRID)
- // Beyond the grid maintain height at grid edges
- NOLESS(ratio_x, 0); // Never < 0.0. (> 1.0 is ok when nextx==gridx.)
- #endif
-
- gridx = gx;
- nextx = MIN(gridx + 1, ABL_BG_POINTS_X - 1);
- }
-
- if (last_y != ry || last_gridx != gridx) {
-
- if (last_y != ry) {
- last_y = ry;
- ratio_y = ry * ABL_BG_FACTOR(Y_AXIS);
- const float gy = constrain(FLOOR(ratio_y), 0, ABL_BG_POINTS_Y - FAR_EDGE_OR_BOX);
- ratio_y -= gy;
-
- #if DISABLED(EXTRAPOLATE_BEYOND_GRID)
- // Beyond the grid maintain height at grid edges
- NOLESS(ratio_y, 0); // Never < 0.0. (> 1.0 is ok when nexty==gridy.)
- #endif
-
- gridy = gy;
- nexty = MIN(gridy + 1, ABL_BG_POINTS_Y - 1);
- }
-
- if (last_gridx != gridx || last_gridy != gridy) {
- last_gridx = gridx;
- last_gridy = gridy;
- // Z at the box corners
- z1 = ABL_BG_GRID(gridx, gridy); // left-front
- d2 = ABL_BG_GRID(gridx, nexty) - z1; // left-back (delta)
- z3 = ABL_BG_GRID(nextx, gridy); // right-front
- d4 = ABL_BG_GRID(nextx, nexty) - z3; // right-back (delta)
- }
-
- // Bilinear interpolate. Needed since ry or gridx has changed.
- L = z1 + d2 * ratio_y; // Linear interp. LF -> LB
- const float R = z3 + d4 * ratio_y; // Linear interp. RF -> RB
-
- D = R - L;
- }
-
- const float offset = L + ratio_x * D; // the offset almost always changes
-
- /*
- static float last_offset = 0;
- if (ABS(last_offset - offset) > 0.2) {
- SERIAL_ECHOPGM("Sudden Shift at ");
- SERIAL_ECHOPAIR("x=", rx);
- SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[X_AXIS]);
- SERIAL_ECHOLNPAIR(" -> gridx=", gridx);
- SERIAL_ECHOPAIR(" y=", ry);
- SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[Y_AXIS]);
- SERIAL_ECHOLNPAIR(" -> gridy=", gridy);
- SERIAL_ECHOPAIR(" ratio_x=", ratio_x);
- SERIAL_ECHOLNPAIR(" ratio_y=", ratio_y);
- SERIAL_ECHOPAIR(" z1=", z1);
- SERIAL_ECHOPAIR(" z2=", z2);
- SERIAL_ECHOPAIR(" z3=", z3);
- SERIAL_ECHOLNPAIR(" z4=", z4);
- SERIAL_ECHOPAIR(" L=", L);
- SERIAL_ECHOPAIR(" R=", R);
- SERIAL_ECHOLNPAIR(" offset=", offset);
- }
- last_offset = offset;
- //*/
-
- return offset;
- }
-
-#endif // AUTO_BED_LEVELING_BILINEAR
-
-#if ENABLED(DELTA)
-
- /**
- * Recalculate factors used for delta kinematics whenever
- * settings have been changed (e.g., by M665).
- */
- void recalc_delta_settings() {
- const float trt[ABC] = DELTA_RADIUS_TRIM_TOWER,
- drt[ABC] = DELTA_DIAGONAL_ROD_TRIM_TOWER;
- delta_tower[A_AXIS][X_AXIS] = cos(RADIANS(210 + delta_tower_angle_trim[A_AXIS])) * (delta_radius + trt[A_AXIS]); // front left tower
- delta_tower[A_AXIS][Y_AXIS] = sin(RADIANS(210 + delta_tower_angle_trim[A_AXIS])) * (delta_radius + trt[A_AXIS]);
- delta_tower[B_AXIS][X_AXIS] = cos(RADIANS(330 + delta_tower_angle_trim[B_AXIS])) * (delta_radius + trt[B_AXIS]); // front right tower
- delta_tower[B_AXIS][Y_AXIS] = sin(RADIANS(330 + delta_tower_angle_trim[B_AXIS])) * (delta_radius + trt[B_AXIS]);
- delta_tower[C_AXIS][X_AXIS] = cos(RADIANS( 90 + delta_tower_angle_trim[C_AXIS])) * (delta_radius + trt[C_AXIS]); // back middle tower
- delta_tower[C_AXIS][Y_AXIS] = sin(RADIANS( 90 + delta_tower_angle_trim[C_AXIS])) * (delta_radius + trt[C_AXIS]);
- delta_diagonal_rod_2_tower[A_AXIS] = sq(delta_diagonal_rod + drt[A_AXIS]);
- delta_diagonal_rod_2_tower[B_AXIS] = sq(delta_diagonal_rod + drt[B_AXIS]);
- delta_diagonal_rod_2_tower[C_AXIS] = sq(delta_diagonal_rod + drt[C_AXIS]);
- update_software_endstops(Z_AXIS);
- axis_homed = 0;
- }
-
- /**
- * Delta Inverse Kinematics
- *
- * Calculate the tower positions for a given machine
- * position, storing the result in the delta[] array.
- *
- * This is an expensive calculation, requiring 3 square
- * roots per segmented linear move, and strains the limits
- * of a Mega2560 with a Graphical Display.
- *
- * Suggested optimizations include:
- *
- * - Disable the home_offset (M206) and/or position_shift (G92)
- * features to remove up to 12 float additions.
- */
-
- #define DELTA_DEBUG(VAR) do { \
- SERIAL_ECHOPAIR("cartesian X:", VAR[X_AXIS]); \
- SERIAL_ECHOPAIR(" Y:", VAR[Y_AXIS]); \
- SERIAL_ECHOLNPAIR(" Z:", VAR[Z_AXIS]); \
- SERIAL_ECHOPAIR("delta A:", delta[A_AXIS]); \
- SERIAL_ECHOPAIR(" B:", delta[B_AXIS]); \
- SERIAL_ECHOLNPAIR(" C:", delta[C_AXIS]); \
- }while(0)
-
- void inverse_kinematics(const float raw[XYZ]) {
- #if HOTENDS > 1
- // Delta hotend offsets must be applied in Cartesian space with no "spoofing"
- const float pos[XYZ] = {
- raw[X_AXIS] - hotend_offset[X_AXIS][active_extruder],
- raw[Y_AXIS] - hotend_offset[Y_AXIS][active_extruder],
- raw[Z_AXIS]
- };
- DELTA_IK(pos);
- //DELTA_DEBUG(pos);
- #else
- DELTA_IK(raw);
- //DELTA_DEBUG(raw);
- #endif
- }
-
- /**
- * Calculate the highest Z position where the
- * effector has the full range of XY motion.
- */
- float delta_safe_distance_from_top() {
- float cartesian[XYZ] = { 0, 0, 0 };
- inverse_kinematics(cartesian);
- const float centered_extent = delta[A_AXIS];
- cartesian[Y_AXIS] = DELTA_PRINTABLE_RADIUS;
- inverse_kinematics(cartesian);
- return ABS(centered_extent - delta[A_AXIS]);
- }
-
- /**
- * Delta Forward Kinematics
- *
- * See the Wikipedia article "Trilateration"
- * https://en.wikipedia.org/wiki/Trilateration
- *
- * Establish a new coordinate system in the plane of the
- * three carriage points. This system has its origin at
- * tower1, with tower2 on the X axis. Tower3 is in the X-Y
- * plane with a Z component of zero.
- * We will define unit vectors in this coordinate system
- * in our original coordinate system. Then when we calculate
- * the Xnew, Ynew and Znew values, we can translate back into
- * the original system by moving along those unit vectors
- * by the corresponding values.
- *
- * Variable names matched to Marlin, c-version, and avoid the
- * use of any vector library.
- *
- * by Andreas Hardtung 2016-06-07
- * based on a Java function from "Delta Robot Kinematics V3"
- * by Steve Graves
- *
- * The result is stored in the cartes[] array.
- */
- void forward_kinematics_DELTA(const float &z1, const float &z2, const float &z3) {
- // Create a vector in old coordinates along x axis of new coordinate
- const float p12[] = {
- delta_tower[B_AXIS][X_AXIS] - delta_tower[A_AXIS][X_AXIS],
- delta_tower[B_AXIS][Y_AXIS] - delta_tower[A_AXIS][Y_AXIS],
- z2 - z1
- },
-
- // Get the reciprocal of Magnitude of vector.
- d2 = sq(p12[0]) + sq(p12[1]) + sq(p12[2]), inv_d = RSQRT(d2),
-
- // Create unit vector by multiplying by the inverse of the magnitude.
- ex[3] = { p12[0] * inv_d, p12[1] * inv_d, p12[2] * inv_d },
-
- // Get the vector from the origin of the new system to the third point.
- p13[3] = {
- delta_tower[C_AXIS][X_AXIS] - delta_tower[A_AXIS][X_AXIS],
- delta_tower[C_AXIS][Y_AXIS] - delta_tower[A_AXIS][Y_AXIS],
- z3 - z1
- },
-
- // Use the dot product to find the component of this vector on the X axis.
- i = ex[0] * p13[0] + ex[1] * p13[1] + ex[2] * p13[2],
-
- // Create a vector along the x axis that represents the x component of p13.
- iex[] = { ex[0] * i, ex[1] * i, ex[2] * i };
-
- // Subtract the X component from the original vector leaving only Y. We use the
- // variable that will be the unit vector after we scale it.
- float ey[3] = { p13[0] - iex[0], p13[1] - iex[1], p13[2] - iex[2] };
-
- // The magnitude and the inverse of the magnitude of Y component
- const float j2 = sq(ey[0]) + sq(ey[1]) + sq(ey[2]), inv_j = RSQRT(j2);
-
- // Convert to a unit vector
- ey[0] *= inv_j; ey[1] *= inv_j; ey[2] *= inv_j;
-
- // The cross product of the unit x and y is the unit z
- // float[] ez = vectorCrossProd(ex, ey);
- const float ez[3] = {
- ex[1] * ey[2] - ex[2] * ey[1],
- ex[2] * ey[0] - ex[0] * ey[2],
- ex[0] * ey[1] - ex[1] * ey[0]
- },
- // We now have the d, i and j values defined in Wikipedia.
- // Plug them into the equations defined in Wikipedia for Xnew, Ynew and Znew
- Xnew = (delta_diagonal_rod_2_tower[A_AXIS] - delta_diagonal_rod_2_tower[B_AXIS] + d2) * inv_d * 0.5,
- Ynew = ((delta_diagonal_rod_2_tower[A_AXIS] - delta_diagonal_rod_2_tower[C_AXIS] + sq(i) + j2) * 0.5 - i * Xnew) * inv_j,
- Znew = SQRT(delta_diagonal_rod_2_tower[A_AXIS] - HYPOT2(Xnew, Ynew));
-
- // Start from the origin of the old coordinates and add vectors in the
- // old coords that represent the Xnew, Ynew and Znew to find the point
- // in the old system.
- cartes[X_AXIS] = delta_tower[A_AXIS][X_AXIS] + ex[0] * Xnew + ey[0] * Ynew - ez[0] * Znew;
- cartes[Y_AXIS] = delta_tower[A_AXIS][Y_AXIS] + ex[1] * Xnew + ey[1] * Ynew - ez[1] * Znew;
- cartes[Z_AXIS] = z1 + ex[2] * Xnew + ey[2] * Ynew - ez[2] * Znew;
- }
-
- void forward_kinematics_DELTA(const float (&point)[ABC]) {
- forward_kinematics_DELTA(point[A_AXIS], point[B_AXIS], point[C_AXIS]);
- }
-
-#endif // DELTA
-
-/**
- * Get the stepper positions in the cartes[] array.
- * Forward kinematics are applied for DELTA and SCARA.
- *
- * The result is in the current coordinate space with
- * leveling applied. The coordinates need to be run through
- * unapply_leveling to obtain machine coordinates suitable
- * for current_position, etc.
- */
-void get_cartesian_from_steppers() {
- #if ENABLED(DELTA)
- forward_kinematics_DELTA(
- planner.get_axis_position_mm(A_AXIS),
- planner.get_axis_position_mm(B_AXIS),
- planner.get_axis_position_mm(C_AXIS)
- );
- #else
- #if IS_SCARA
- forward_kinematics_SCARA(
- planner.get_axis_position_degrees(A_AXIS),
- planner.get_axis_position_degrees(B_AXIS)
- );
- #else
- cartes[X_AXIS] = planner.get_axis_position_mm(X_AXIS);
- cartes[Y_AXIS] = planner.get_axis_position_mm(Y_AXIS);
- #endif
- cartes[Z_AXIS] = planner.get_axis_position_mm(Z_AXIS);
- #endif
-}
-
-/**
- * Set the current_position for an axis based on
- * the stepper positions, removing any leveling that
- * may have been applied.
- *
- * To prevent small shifts in axis position always call
- * SYNC_PLAN_POSITION_KINEMATIC after updating axes with this.
- *
- * To keep hosts in sync, always call report_current_position
- * after updating the current_position.
- */
-void set_current_from_steppers_for_axis(const AxisEnum axis) {
- get_cartesian_from_steppers();
- #if PLANNER_LEVELING
- planner.unapply_leveling(cartes);
- #endif
- if (axis == ALL_AXES)
- COPY(current_position, cartes);
- else
- current_position[axis] = cartes[axis];
-}
-
-#if IS_CARTESIAN
-#if ENABLED(SEGMENT_LEVELED_MOVES)
-
- /**
- * Prepare a segmented move on a CARTESIAN setup.
- *
- * This calls planner.buffer_line several times, adding
- * small incremental moves. This allows the planner to
- * apply more detailed bed leveling to the full move.
- */
- inline void segmented_line_to_destination(const float &fr_mm_s, const float segment_size=LEVELED_SEGMENT_LENGTH) {
-
- const float xdiff = destination[X_AXIS] - current_position[X_AXIS],
- ydiff = destination[Y_AXIS] - current_position[Y_AXIS];
-
- // If the move is only in Z/E don't split up the move
- if (!xdiff && !ydiff) {
- planner.buffer_line_kinematic(destination, fr_mm_s, active_extruder);
- return;
- }
-
- // Remaining cartesian distances
- const float zdiff = destination[Z_AXIS] - current_position[Z_AXIS],
- ediff = destination[E_AXIS] - current_position[E_AXIS];
-
- // Get the linear distance in XYZ
- // If the move is very short, check the E move distance
- // No E move either? Game over.
- float cartesian_mm = SQRT(sq(xdiff) + sq(ydiff) + sq(zdiff));
- if (UNEAR_ZERO(cartesian_mm)) cartesian_mm = ABS(ediff);
- if (UNEAR_ZERO(cartesian_mm)) return;
-
- // The length divided by the segment size
- // At least one segment is required
- uint16_t segments = cartesian_mm / segment_size;
- NOLESS(segments, 1);
-
- // The approximate length of each segment
- const float inv_segments = 1.0f / float(segments),
- cartesian_segment_mm = cartesian_mm * inv_segments,
- segment_distance[XYZE] = {
- xdiff * inv_segments,
- ydiff * inv_segments,
- zdiff * inv_segments,
- ediff * inv_segments
- };
-
- // SERIAL_ECHOPAIR("mm=", cartesian_mm);
- // SERIAL_ECHOLNPAIR(" segments=", segments);
- // SERIAL_ECHOLNPAIR(" segment_mm=", cartesian_segment_mm);
-
- // Get the raw current position as starting point
- float raw[XYZE];
- COPY(raw, current_position);
-
- // Calculate and execute the segments
- while (--segments) {
- static millis_t next_idle_ms = millis() + 200UL;
- thermalManager.manage_heater(); // This returns immediately if not really needed.
- if (ELAPSED(millis(), next_idle_ms)) {
- next_idle_ms = millis() + 200UL;
- idle();
- }
- LOOP_XYZE(i) raw[i] += segment_distance[i];
- if (!planner.buffer_line_kinematic(raw, fr_mm_s, active_extruder, cartesian_segment_mm))
- break;
- }
-
- // Since segment_distance is only approximate,
- // the final move must be to the exact destination.
- planner.buffer_line_kinematic(destination, fr_mm_s, active_extruder, cartesian_segment_mm);
- }
-
-#elif ENABLED(MESH_BED_LEVELING)
-
- /**
- * Prepare a mesh-leveled linear move in a Cartesian setup,
- * splitting the move where it crosses mesh borders.
- */
- void mesh_line_to_destination(const float fr_mm_s, uint8_t x_splits=0xFF, uint8_t y_splits=0xFF) {
- // Get current and destination cells for this line
- int cx1 = mbl.cell_index_x(current_position[X_AXIS]),
- cy1 = mbl.cell_index_y(current_position[Y_AXIS]),
- cx2 = mbl.cell_index_x(destination[X_AXIS]),
- cy2 = mbl.cell_index_y(destination[Y_AXIS]);
- NOMORE(cx1, GRID_MAX_POINTS_X - 2);
- NOMORE(cy1, GRID_MAX_POINTS_Y - 2);
- NOMORE(cx2, GRID_MAX_POINTS_X - 2);
- NOMORE(cy2, GRID_MAX_POINTS_Y - 2);
-
- // Start and end in the same cell? No split needed.
- if (cx1 == cx2 && cy1 == cy2) {
- buffer_line_to_destination(fr_mm_s);
- set_current_from_destination();
- return;
- }
-
- #define MBL_SEGMENT_END(A) (current_position[_AXIS(A)] + (destination[_AXIS(A)] - current_position[_AXIS(A)]) * normalized_dist)
-
- float normalized_dist, end[XYZE];
- const int8_t gcx = MAX(cx1, cx2), gcy = MAX(cy1, cy2);
-
- // Crosses on the X and not already split on this X?
- // The x_splits flags are insurance against rounding errors.
- if (cx2 != cx1 && TEST(x_splits, gcx)) {
- // Split on the X grid line
- CBI(x_splits, gcx);
- COPY(end, destination);
- destination[X_AXIS] = mbl.index_to_xpos[gcx];
- normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
- destination[Y_AXIS] = MBL_SEGMENT_END(Y);
- }
- // Crosses on the Y and not already split on this Y?
- else if (cy2 != cy1 && TEST(y_splits, gcy)) {
- // Split on the Y grid line
- CBI(y_splits, gcy);
- COPY(end, destination);
- destination[Y_AXIS] = mbl.index_to_ypos[gcy];
- normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
- destination[X_AXIS] = MBL_SEGMENT_END(X);
- }
- else {
- // Must already have been split on these border(s)
- buffer_line_to_destination(fr_mm_s);
- set_current_from_destination();
- return;
- }
-
- destination[Z_AXIS] = MBL_SEGMENT_END(Z);
- destination[E_AXIS] = MBL_SEGMENT_END(E);
-
- // Do the split and look for more borders
- mesh_line_to_destination(fr_mm_s, x_splits, y_splits);
-
- // Restore destination from stack
- COPY(destination, end);
- mesh_line_to_destination(fr_mm_s, x_splits, y_splits);
- }
-
-#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
-
- #define CELL_INDEX(A,V) ((V - bilinear_start[_AXIS(A)]) * ABL_BG_FACTOR(_AXIS(A)))
-
- /**
- * Prepare a bilinear-leveled linear move on Cartesian,
- * splitting the move where it crosses grid borders.
- */
- void bilinear_line_to_destination(const float fr_mm_s, uint16_t x_splits=0xFFFF, uint16_t y_splits=0xFFFF) {
- // Get current and destination cells for this line
- int cx1 = CELL_INDEX(X, current_position[X_AXIS]),
- cy1 = CELL_INDEX(Y, current_position[Y_AXIS]),
- cx2 = CELL_INDEX(X, destination[X_AXIS]),
- cy2 = CELL_INDEX(Y, destination[Y_AXIS]);
- cx1 = constrain(cx1, 0, ABL_BG_POINTS_X - 2);
- cy1 = constrain(cy1, 0, ABL_BG_POINTS_Y - 2);
- cx2 = constrain(cx2, 0, ABL_BG_POINTS_X - 2);
- cy2 = constrain(cy2, 0, ABL_BG_POINTS_Y - 2);
-
- // Start and end in the same cell? No split needed.
- if (cx1 == cx2 && cy1 == cy2) {
- buffer_line_to_destination(fr_mm_s);
- set_current_from_destination();
- return;
- }
-
- #define LINE_SEGMENT_END(A) (current_position[_AXIS(A)] + (destination[_AXIS(A)] - current_position[_AXIS(A)]) * normalized_dist)
-
- float normalized_dist, end[XYZE];
- const int8_t gcx = MAX(cx1, cx2), gcy = MAX(cy1, cy2);
-
- // Crosses on the X and not already split on this X?
- // The x_splits flags are insurance against rounding errors.
- if (cx2 != cx1 && TEST(x_splits, gcx)) {
- // Split on the X grid line
- CBI(x_splits, gcx);
- COPY(end, destination);
- destination[X_AXIS] = bilinear_start[X_AXIS] + ABL_BG_SPACING(X_AXIS) * gcx;
- normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
- destination[Y_AXIS] = LINE_SEGMENT_END(Y);
- }
- // Crosses on the Y and not already split on this Y?
- else if (cy2 != cy1 && TEST(y_splits, gcy)) {
- // Split on the Y grid line
- CBI(y_splits, gcy);
- COPY(end, destination);
- destination[Y_AXIS] = bilinear_start[Y_AXIS] + ABL_BG_SPACING(Y_AXIS) * gcy;
- normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
- destination[X_AXIS] = LINE_SEGMENT_END(X);
- }
- else {
- // Must already have been split on these border(s)
- buffer_line_to_destination(fr_mm_s);
- set_current_from_destination();
- return;
- }
-
- destination[Z_AXIS] = LINE_SEGMENT_END(Z);
- destination[E_AXIS] = LINE_SEGMENT_END(E);
-
- // Do the split and look for more borders
- bilinear_line_to_destination(fr_mm_s, x_splits, y_splits);
-
- // Restore destination from stack
- COPY(destination, end);
- bilinear_line_to_destination(fr_mm_s, x_splits, y_splits);
- }
-
-#endif // AUTO_BED_LEVELING_BILINEAR
-#endif // IS_CARTESIAN
-
-#if !UBL_SEGMENTED
-#if IS_KINEMATIC
-
- #if IS_SCARA
- /**
- * Before raising this value, use M665 S[seg_per_sec] to decrease
- * the number of segments-per-second. Default is 200. Some deltas
- * do better with 160 or lower. It would be good to know how many
- * segments-per-second are actually possible for SCARA on AVR.
- *
- * Longer segments result in less kinematic overhead
- * but may produce jagged lines. Try 0.5mm, 1.0mm, and 2.0mm
- * and compare the difference.
- */
- #define SCARA_MIN_SEGMENT_LENGTH 0.5f
- #endif
-
- /**
- * Prepare a linear move in a DELTA or SCARA setup.
- *
- * This calls planner.buffer_line several times, adding
- * small incremental moves for DELTA or SCARA.
- *
- * For Unified Bed Leveling (Delta or Segmented Cartesian)
- * the ubl.prepare_segmented_line_to method replaces this.
- */
- inline bool prepare_kinematic_move_to(const float (&rtarget)[XYZE]) {
-
- // Get the top feedrate of the move in the XY plane
- const float _feedrate_mm_s = MMS_SCALED(feedrate_mm_s);
-
- const float xdiff = rtarget[X_AXIS] - current_position[X_AXIS],
- ydiff = rtarget[Y_AXIS] - current_position[Y_AXIS];
-
- // If the move is only in Z/E don't split up the move
- if (!xdiff && !ydiff) {
- planner.buffer_line_kinematic(rtarget, _feedrate_mm_s, active_extruder);
- return false; // caller will update current_position
- }
-
- // Fail if attempting move outside printable radius
- if (!position_is_reachable(rtarget[X_AXIS], rtarget[Y_AXIS])) return true;
-
- // Remaining cartesian distances
- const float zdiff = rtarget[Z_AXIS] - current_position[Z_AXIS],
- ediff = rtarget[E_AXIS] - current_position[E_AXIS];
-
- // Get the linear distance in XYZ
- // If the move is very short, check the E move distance
- // No E move either? Game over.
- float cartesian_mm = SQRT(sq(xdiff) + sq(ydiff) + sq(zdiff));
- if (UNEAR_ZERO(cartesian_mm)) cartesian_mm = ABS(ediff);
- if (UNEAR_ZERO(cartesian_mm)) return true;
-
- // Minimum number of seconds to move the given distance
- const float seconds = cartesian_mm / _feedrate_mm_s;
-
- // The number of segments-per-second times the duration
- // gives the number of segments
- uint16_t segments = delta_segments_per_second * seconds;
-
- // For SCARA enforce a minimum segment size
- #if IS_SCARA
- NOMORE(segments, cartesian_mm * (1.0f / float(SCARA_MIN_SEGMENT_LENGTH)));
- #endif
-
- // At least one segment is required
- NOLESS(segments, 1);
-
- // The approximate length of each segment
- const float inv_segments = 1.0f / float(segments),
- segment_distance[XYZE] = {
- xdiff * inv_segments,
- ydiff * inv_segments,
- zdiff * inv_segments,
- ediff * inv_segments
- };
-
- #if !HAS_FEEDRATE_SCALING
- const float cartesian_segment_mm = cartesian_mm * inv_segments;
- #endif
-
- /*
- SERIAL_ECHOPAIR("mm=", cartesian_mm);
- SERIAL_ECHOPAIR(" seconds=", seconds);
- SERIAL_ECHOPAIR(" segments=", segments);
- #if !HAS_FEEDRATE_SCALING
- SERIAL_ECHOPAIR(" segment_mm=", cartesian_segment_mm);
- #endif
- SERIAL_EOL();
- //*/
-
- #if HAS_FEEDRATE_SCALING
- // SCARA needs to scale the feed rate from mm/s to degrees/s
- // i.e., Complete the angular vector in the given time.
- const float segment_length = cartesian_mm * inv_segments,
- inv_segment_length = 1.0f / segment_length, // 1/mm/segs
- inverse_secs = inv_segment_length * _feedrate_mm_s;
-
- float oldA = planner.position_float[A_AXIS],
- oldB = planner.position_float[B_AXIS]
- #if ENABLED(DELTA_FEEDRATE_SCALING)
- , oldC = planner.position_float[C_AXIS]
- #endif
- ;
-
- /*
- SERIAL_ECHOPGM("Scaled kinematic move: ");
- SERIAL_ECHOPAIR(" segment_length (inv)=", segment_length);
- SERIAL_ECHOPAIR(" (", inv_segment_length);
- SERIAL_ECHOPAIR(") _feedrate_mm_s=", _feedrate_mm_s);
- SERIAL_ECHOPAIR(" inverse_secs=", inverse_secs);
- SERIAL_ECHOPAIR(" oldA=", oldA);
- SERIAL_ECHOPAIR(" oldB=", oldB);
- #if ENABLED(DELTA_FEEDRATE_SCALING)
- SERIAL_ECHOPAIR(" oldC=", oldC);
- #endif
- SERIAL_EOL();
- safe_delay(5);
- //*/
- #endif
-
- // Get the current position as starting point
- float raw[XYZE];
- COPY(raw, current_position);
-
- // Calculate and execute the segments
- while (--segments) {
-
- static millis_t next_idle_ms = millis() + 200UL;
- thermalManager.manage_heater(); // This returns immediately if not really needed.
- if (ELAPSED(millis(), next_idle_ms)) {
- next_idle_ms = millis() + 200UL;
- idle();
- }
-
- LOOP_XYZE(i) raw[i] += segment_distance[i];
- #if ENABLED(DELTA) && HOTENDS < 2
- DELTA_IK(raw); // Delta can inline its kinematics
- #else
- inverse_kinematics(raw);
- #endif
-
- ADJUST_DELTA(raw); // Adjust Z if bed leveling is enabled
-
- #if ENABLED(SCARA_FEEDRATE_SCALING)
- // For SCARA scale the feed rate from mm/s to degrees/s
- // i.e., Complete the angular vector in the given time.
- if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], raw[Z_AXIS], raw[E_AXIS], HYPOT(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB) * inverse_secs, active_extruder))
- break;
- /*
- SERIAL_ECHO(segments);
- SERIAL_ECHOPAIR(": X=", raw[X_AXIS]); SERIAL_ECHOPAIR(" Y=", raw[Y_AXIS]);
- SERIAL_ECHOPAIR(" A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]);
- SERIAL_ECHOLNPAIR(" F", HYPOT(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB) * inverse_secs * 60);
- safe_delay(5);
- //*/
- oldA = delta[A_AXIS]; oldB = delta[B_AXIS];
- #elif ENABLED(DELTA_FEEDRATE_SCALING)
- // For DELTA scale the feed rate from Effector mm/s to Carriage mm/s
- // i.e., Complete the linear vector in the given time.
- if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], SQRT(sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC)) * inverse_secs, active_extruder))
- break;
- /*
- SERIAL_ECHO(segments);
- SERIAL_ECHOPAIR(": X=", raw[X_AXIS]); SERIAL_ECHOPAIR(" Y=", raw[Y_AXIS]);
- SERIAL_ECHOPAIR(" A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]); SERIAL_ECHOPAIR(" C=", delta[C_AXIS]);
- SERIAL_ECHOLNPAIR(" F", SQRT(sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC)) * inverse_secs * 60);
- safe_delay(5);
- //*/
- oldA = delta[A_AXIS]; oldB = delta[B_AXIS]; oldC = delta[C_AXIS];
- #else
- if (!planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], _feedrate_mm_s, active_extruder, cartesian_segment_mm))
- break;
- #endif
- }
-
- // Ensure last segment arrives at target location.
- #if HAS_FEEDRATE_SCALING
- inverse_kinematics(rtarget);
- ADJUST_DELTA(rtarget);
- #endif
-
- #if ENABLED(SCARA_FEEDRATE_SCALING)
- const float diff2 = HYPOT2(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB);
- if (diff2) {
- planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], rtarget[Z_AXIS], rtarget[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder);
- /*
- SERIAL_ECHOPAIR("final: A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]);
- SERIAL_ECHOPAIR(" adiff=", delta[A_AXIS] - oldA); SERIAL_ECHOPAIR(" bdiff=", delta[B_AXIS] - oldB);
- SERIAL_ECHOLNPAIR(" F", SQRT(diff2) * inverse_secs * 60);
- SERIAL_EOL();
- safe_delay(5);
- //*/
- }
- #elif ENABLED(DELTA_FEEDRATE_SCALING)
- const float diff2 = sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC);
- if (diff2) {
- planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], rtarget[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder);
- /*
- SERIAL_ECHOPAIR("final: A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]); SERIAL_ECHOPAIR(" C=", delta[C_AXIS]);
- SERIAL_ECHOPAIR(" adiff=", delta[A_AXIS] - oldA); SERIAL_ECHOPAIR(" bdiff=", delta[B_AXIS] - oldB); SERIAL_ECHOPAIR(" cdiff=", delta[C_AXIS] - oldC);
- SERIAL_ECHOLNPAIR(" F", SQRT(diff2) * inverse_secs * 60);
- SERIAL_EOL();
- safe_delay(5);
- //*/
- }
- #else
- planner.buffer_line_kinematic(rtarget, _feedrate_mm_s, active_extruder, cartesian_segment_mm);
- #endif
-
- return false; // caller will update current_position
- }
-
-#else // !IS_KINEMATIC
-
- /**
- * Prepare a linear move in a Cartesian setup.
- *
- * When a mesh-based leveling system is active, moves are segmented
- * according to the configuration of the leveling system.
- *
- * Returns true if current_position[] was set to destination[]
- */
- inline bool prepare_move_to_destination_cartesian() {
- #if HAS_MESH
- if (planner.leveling_active && planner.leveling_active_at_z(destination[Z_AXIS])) {
- #if ENABLED(AUTO_BED_LEVELING_UBL)
- ubl.line_to_destination_cartesian(MMS_SCALED(feedrate_mm_s), active_extruder); // UBL's motion routine needs to know about
- return true; // all moves, including Z-only moves.
- #elif ENABLED(SEGMENT_LEVELED_MOVES)
- segmented_line_to_destination(MMS_SCALED(feedrate_mm_s));
- return false; // caller will update current_position
- #else
- /**
- * For MBL and ABL-BILINEAR only segment moves when X or Y are involved.
- * Otherwise fall through to do a direct single move.
- */
- if (current_position[X_AXIS] != destination[X_AXIS] || current_position[Y_AXIS] != destination[Y_AXIS]) {
- #if ENABLED(MESH_BED_LEVELING)
- mesh_line_to_destination(MMS_SCALED(feedrate_mm_s));
- #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
- bilinear_line_to_destination(MMS_SCALED(feedrate_mm_s));
- #endif
- return true;
- }
- #endif
- }
- #endif // HAS_MESH
-
- buffer_line_to_destination(MMS_SCALED(feedrate_mm_s));
- return false; // caller will update current_position
- }
-
-#endif // !IS_KINEMATIC
-#endif // !UBL_SEGMENTED
-
-#if ENABLED(DUAL_X_CARRIAGE)
-
- /**
- * Unpark the carriage, if needed
- */
- inline bool dual_x_carriage_unpark() {
- if (active_extruder_parked)
- switch (dual_x_carriage_mode) {
-
- case DXC_FULL_CONTROL_MODE: break;
-
- case DXC_AUTO_PARK_MODE:
- if (current_position[E_AXIS] == destination[E_AXIS]) {
- // This is a travel move (with no extrusion)
- // Skip it, but keep track of the current position
- // (so it can be used as the start of the next non-travel move)
- if (delayed_move_time != 0xFFFFFFFFUL) {
- set_current_from_destination();
- NOLESS(raised_parked_position[Z_AXIS], destination[Z_AXIS]);
- delayed_move_time = millis();
- return true;
- }
- }
- // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower
- for (uint8_t i = 0; i < 3; i++)
- if (!planner.buffer_line(
- i == 0 ? raised_parked_position[X_AXIS] : current_position[X_AXIS],
- i == 0 ? raised_parked_position[Y_AXIS] : current_position[Y_AXIS],
- i == 2 ? current_position[Z_AXIS] : raised_parked_position[Z_AXIS],
- current_position[E_AXIS],
- i == 1 ? PLANNER_XY_FEEDRATE() : planner.max_feedrate_mm_s[Z_AXIS],
- active_extruder)
- ) break;
- delayed_move_time = 0;
- active_extruder_parked = false;
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Clear active_extruder_parked");
- #endif
- break;
-
- case DXC_DUPLICATION_MODE:
- if (active_extruder == 0) {
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) {
- SERIAL_ECHOPAIR("Set planner X", inactive_extruder_x_pos);
- SERIAL_ECHOLNPAIR(" ... Line to X", current_position[X_AXIS] + duplicate_extruder_x_offset);
- }
- #endif
- // move duplicate extruder into correct duplication position.
- planner.set_position_mm(inactive_extruder_x_pos, current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
- if (!planner.buffer_line(
- current_position[X_AXIS] + duplicate_extruder_x_offset,
- current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS],
- planner.max_feedrate_mm_s[X_AXIS], 1)
- ) break;
- planner.synchronize();
- SYNC_PLAN_POSITION_KINEMATIC();
- extruder_duplication_enabled = true;
- active_extruder_parked = false;
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Set extruder_duplication_enabled\nClear active_extruder_parked");
- #endif
- }
- else {
- #if ENABLED(DEBUG_LEVELING_FEATURE)
- if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Active extruder not 0");
- #endif
- }
- break;
- }
- return false;
- }
-
-#endif // DUAL_X_CARRIAGE
-
-/**
- * Prepare a single move and get ready for the next one
- *
- * This may result in several calls to planner.buffer_line to
- * do smaller moves for DELTA, SCARA, mesh moves, etc.
- *
- * Make sure current_position[E] and destination[E] are good
- * before calling or cold/lengthy extrusion may get missed.
- */
-void prepare_move_to_destination() {
- clamp_to_software_endstops(destination);
-
- #if ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE)
-
- if (!DEBUGGING(DRYRUN)) {
- if (destination[E_AXIS] != current_position[E_AXIS]) {
- #if ENABLED(PREVENT_COLD_EXTRUSION)
- if (thermalManager.tooColdToExtrude(active_extruder)) {
- current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP);
- }
- #endif // PREVENT_COLD_EXTRUSION
- #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
- if (ABS(destination[E_AXIS] - current_position[E_AXIS]) * planner.e_factor[active_extruder] > (EXTRUDE_MAXLENGTH)) {
- current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP);
- }
- #endif // PREVENT_LENGTHY_EXTRUDE
- }
- }
-
- #endif
-
- #if ENABLED(DUAL_X_CARRIAGE)
- if (dual_x_carriage_unpark()) return;
- #endif
-
- if (
- #if UBL_SEGMENTED
- ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s))
- #elif IS_KINEMATIC
- prepare_kinematic_move_to(destination)
- #else
- prepare_move_to_destination_cartesian()
- #endif
- ) return;
-
- set_current_from_destination();
-}
-
-#if ENABLED(ARC_SUPPORT)
-
- #if N_ARC_CORRECTION < 1
- #undef N_ARC_CORRECTION
- #define N_ARC_CORRECTION 1
- #endif
-
- /**
- * Plan an arc in 2 dimensions
- *
- * The arc is approximated by generating many small linear segments.
- * The length of each segment is configured in MM_PER_ARC_SEGMENT (Default 1mm)
- * Arcs should only be made relatively large (over 5mm), as larger arcs with
- * larger segments will tend to be more efficient. Your slicer should have
- * options for G2/G3 arc generation. In future these options may be GCode tunable.
- */
- void plan_arc(
- const float (&cart)[XYZE], // Destination position
- const float (&offset)[2], // Center of rotation relative to current_position
- const bool clockwise // Clockwise?
- ) {
- #if ENABLED(CNC_WORKSPACE_PLANES)
- AxisEnum p_axis, q_axis, l_axis;
- switch (workspace_plane) {
- default:
- case PLANE_XY: p_axis = X_AXIS; q_axis = Y_AXIS; l_axis = Z_AXIS; break;
- case PLANE_ZX: p_axis = Z_AXIS; q_axis = X_AXIS; l_axis = Y_AXIS; break;
- case PLANE_YZ: p_axis = Y_AXIS; q_axis = Z_AXIS; l_axis = X_AXIS; break;
- }
- #else
- constexpr AxisEnum p_axis = X_AXIS, q_axis = Y_AXIS, l_axis = Z_AXIS;
- #endif
-
- // Radius vector from center to current location
- float r_P = -offset[0], r_Q = -offset[1];
-
- const float radius = HYPOT(r_P, r_Q),
- center_P = current_position[p_axis] - r_P,
- center_Q = current_position[q_axis] - r_Q,
- rt_X = cart[p_axis] - center_P,
- rt_Y = cart[q_axis] - center_Q,
- linear_travel = cart[l_axis] - current_position[l_axis],
- extruder_travel = cart[E_AXIS] - current_position[E_AXIS];
-
- // CCW angle of rotation between position and target from the circle center. Only one atan2() trig computation required.
- float angular_travel = ATAN2(r_P * rt_Y - r_Q * rt_X, r_P * rt_X + r_Q * rt_Y);
- if (angular_travel < 0) angular_travel += RADIANS(360);
- if (clockwise) angular_travel -= RADIANS(360);
-
- // Make a circle if the angular rotation is 0 and the target is current position
- if (angular_travel == 0 && current_position[p_axis] == cart[p_axis] && current_position[q_axis] == cart[q_axis])
- angular_travel = RADIANS(360);
-
- const float flat_mm = radius * angular_travel,
- mm_of_travel = linear_travel ? HYPOT(flat_mm, linear_travel) : ABS(flat_mm);
- if (mm_of_travel < 0.001f) return;
-
- uint16_t segments = FLOOR(mm_of_travel / (MM_PER_ARC_SEGMENT));
- NOLESS(segments, 1);
-
- /**
- * Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector,
- * and phi is the angle of rotation. Based on the solution approach by Jens Geisler.
- * r_T = [cos(phi) -sin(phi);
- * sin(phi) cos(phi)] * r ;
- *
- * For arc generation, the center of the circle is the axis of rotation and the radius vector is
- * defined from the circle center to the initial position. Each line segment is formed by successive
- * vector rotations. This requires only two cos() and sin() computations to form the rotation
- * matrix for the duration of the entire arc. Error may accumulate from numerical round-off, since
- * all double numbers are single precision on the Arduino. (True double precision will not have
- * round off issues for CNC applications.) Single precision error can accumulate to be greater than
- * tool precision in some cases. Therefore, arc path correction is implemented.
- *
- * Small angle approximation may be used to reduce computation overhead further. This approximation
- * holds for everything, but very small circles and large MM_PER_ARC_SEGMENT values. In other words,
- * theta_per_segment would need to be greater than 0.1 rad and N_ARC_CORRECTION would need to be large
- * to cause an appreciable drift error. N_ARC_CORRECTION~=25 is more than small enough to correct for
- * numerical drift error. N_ARC_CORRECTION may be on the order a hundred(s) before error becomes an
- * issue for CNC machines with the single precision Arduino calculations.
- *
- * This approximation also allows plan_arc to immediately insert a line segment into the planner
- * without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied
- * a correction, the planner should have caught up to the lag caused by the initial plan_arc overhead.
- * This is important when there are successive arc motions.
- */
- // Vector rotation matrix values
- float raw[XYZE];
- const float theta_per_segment = angular_travel / segments,
- linear_per_segment = linear_travel / segments,
- extruder_per_segment = extruder_travel / segments,
- sin_T = theta_per_segment,
- cos_T = 1 - 0.5f * sq(theta_per_segment); // Small angle approximation
-
- // Initialize the linear axis
- raw[l_axis] = current_position[l_axis];
-
- // Initialize the extruder axis
- raw[E_AXIS] = current_position[E_AXIS];
-
- const float fr_mm_s = MMS_SCALED(feedrate_mm_s);
-
- millis_t next_idle_ms = millis() + 200UL;
-
- #if HAS_FEEDRATE_SCALING
- // SCARA needs to scale the feed rate from mm/s to degrees/s
- const float inv_segment_length = 1.0f / (MM_PER_ARC_SEGMENT),
- inverse_secs = inv_segment_length * fr_mm_s;
- float oldA = planner.position_float[A_AXIS],
- oldB = planner.position_float[B_AXIS]
- #if ENABLED(DELTA_FEEDRATE_SCALING)
- , oldC = planner.position_float[C_AXIS]
- #endif
- ;
- #endif
-
- #if N_ARC_CORRECTION > 1
- int8_t arc_recalc_count = N_ARC_CORRECTION;
- #endif
-
- for (uint16_t i = 1; i < segments; i++) { // Iterate (segments-1) times
-
- thermalManager.manage_heater();
- if (ELAPSED(millis(), next_idle_ms)) {
- next_idle_ms = millis() + 200UL;
- idle();
- }
-
- #if N_ARC_CORRECTION > 1
- if (--arc_recalc_count) {
- // Apply vector rotation matrix to previous r_P / 1
- const float r_new_Y = r_P * sin_T + r_Q * cos_T;
- r_P = r_P * cos_T - r_Q * sin_T;
- r_Q = r_new_Y;
- }
- else
- #endif
- {
- #if N_ARC_CORRECTION > 1
- arc_recalc_count = N_ARC_CORRECTION;
- #endif
-
- // Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments.
- // Compute exact location by applying transformation matrix from initial radius vector(=-offset).
- // To reduce stuttering, the sin and cos could be computed at different times.
- // For now, compute both at the same time.
- const float cos_Ti = cos(i * theta_per_segment), sin_Ti = sin(i * theta_per_segment);
- r_P = -offset[0] * cos_Ti + offset[1] * sin_Ti;
- r_Q = -offset[0] * sin_Ti - offset[1] * cos_Ti;
- }
-
- // Update raw location
- raw[p_axis] = center_P + r_P;
- raw[q_axis] = center_Q + r_Q;
- raw[l_axis] += linear_per_segment;
- raw[E_AXIS] += extruder_per_segment;
-
- clamp_to_software_endstops(raw);
-
- #if HAS_FEEDRATE_SCALING
- inverse_kinematics(raw);
- ADJUST_DELTA(raw);
- #endif
-
- #if ENABLED(SCARA_FEEDRATE_SCALING)
- // For SCARA scale the feed rate from mm/s to degrees/s
- // i.e., Complete the angular vector in the given time.
- if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], raw[Z_AXIS], raw[E_AXIS], HYPOT(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB) * inverse_secs, active_extruder))
- break;
- oldA = delta[A_AXIS]; oldB = delta[B_AXIS];
- #elif ENABLED(DELTA_FEEDRATE_SCALING)
- // For DELTA scale the feed rate from Effector mm/s to Carriage mm/s
- // i.e., Complete the linear vector in the given time.
- if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], SQRT(sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC)) * inverse_secs, active_extruder))
- break;
- oldA = delta[A_AXIS]; oldB = delta[B_AXIS]; oldC = delta[C_AXIS];
- #elif HAS_UBL_AND_CURVES
- float pos[XYZ] = { raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS] };
- planner.apply_leveling(pos);
- if (!planner.buffer_segment(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS], raw[E_AXIS], fr_mm_s, active_extruder))
- break;
- #else
- if (!planner.buffer_line_kinematic(raw, fr_mm_s, active_extruder))
- break;
- #endif
- }
-
- // Ensure last segment arrives at target location.
- #if HAS_FEEDRATE_SCALING
- inverse_kinematics(cart);
- ADJUST_DELTA(cart);
- #endif
-
- #if ENABLED(SCARA_FEEDRATE_SCALING)
- const float diff2 = HYPOT2(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB);
- if (diff2)
- planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], cart[Z_AXIS], cart[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder);
- #elif ENABLED(DELTA_FEEDRATE_SCALING)
- const float diff2 = sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC);
- if (diff2)
- planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder);
- #elif HAS_UBL_AND_CURVES
- float pos[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
- planner.apply_leveling(pos);
- planner.buffer_segment(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS], cart[E_AXIS], fr_mm_s, active_extruder);
- #else
- planner.buffer_line_kinematic(cart, fr_mm_s, active_extruder);
- #endif
-
- COPY(current_position, cart);
- } // plan_arc
-
-#endif // ARC_SUPPORT
-
-#if ENABLED(BEZIER_CURVE_SUPPORT)
-
- void plan_cubic_move(const float (&cart)[XYZE], const float (&offset)[4]) {
- cubic_b_spline(current_position, cart, offset, MMS_SCALED(feedrate_mm_s), active_extruder);
- COPY(current_position, cart);
- }
-
-#endif // BEZIER_CURVE_SUPPORT
-
-#if ENABLED(USE_CONTROLLER_FAN)
-
- void controllerFan() {
- static millis_t lastMotorOn = 0, // Last time a motor was turned on
- nextMotorCheck = 0; // Last time the state was checked
- const millis_t ms = millis();
- if (ELAPSED(ms, nextMotorCheck)) {
- nextMotorCheck = ms + 2500UL; // Not a time critical function, so only check every 2.5s
- if (X_ENABLE_READ == X_ENABLE_ON || Y_ENABLE_READ == Y_ENABLE_ON || Z_ENABLE_READ == Z_ENABLE_ON
- #if HAS_HEATED_BED
- || thermalManager.soft_pwm_amount_bed > 0
- #endif
- || E0_ENABLE_READ == E_ENABLE_ON // If any of the drivers are enabled...
- #if E_STEPPERS > 1
- || E1_ENABLE_READ == E_ENABLE_ON
- #if HAS_X2_ENABLE
- || X2_ENABLE_READ == X_ENABLE_ON
- #endif
- #if E_STEPPERS > 2
- || E2_ENABLE_READ == E_ENABLE_ON
- #if E_STEPPERS > 3
- || E3_ENABLE_READ == E_ENABLE_ON
- #if E_STEPPERS > 4
- || E4_ENABLE_READ == E_ENABLE_ON
- #endif // E_STEPPERS > 4
- #endif // E_STEPPERS > 3
- #endif // E_STEPPERS > 2
- #endif // E_STEPPERS > 1
- ) {
- lastMotorOn = ms; //... set time to NOW so the fan will turn on
- }
-
- // Fan off if no steppers have been enabled for CONTROLLERFAN_SECS seconds
- const uint8_t speed = (lastMotorOn && PENDING(ms, lastMotorOn + (CONTROLLERFAN_SECS) * 1000UL)) ? CONTROLLERFAN_SPEED : 0;
- controllerFanSpeed = speed;
-
- // allows digital or PWM fan output to be used (see M42 handling)
- WRITE(CONTROLLER_FAN_PIN, speed);
- analogWrite(CONTROLLER_FAN_PIN, speed);
- }
- }
-
-#endif // USE_CONTROLLER_FAN
-
-#if ENABLED(MORGAN_SCARA)
-
- /**
- * Morgan SCARA Forward Kinematics. Results in cartes[].
- * Maths and first version by QHARLEY.
- * Integrated into Marlin and slightly restructured by Joachim Cerny.
- */
- void forward_kinematics_SCARA(const float &a, const float &b) {
-
- float a_sin = sin(RADIANS(a)) * L1,
- a_cos = cos(RADIANS(a)) * L1,
- b_sin = sin(RADIANS(b)) * L2,
- b_cos = cos(RADIANS(b)) * L2;
-
- cartes[X_AXIS] = a_cos + b_cos + SCARA_OFFSET_X; //theta
- cartes[Y_AXIS] = a_sin + b_sin + SCARA_OFFSET_Y; //theta+phi
-
- /*
- SERIAL_ECHOPAIR("SCARA FK Angle a=", a);
- SERIAL_ECHOPAIR(" b=", b);
- SERIAL_ECHOPAIR(" a_sin=", a_sin);
- SERIAL_ECHOPAIR(" a_cos=", a_cos);
- SERIAL_ECHOPAIR(" b_sin=", b_sin);
- SERIAL_ECHOLNPAIR(" b_cos=", b_cos);
- SERIAL_ECHOPAIR(" cartes[X_AXIS]=", cartes[X_AXIS]);
- SERIAL_ECHOLNPAIR(" cartes[Y_AXIS]=", cartes[Y_AXIS]);
- //*/
- }
-
- /**
- * Morgan SCARA Inverse Kinematics. Results in delta[].
- *
- * See http://forums.reprap.org/read.php?185,283327
- *
- * Maths and first version by QHARLEY.
- * Integrated into Marlin and slightly restructured by Joachim Cerny.
- */
- void inverse_kinematics(const float raw[XYZ]) {
-
- static float C2, S2, SK1, SK2, THETA, PSI;
-
- float sx = raw[X_AXIS] - SCARA_OFFSET_X, // Translate SCARA to standard X Y
- sy = raw[Y_AXIS] - SCARA_OFFSET_Y; // With scaling factor.
-
- if (L1 == L2)
- C2 = HYPOT2(sx, sy) / L1_2_2 - 1;
- else
- C2 = (HYPOT2(sx, sy) - (L1_2 + L2_2)) / (2.0 * L1 * L2);
-
- S2 = SQRT(1 - sq(C2));
-
- // Unrotated Arm1 plus rotated Arm2 gives the distance from Center to End
- SK1 = L1 + L2 * C2;
-
- // Rotated Arm2 gives the distance from Arm1 to Arm2
- SK2 = L2 * S2;
-
- // Angle of Arm1 is the difference between Center-to-End angle and the Center-to-Elbow
- THETA = ATAN2(SK1, SK2) - ATAN2(sx, sy);
-
- // Angle of Arm2
- PSI = ATAN2(S2, C2);
-
- delta[A_AXIS] = DEGREES(THETA); // theta is support arm angle
- delta[B_AXIS] = DEGREES(THETA + PSI); // equal to sub arm angle (inverted motor)
- delta[C_AXIS] = raw[Z_AXIS];
-
- /*
- DEBUG_POS("SCARA IK", raw);
- DEBUG_POS("SCARA IK", delta);
- SERIAL_ECHOPAIR(" SCARA (x,y) ", sx);
- SERIAL_ECHOPAIR(",", sy);
- SERIAL_ECHOPAIR(" C2=", C2);
- SERIAL_ECHOPAIR(" S2=", S2);
- SERIAL_ECHOPAIR(" Theta=", THETA);
- SERIAL_ECHOLNPAIR(" Phi=", PHI);
- //*/
- }
-
-#endif // MORGAN_SCARA
-
-#if ENABLED(TEMP_STAT_LEDS)
-
- static bool red_led = false;
- static millis_t next_status_led_update_ms = 0;
-
- void handle_status_leds(void) {
- if (ELAPSED(millis(), next_status_led_update_ms)) {
- next_status_led_update_ms += 500; // Update every 0.5s
- float max_temp = 0.0;
- #if HAS_HEATED_BED
- max_temp = MAX3(max_temp, thermalManager.degTargetBed(), thermalManager.degBed());
- #endif
- HOTEND_LOOP()
- max_temp = MAX3(max_temp, thermalManager.degHotend(e), thermalManager.degTargetHotend(e));
- const bool new_led = (max_temp > 55.0) ? true : (max_temp < 54.0) ? false : red_led;
- if (new_led != red_led) {
- red_led = new_led;
- #if PIN_EXISTS(STAT_LED_RED)
- WRITE(STAT_LED_RED_PIN, new_led ? HIGH : LOW);
- #if PIN_EXISTS(STAT_LED_BLUE)
- WRITE(STAT_LED_BLUE_PIN, new_led ? LOW : HIGH);
- #endif
- #else
- WRITE(STAT_LED_BLUE_PIN, new_led ? HIGH : LOW);
- #endif
- }
- }
- }
-
-#endif
-
-void enable_all_steppers() {
- #if ENABLED(AUTO_POWER_CONTROL)
- powerManager.power_on();
- #endif
- enable_X();
- enable_Y();
- enable_Z();
- enable_E0();
- enable_E1();
- enable_E2();
- enable_E3();
- enable_E4();
-}
-
-void disable_e_stepper(const uint8_t e) {
- switch (e) {
- case 0: disable_E0(); break;
- case 1: disable_E1(); break;
- case 2: disable_E2(); break;
- case 3: disable_E3(); break;
- case 4: disable_E4(); break;
- }
-}
-
-void disable_e_steppers() {
- disable_E0();
- disable_E1();
- disable_E2();
- disable_E3();
- disable_E4();
-}
-
-void disable_all_steppers() {
- disable_X();
- disable_Y();
- disable_Z();
- disable_e_steppers();
-}
-
-/**
- * Manage several activities:
- * - Check for Filament Runout
- * - Keep the command buffer full
- * - Check for maximum inactive time between commands
- * - Check for maximum inactive time between stepper commands
- * - Check if pin CHDK needs to go LOW
- * - Check for KILL button held down
- * - Check for HOME button held down
- * - Check if cooling fan needs to be switched on
- * - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT)
- */
-void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
-
- #if ENABLED(FILAMENT_RUNOUT_SENSOR)
- runout.run();
- #endif
-
- if (commands_in_queue < BUFSIZE) get_available_commands();
-
- const millis_t ms = millis();
-
- if (max_inactive_time && ELAPSED(ms, previous_move_ms + max_inactive_time)) {
- SERIAL_ERROR_START();
- SERIAL_ECHOLNPAIR(MSG_KILL_INACTIVE_TIME, parser.command_ptr);
- kill(PSTR(MSG_KILLED));
- }
-
- // Prevent steppers timing-out in the middle of M600
- #if ENABLED(ADVANCED_PAUSE_FEATURE) && ENABLED(PAUSE_PARK_NO_STEPPER_TIMEOUT)
- #define MOVE_AWAY_TEST !did_pause_print
- #else
- #define MOVE_AWAY_TEST true
- #endif
-
- if (stepper_inactive_time) {
- if (planner.has_blocks_queued())
- previous_move_ms = ms; // reset_stepper_timeout to keep steppers powered
- else if (MOVE_AWAY_TEST && !ignore_stepper_queue && ELAPSED(ms, previous_move_ms + stepper_inactive_time)) {
- #if ENABLED(DISABLE_INACTIVE_X)
- disable_X();
- #endif
- #if ENABLED(DISABLE_INACTIVE_Y)
- disable_Y();
- #endif
- #if ENABLED(DISABLE_INACTIVE_Z)
- disable_Z();
- #endif
- #if ENABLED(DISABLE_INACTIVE_E)
- disable_e_steppers();
- #endif
- #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTIPANEL) // Only needed with an LCD
- if (ubl.lcd_map_control) ubl.lcd_map_control = defer_return_to_status = false;
- #endif
- }
- }
-
- #ifdef CHDK // Check if pin should be set to LOW after M240 set it to HIGH
- if (chdkActive && ELAPSED(ms, chdkHigh + CHDK_DELAY)) {
- chdkActive = false;
- WRITE(CHDK, LOW);
- }
- #endif
-
- #if HAS_KILL
-
- // Check if the kill button was pressed and wait just in case it was an accidental
- // key kill key press
- // -------------------------------------------------------------------------------
- static int killCount = 0; // make the inactivity button a bit less responsive
- const int KILL_DELAY = 750;
- if (!READ(KILL_PIN))
- killCount++;
- else if (killCount > 0)
- killCount--;
-
- // Exceeded threshold and we can confirm that it was not accidental
- // KILL the machine
- // ----------------------------------------------------------------
- if (killCount >= KILL_DELAY) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_KILL_BUTTON);
- kill(PSTR(MSG_KILLED));
- }
- #endif
-
- #if HAS_HOME
- // Check to see if we have to home, use poor man's debouncer
- // ---------------------------------------------------------
- static int homeDebounceCount = 0; // poor man's debouncing count
- const int HOME_DEBOUNCE_DELAY = 2500;
- if (!IS_SD_PRINTING && !READ(HOME_PIN)) {
- if (!homeDebounceCount) {
- enqueue_and_echo_commands_P(PSTR("G28"));
- LCD_MESSAGEPGM(MSG_AUTO_HOME);
- }
- if (homeDebounceCount < HOME_DEBOUNCE_DELAY)
- homeDebounceCount++;
- else
- homeDebounceCount = 0;
- }
- #endif
-
- #if ENABLED(USE_CONTROLLER_FAN)
- controllerFan(); // Check if fan should be turned on to cool stepper drivers down
- #endif
-
- #if ENABLED(AUTO_POWER_CONTROL)
- powerManager.check();
- #endif
-
- #if ENABLED(EXTRUDER_RUNOUT_PREVENT)
- if (thermalManager.degHotend(active_extruder) > EXTRUDER_RUNOUT_MINTEMP
- && ELAPSED(ms, previous_move_ms + (EXTRUDER_RUNOUT_SECONDS) * 1000UL)
- && !planner.has_blocks_queued()
- ) {
- #if ENABLED(SWITCHING_EXTRUDER)
- bool oldstatus;
- switch (active_extruder) {
- default: oldstatus = E0_ENABLE_READ; enable_E0(); break;
- #if E_STEPPERS > 1
- case 2: case 3: oldstatus = E1_ENABLE_READ; enable_E1(); break;
- #if E_STEPPERS > 2
- case 4: oldstatus = E2_ENABLE_READ; enable_E2(); break;
- #endif // E_STEPPERS > 2
- #endif // E_STEPPERS > 1
- }
- #else // !SWITCHING_EXTRUDER
- bool oldstatus;
- switch (active_extruder) {
- default: oldstatus = E0_ENABLE_READ; enable_E0(); break;
- #if E_STEPPERS > 1
- case 1: oldstatus = E1_ENABLE_READ; enable_E1(); break;
- #if E_STEPPERS > 2
- case 2: oldstatus = E2_ENABLE_READ; enable_E2(); break;
- #if E_STEPPERS > 3
- case 3: oldstatus = E3_ENABLE_READ; enable_E3(); break;
- #if E_STEPPERS > 4
- case 4: oldstatus = E4_ENABLE_READ; enable_E4(); break;
- #endif // E_STEPPERS > 4
- #endif // E_STEPPERS > 3
- #endif // E_STEPPERS > 2
- #endif // E_STEPPERS > 1
- }
- #endif // !SWITCHING_EXTRUDER
-
- const float olde = current_position[E_AXIS];
- current_position[E_AXIS] += EXTRUDER_RUNOUT_EXTRUDE;
- planner.buffer_line_kinematic(current_position, MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED), active_extruder);
- current_position[E_AXIS] = olde;
- planner.set_e_position_mm(olde);
- planner.synchronize();
-
- #if ENABLED(SWITCHING_EXTRUDER)
- switch (active_extruder) {
- default: oldstatus = E0_ENABLE_WRITE(oldstatus); break;
- #if E_STEPPERS > 1
- case 2: case 3: oldstatus = E1_ENABLE_WRITE(oldstatus); break;
- #if E_STEPPERS > 2
- case 4: oldstatus = E2_ENABLE_WRITE(oldstatus); break;
- #endif // E_STEPPERS > 2
- #endif // E_STEPPERS > 1
- }
- #else // !SWITCHING_EXTRUDER
- switch (active_extruder) {
- case 0: E0_ENABLE_WRITE(oldstatus); break;
- #if E_STEPPERS > 1
- case 1: E1_ENABLE_WRITE(oldstatus); break;
- #if E_STEPPERS > 2
- case 2: E2_ENABLE_WRITE(oldstatus); break;
- #if E_STEPPERS > 3
- case 3: E3_ENABLE_WRITE(oldstatus); break;
- #if E_STEPPERS > 4
- case 4: E4_ENABLE_WRITE(oldstatus); break;
- #endif // E_STEPPERS > 4
- #endif // E_STEPPERS > 3
- #endif // E_STEPPERS > 2
- #endif // E_STEPPERS > 1
- }
- #endif // !SWITCHING_EXTRUDER
-
- previous_move_ms = ms; // reset_stepper_timeout to keep steppers powered
- }
- #endif // EXTRUDER_RUNOUT_PREVENT
-
- #if ENABLED(DUAL_X_CARRIAGE)
- // handle delayed move timeout
- if (delayed_move_time && ELAPSED(ms, delayed_move_time + 1000UL) && IsRunning()) {
- // travel moves have been received so enact them
- delayed_move_time = 0xFFFFFFFFUL; // force moves to be done
- set_destination_from_current();
- prepare_move_to_destination();
- }
- #endif
-
- #if ENABLED(TEMP_STAT_LEDS)
- handle_status_leds();
- #endif
-
- #if ENABLED(MONITOR_DRIVER_STATUS)
- monitor_tmc_driver();
- #endif
-
- planner.check_axes_activity();
-}
-
-/**
- * Standard idle routine keeps the machine alive
- */
-void idle(
- #if ENABLED(ADVANCED_PAUSE_FEATURE)
- bool no_stepper_sleep/*=false*/
- #endif
-) {
- #if ENABLED(MAX7219_DEBUG)
- Max7219_idle_tasks();
- #endif
-
- lcd_update();
-
- host_keepalive();
-
- manage_inactivity(
- #if ENABLED(ADVANCED_PAUSE_FEATURE)
- no_stepper_sleep
- #endif
- );
-
- thermalManager.manage_heater();
-
- #if ENABLED(PRINTCOUNTER)
- print_job_timer.tick();
- #endif
-
- #if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER)
- buzzer.tick();
- #endif
-
- #if ENABLED(I2C_POSITION_ENCODERS)
- static millis_t i2cpem_next_update_ms;
- if (planner.has_blocks_queued() && ELAPSED(millis(), i2cpem_next_update_ms)) {
- I2CPEM.update();
- i2cpem_next_update_ms = millis() + I2CPE_MIN_UPD_TIME_MS;
- }
- #endif
-
- #if HAS_AUTO_REPORTING
- if (!suspend_auto_report) {
- #if ENABLED(AUTO_REPORT_TEMPERATURES)
- thermalManager.auto_report_temperatures();
- #endif
- #if ENABLED(AUTO_REPORT_SD_STATUS)
- card.auto_report_sd_status();
- #endif
- }
- #endif
-}
-
-/**
- * Kill all activity and lock the machine.
- * After this the machine will need to be reset.
- */
-void kill(const char* lcd_msg) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_KILLED);
-
- thermalManager.disable_all_heaters();
- disable_all_steppers();
-
- #if ENABLED(ULTRA_LCD)
- kill_screen(lcd_msg);
- #else
- UNUSED(lcd_msg);
- #endif
-
- _delay_ms(600); // Wait a short time (allows messages to get out before shutting down.
- cli(); // Stop interrupts
-
- _delay_ms(250); //Wait to ensure all interrupts routines stopped
- thermalManager.disable_all_heaters(); //turn off heaters again
-
- #ifdef ACTION_ON_KILL
- SERIAL_ECHOLNPGM("//action:" ACTION_ON_KILL);
- #endif
-
- #if HAS_POWER_SWITCH
- PSU_OFF();
- #endif
-
- suicide();
- while (1) {
- #if ENABLED(USE_WATCHDOG)
- watchdog_reset();
- #endif
- } // Wait for reset
-}
-
-/**
- * Turn off heaters and stop the print in progress
- * After a stop the machine may be resumed with M999
- */
-void stop() {
- thermalManager.disable_all_heaters(); // 'unpause' taken care of in here
-
- #if ENABLED(PROBING_FANS_OFF)
- if (fans_paused) fans_pause(false); // put things back the way they were
- #endif
-
- if (IsRunning()) {
- Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_ERR_STOPPED);
- LCD_MESSAGEPGM(MSG_STOPPED);
- safe_delay(350); // allow enough time for messages to get out before stopping
- Running = false;
- }
-}
-
-/**
- * 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() {
-
- #if ENABLED(MAX7219_DEBUG)
- Max7219_init();
- #endif
-
- #if ENABLED(DISABLE_JTAG)
- // Disable JTAG on AT90USB chips to free up pins for IO
- MCUCR = 0x80;
- MCUCR = 0x80;
- #endif
-
- #if ENABLED(FILAMENT_RUNOUT_SENSOR)
- runout.setup();
- #endif
-
- setup_killpin();
-
- setup_powerhold();
-
- #if HAS_STEPPER_RESET
- disableStepperDrivers();
- #endif
-
- MYSERIAL0.begin(BAUDRATE);
- SERIAL_PROTOCOLLNPGM("start");
- SERIAL_ECHO_START();
-
- // Prepare communication for TMC drivers
- #if ENABLED(HAVE_TMC2130)
- tmc_init_cs_pins();
- #endif
- #if ENABLED(HAVE_TMC2208)
- tmc2208_serial_begin();
- #endif
-
- // 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_CHAR(' ');
- SERIAL_ECHOLNPGM(SHORT_BUILD_VERSION);
- SERIAL_EOL();
-
- #if defined(STRING_DISTRIBUTION_DATE) && defined(STRING_CONFIG_H_AUTHOR)
- SERIAL_ECHO_START();
- SERIAL_ECHOPGM(MSG_CONFIGURATION_VER);
- SERIAL_ECHOPGM(STRING_DISTRIBUTION_DATE);
- SERIAL_ECHOLNPGM(MSG_AUTHOR STRING_CONFIG_H_AUTHOR);
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPGM("Compiled: " __DATE__);
- #endif
-
- SERIAL_ECHO_START();
- SERIAL_ECHOPAIR(MSG_FREE_MEMORY, freeMemory());
- SERIAL_ECHOLNPAIR(MSG_PLANNER_BUFFER_BYTES, (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
- (void)settings.load();
-
- #if HAS_M206_COMMAND
- // Initialize current position based on home_offset
- COPY(current_position, home_offset);
- #else
- ZERO(current_position);
- #endif
-
- // Vital to init stepper/planner equivalent for current_position
- SYNC_PLAN_POSITION_KINEMATIC();
-
- thermalManager.init(); // Initialize temperature loop
-
- print_job_timer.init(); // Initial setup of print job timer
-
- endstops.init(); // Init endstops and pullups
-
- stepper.init(); // Init stepper. This enables interrupts!
-
- servo_init(); // Initialize all servos, stow servo probe
-
- #if HAS_PHOTOGRAPH
- OUT_WRITE(PHOTOGRAPH_PIN, LOW);
- #endif
-
- #if HAS_CASE_LIGHT
- case_light_on = CASE_LIGHT_DEFAULT_ON;
- case_light_brightness = CASE_LIGHT_DEFAULT_BRIGHTNESS;
- update_case_light();
- #endif
-
- #if ENABLED(SPINDLE_LASER_ENABLE)
- OUT_WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT); // init spindle to off
- #if SPINDLE_DIR_CHANGE
- OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR ? 255 : 0); // init rotation to clockwise (M3)
- #endif
- #if ENABLED(SPINDLE_LASER_PWM)
- SET_OUTPUT(SPINDLE_LASER_PWM_PIN);
- analogWrite(SPINDLE_LASER_PWM_PIN, SPINDLE_LASER_PWM_INVERT ? 255 : 0); // set to lowest speed
- #endif
- #endif
-
- #if HAS_BED_PROBE
- endstops.enable_z_probe(false);
- #endif
-
- #if ENABLED(USE_CONTROLLER_FAN)
- SET_OUTPUT(CONTROLLER_FAN_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) || ENABLED(SOLENOID_PROBE)) && HAS_SOLENOID_1
- OUT_WRITE(SOL1_PIN, LOW); // turn it off
- #endif
-
- #if HAS_HOME
- SET_INPUT_PULLUP(HOME_PIN);
- #endif
-
- #if PIN_EXISTS(STAT_LED_RED)
- OUT_WRITE(STAT_LED_RED_PIN, LOW); // turn it off
- #endif
-
- #if PIN_EXISTS(STAT_LED_BLUE)
- OUT_WRITE(STAT_LED_BLUE_PIN, LOW); // turn it off
- #endif
-
- #if HAS_COLOR_LEDS
- leds.setup();
- #endif
-
- #if ENABLED(RGB_LED) || ENABLED(RGBW_LED)
- SET_OUTPUT(RGB_LED_R_PIN);
- SET_OUTPUT(RGB_LED_G_PIN);
- SET_OUTPUT(RGB_LED_B_PIN);
- #if ENABLED(RGBW_LED)
- SET_OUTPUT(RGB_LED_W_PIN);
- #endif
- #endif
-
- #if ENABLED(MK2_MULTIPLEXER)
- SET_OUTPUT(E_MUX0_PIN);
- SET_OUTPUT(E_MUX1_PIN);
- SET_OUTPUT(E_MUX2_PIN);
- #endif
-
- #if HAS_FANMUX
- fanmux_init();
- #endif
-
- lcd_init();
- lcd_reset_status();
-
- #if ENABLED(SHOW_BOOTSCREEN)
- lcd_bootscreen();
- #endif
-
- #if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1
- // Virtual Tools 0, 1, 2, 3 = Filament 1, 2, 3, 4, etc.
- for (uint8_t t = 0; t < MIXING_VIRTUAL_TOOLS && t < MIXING_STEPPERS; t++)
- for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
- mixing_virtual_tool_mix[t][i] = (t == i) ? 1.0 : 0.0;
-
- // Remaining virtual tools are 100% filament 1
- #if MIXING_STEPPERS < MIXING_VIRTUAL_TOOLS
- for (uint8_t t = MIXING_STEPPERS; t < MIXING_VIRTUAL_TOOLS; t++)
- for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
- mixing_virtual_tool_mix[t][i] = (i == 0) ? 1.0 : 0.0;
- #endif
-
- // Initialize mixing to tool 0 color
- for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
- mixing_factor[i] = mixing_virtual_tool_mix[0][i];
- #endif
-
- #if ENABLED(BLTOUCH)
- // Make sure any BLTouch error condition is cleared
- bltouch_command(BLTOUCH_RESET);
- set_bltouch_deployed(true);
- set_bltouch_deployed(false);
- #endif
-
- #if ENABLED(I2C_POSITION_ENCODERS)
- I2CPEM.init();
- #endif
-
- #if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
- i2c.onReceive(i2c_on_receive);
- i2c.onRequest(i2c_on_request);
- #endif
-
- #if DO_SWITCH_EXTRUDER
- move_extruder_servo(0); // Initialize extruder servo
- #endif
-
- #if ENABLED(SWITCHING_NOZZLE)
- move_nozzle_servo(0); // Initialize nozzle servo
- #endif
-
- #if ENABLED(PARKING_EXTRUDER)
- #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT)
- pe_activate_magnet(0);
- pe_activate_magnet(1);
- #else
- pe_deactivate_magnet(0);
- pe_deactivate_magnet(1);
- #endif
- #endif
-
- #if ENABLED(POWER_LOSS_RECOVERY)
- check_print_job_recovery();
- #endif
-
- #if ENABLED(USE_WATCHDOG)
- watchdog_init();
- #endif
-}
-
-/**
- * The main Marlin program loop
- *
- * - Abort SD printing if flagged
- * - 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 ENABLED(SDSUPPORT)
-
- card.checkautostart();
-
- #if ENABLED(ULTIPANEL)
- if (abort_sd_printing) {
- abort_sd_printing = false;
- card.stopSDPrint(
- #if SD_RESORT
- true
- #endif
- );
- clear_command_queue();
- quickstop_stepper();
- print_job_timer.stop();
- thermalManager.disable_all_heaters();
- #if FAN_COUNT > 0
- for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0;
- #endif
- wait_for_heatup = false;
- #if ENABLED(POWER_LOSS_RECOVERY)
- card.removeJobRecoveryFile();
- #endif
- }
- #endif
-
- #endif // SDSUPPORT
-
- if (commands_in_queue < BUFSIZE) get_available_commands();
-
- 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);
-
- #if USE_MARLINSERIAL
- #if ENABLED(SERIAL_STATS_DROPPED_RX)
- SERIAL_ECHOLNPAIR("Dropped bytes: ", customizedSerial.dropped());
- #endif
- #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
- SERIAL_ECHOLNPAIR("Max RX Queue Size: ", customizedSerial.rxMaxEnqueued());
- #endif
- #endif
-
- 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();
- #if ENABLED(POWER_LOSS_RECOVERY)
- if (card.cardOK && card.sdprinting) save_job_recovery_info();
- #endif
- }
-
- #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;
- if (++cmd_queue_index_r >= BUFSIZE) cmd_queue_index_r = 0;
- }
- }
- endstops.report_state();
- idle();
-}
diff --git a/Marlin/Max7219_Debug_LEDs.cpp b/Marlin/Max7219_Debug_LEDs.cpp
deleted file mode 100644
index eba1ffcd27..0000000000
--- a/Marlin/Max7219_Debug_LEDs.cpp
+++ /dev/null
@@ -1,455 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-/**
- * This module is off by default, but can be enabled to facilitate the display of
- * extra debug information during code development.
- *
- * Just connect up 5V and GND to give it power, then connect up the pins assigned
- * in Configuration_adv.h. For example, on the Re-ARM you could use:
- *
- * #define MAX7219_CLK_PIN 77
- * #define MAX7219_DIN_PIN 78
- * #define MAX7219_LOAD_PIN 79
- *
- * Max7219_init() is called automatically at startup, and then there are a number of
- * support functions available to control the LEDs in the 8x8 grid.
- */
-
-#include "MarlinConfig.h"
-
-#if ENABLED(MAX7219_DEBUG)
-
-#define MAX7219_ERRORS // Disable to save 406 bytes of Program Memory
-
-#include "Max7219_Debug_LEDs.h"
-
-#include "planner.h"
-#include "stepper.h"
-#include "Marlin.h"
-#include "delay.h"
-
-static uint8_t LEDs[8] = { 0 };
-
-#ifndef MAX7219_ROTATE
- #define MAX7219_ROTATE 0
-#endif
-#define _ROT ((MAX7219_ROTATE + 360) % 360)
-#if _ROT == 0
- #define _ROW_ y
- #define _COL_ x
- #define XOR_7219(x, y) LEDs[y] ^= _BV(7 - x)
- #define BIT_7219(x, y) TEST(LEDs[y], 7 - x)
- #define SEND_7219(R,V) Max7219(max7219_reg_digit0 + R, V)
-#elif _ROT == 90
- #define _ROW_ x
- #define _COL_ y
- #define XOR_7219(x, y) LEDs[x] ^= _BV(y)
- #define BIT_7219(x, y) TEST(LEDs[x], y)
- #define SEND_7219(R,V) Max7219(max7219_reg_digit0 + R, V)
-#elif _ROT == 180
- #define _ROW_ y
- #define _COL_ x
- #define XOR_7219(x, y) LEDs[y] ^= _BV(x)
- #define BIT_7219(x, y) TEST(LEDs[y], x)
- #define SEND_7219(R,V) Max7219(max7219_reg_digit7 - R, V)
-#elif _ROT == 270
- #define _ROW_ x
- #define _COL_ y
- #define XOR_7219(x, y) LEDs[x] ^= _BV(7 - y)
- #define BIT_7219(x, y) TEST(LEDs[x], 7 - y)
- #define SEND_7219(R,V) Max7219(max7219_reg_digit7 - R, V)
-#else
- #error "MAX7219_ROTATE must be a multiple of +/- 90°."
-#endif
-
-// Delay for 0.1875µs (16MHz AVR) or 0.15µs (20MHz AVR)
-#define SIG_DELAY() DELAY_NS(188)
-
-void Max7219_PutByte(uint8_t data) {
- CRITICAL_SECTION_START;
- for (uint8_t i = 8; i--;) {
- SIG_DELAY();
- WRITE(MAX7219_CLK_PIN, LOW); // tick
- SIG_DELAY();
- WRITE(MAX7219_DIN_PIN, (data & 0x80) ? HIGH : LOW); // send 1 or 0 based on data bit
- SIG_DELAY();
- WRITE(MAX7219_CLK_PIN, HIGH); // tock
- SIG_DELAY();
- data <<= 1;
- }
- CRITICAL_SECTION_END;
-}
-
-void Max7219(const uint8_t reg, const uint8_t data) {
- SIG_DELAY();
- CRITICAL_SECTION_START;
- WRITE(MAX7219_LOAD_PIN, LOW); // begin
- SIG_DELAY();
- Max7219_PutByte(reg); // specify register
- SIG_DELAY();
- Max7219_PutByte(data); // put data
- SIG_DELAY();
- WRITE(MAX7219_LOAD_PIN, LOW); // and tell the chip to load the data
- SIG_DELAY();
- WRITE(MAX7219_LOAD_PIN, HIGH);
- CRITICAL_SECTION_END;
- SIG_DELAY();
-}
-
-#if ENABLED(MAX7219_NUMERIC)
-
- // Draw an integer with optional leading zeros and optional decimal point
- void Max7219_Print(const uint8_t start, int16_t value, uint8_t size, const bool leadzero=false, bool dec=false) {
- constexpr uint8_t led_numeral[10] = { 0x7E, 0x60, 0x6D, 0x79, 0x63, 0x5B, 0x5F, 0x70, 0x7F, 0x7A },
- led_decimal = 0x80, led_minus = 0x01;
-
- bool blank = false, neg = value < 0;
- if (neg) value *= -1;
- while (size--) {
- const bool minus = neg && blank;
- if (minus) neg = false;
- Max7219(
- max7219_reg_digit0 + start + size,
- minus ? led_minus : blank ? 0x00 : led_numeral[value % 10] | (dec ? led_decimal : 0x00)
- );
- value /= 10;
- if (!value && !leadzero) blank = true;
- dec = false;
- }
- }
-
- // Draw a float with a decimal point and optional digits
- void Max7219_Print(const uint8_t start, const float value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false) {
- if (pre_size) Max7219_Print(start, value, pre_size, leadzero, !!post_size);
- if (post_size) {
- const int16_t after = ABS(value) * (10 ^ post_size);
- Max7219_Print(start + pre_size, after, post_size, true);
- }
- }
-
-#endif // MAX7219_NUMERIC
-
-inline void Max7219_Error(const char * const func, const int32_t v1, const int32_t v2=-1) {
- #if ENABLED(MAX7219_ERRORS)
- SERIAL_ECHOPGM("??? ");
- serialprintPGM(func);
- SERIAL_CHAR('(');
- SERIAL_ECHO(v1);
- if (v2 > 0) SERIAL_ECHOPAIR(", ", v2);
- SERIAL_CHAR(')');
- SERIAL_EOL();
- #else
- UNUSED(func); UNUSED(v1); UNUSED(v2);
- #endif
-}
-
-inline uint8_t flipped(const uint8_t bits) {
- uint8_t outbits = 0;
- for (uint8_t b = 0; b < 8; b++)
- if (bits & _BV(b)) outbits |= _BV(7 - b);
- return outbits;
-}
-
-// Modify a single LED bit and send the changed line
-void Max7219_LED_Set(const uint8_t x, const uint8_t y, const bool on) {
- if (x > 7 || y > 7) return Max7219_Error(PSTR("Max7219_LED_Set"), x, y);
- if (BIT_7219(x, y) == on) return;
- XOR_7219(x, y);
- SEND_7219(_ROW_, LEDs[_ROW_]);
-}
-
-void Max7219_LED_On(const uint8_t x, const uint8_t y) {
- if (x > 7 || y > 7) return Max7219_Error(PSTR("Max7219_LED_On"), x, y);
- Max7219_LED_Set(x, y, true);
-}
-
-void Max7219_LED_Off(const uint8_t x, const uint8_t y) {
- if (x > 7 || y > 7) return Max7219_Error(PSTR("Max7219_LED_Off"), x, y);
- Max7219_LED_Set(x, y, false);
-}
-
-void Max7219_LED_Toggle(const uint8_t x, const uint8_t y) {
- if (x > 7 || y > 7) return Max7219_Error(PSTR("Max7219_LED_Toggle"), x, y);
- Max7219_LED_Set(x, y, !BIT_7219(x, y));
-}
-
-inline void _Max7219_Set_Reg(const uint8_t reg, const uint8_t val) {
- LEDs[reg] = val;
- SEND_7219(reg, val);
-}
-
-void Max7219_Set_Row(const uint8_t _ROW_, const uint8_t val) {
- if (_ROW_ > 7) return Max7219_Error(PSTR("Max7219_Set_Row"), _ROW_);
- #if _ROT == 90
- for (uint8_t _COL_ = 0; _COL_ <= 7; _COL_++) Max7219_LED_Set(7 - _COL_, _ROW_, TEST(val, _COL_));
- #elif _ROT == 180
- _Max7219_Set_Reg(_ROW_, flipped(val));
- #elif _ROT == 270
- for (uint8_t _COL_ = 0; _COL_ <= 7; _COL_++) Max7219_LED_Set(_COL_, _ROW_, TEST(val, _COL_));
- #else
- _Max7219_Set_Reg(_ROW_, val);
- #endif
-}
-
-void Max7219_Clear_Row(const uint8_t _ROW_) {
- if (_ROW_ > 7) return Max7219_Error(PSTR("Max7219_Clear_Row"), _ROW_);
- #if _ROT == 90 || _ROT == 270
- for (uint8_t _COL_ = 0; _COL_ <= 7; _COL_++) Max7219_LED_Off(_COL_, _ROW_);
- #else
- _Max7219_Set_Reg(_ROW_, 0);
- #endif
-}
-
-void Max7219_Set_Column(const uint8_t _COL_, const uint8_t val) {
- if (_COL_ > 7) return Max7219_Error(PSTR("Max7219_Set_Column"), _COL_);
- #if _ROT == 90
- _Max7219_Set_Reg(_COL_, val);
- #elif _ROT == 180
- for (uint8_t _ROW_ = 0; _ROW_ <= 7; _ROW_++) Max7219_LED_Set(_COL_, _ROW_, TEST(val, _ROW_));
- #elif _ROT == 270
- _Max7219_Set_Reg(_COL_, flipped(val));
- #else
- for (uint8_t _ROW_ = 0; _ROW_ <= 7; _ROW_++) Max7219_LED_Set(_COL_, _ROW_, TEST(val, _ROW_));
- #endif
-}
-
-void Max7219_Clear_Column(const uint8_t _COL_) {
- if (_COL_ > 7) return Max7219_Error(PSTR("Max7219_Clear_Column"), _COL_);
- #if _ROT == 90 || _ROT == 270
- _Max7219_Set_Reg(_COL_, 0);
- #else
- for (uint8_t _ROW_ = 0; _ROW_ <= 7; _ROW_++) Max7219_LED_Off(_COL_, _ROW_);
- #endif
-}
-
-void Max7219_Clear() {
- for (uint8_t r = 0; r < 8; r++) _Max7219_Set_Reg(r, 0);
-}
-
-void Max7219_Set_2_Rows(const uint8_t y, uint16_t val) {
- if (y > 6) return Max7219_Error(PSTR("Max7219_Set_2_Rows"), y, val);
- Max7219_Set_Row(y + 0, val & 0xFF); val >>= 8;
- Max7219_Set_Row(y + 1, val & 0xFF);
-}
-
-void Max7219_Set_4_Rows(const uint8_t y, uint32_t val) {
- if (y > 4) return Max7219_Error(PSTR("Max7219_Set_4_Rows"), y, val);
- Max7219_Set_Row(y + 0, val & 0xFF); val >>= 8;
- Max7219_Set_Row(y + 1, val & 0xFF); val >>= 8;
- Max7219_Set_Row(y + 2, val & 0xFF); val >>= 8;
- Max7219_Set_Row(y + 3, val & 0xFF);
-}
-
-void Max7219_Set_2_Columns(const uint8_t x, uint16_t val) {
- if (x > 6) return Max7219_Error(PSTR("Max7219_Set_2_Columns"), x, val);
- Max7219_Set_Column(x + 0, val & 0xFF); val >>= 8;
- Max7219_Set_Column(x + 1, val & 0xFF);
-}
-
-void Max7219_Set_4_Columns(const uint8_t x, uint32_t val) {
- if (x > 4) return Max7219_Error(PSTR("Max7219_Set_4_Columns"), x, val);
- Max7219_Set_Column(x + 0, val & 0xFF); val >>= 8;
- Max7219_Set_Column(x + 1, val & 0xFF); val >>= 8;
- Max7219_Set_Column(x + 2, val & 0xFF); val >>= 8;
- Max7219_Set_Column(x + 3, val & 0xFF);
-}
-
-void Max7219_register_setup() {
- // Initialize the Max7219
- Max7219(max7219_reg_scanLimit, 0x07);
- Max7219(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits)
- Max7219(max7219_reg_shutdown, 0x01); // not in shutdown mode
- Max7219(max7219_reg_displayTest, 0x00); // no display test
- Max7219(max7219_reg_intensity, 0x01 & 0x0F); // the first 0x0F is the value you can set
- // range: 0x00 to 0x0F
-}
-
-#ifdef MAX7219_INIT_TEST
-#if (MAX7219_INIT_TEST + 0) == 2
-
- inline void Max7219_spiral(const bool on, const uint16_t del) {
- constexpr int8_t way[] = { 1, 0, 0, 1, -1, 0, 0, -1 };
- int8_t px = 0, py = 0, dir = 0;
- for (uint8_t i = 64; i--;) {
- Max7219_LED_Set(px, py, on);
- delay(del);
- const int8_t x = px + way[dir], y = py + way[dir + 1];
- if (!WITHIN(x, 0, 7) || !WITHIN(y, 0, 7) || BIT_7219(x, y) == on) dir = (dir + 2) & 0x7;
- px += way[dir]; py += way[dir + 1];
- }
- }
-
-#else
-
- inline void Max7219_colset(const uint8_t x, const bool on) {
- for (uint8_t y = 0; y <= 7; y++) Max7219_LED_Set(x, y, on);
- }
- inline void Max7219_sweep(const int8_t dir, const uint16_t ms, const bool on) {
- uint8_t x = dir > 0 ? 0 : 7;
- for (uint8_t i = 8; i--; x += dir) {
- Max7219_Set_Column(x, on ? 0xFF : 0x00);
- delay(ms);
- }
- }
-
-#endif
-#endif // MAX7219_INIT_TEST
-
-void Max7219_init() {
- SET_OUTPUT(MAX7219_DIN_PIN);
- SET_OUTPUT(MAX7219_CLK_PIN);
- OUT_WRITE(MAX7219_LOAD_PIN, HIGH);
- delay(1);
-
- Max7219_register_setup();
-
- for (uint8_t i = 0; i <= 7; i++) { // Empty registers to turn all LEDs off
- LEDs[i] = 0x00;
- Max7219(max7219_reg_digit0 + i, 0);
- }
-
- #ifdef MAX7219_INIT_TEST
- #if (MAX7219_INIT_TEST + 0) == 2
- Max7219_spiral(true, 8);
- delay(150);
- Max7219_spiral(false, 8);
- #else
- // Do an aesthetically-pleasing pattern to fully test the Max7219 module and LEDs.
- // Light up and turn off columns, both forward and backward.
- Max7219_sweep(1, 20, true);
- Max7219_sweep(1, 20, false);
- delay(150);
- Max7219_sweep(-1, 20, true);
- Max7219_sweep(-1, 20, false);
- #endif
- #endif
-}
-
-/**
- * This code demonstrates some simple debugging using a single 8x8 LED Matrix. If your feature could
- * benefit from matrix display, add its code here. Very little processing is required, so the 7219 is
- * ideal for debugging when realtime feedback is important but serial output can't be used.
- */
-
-// Apply changes to update a marker
-inline void Max7219_Mark16(const uint8_t y, const uint8_t v1, const uint8_t v2) {
- Max7219_LED_Off(v1 & 0x7, y + (v1 >= 8));
- Max7219_LED_On(v2 & 0x7, y + (v2 >= 8));
-}
-
-// Apply changes to update a tail-to-head range
-inline void Max7219_Range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh) {
- if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
- Max7219_LED_Off(n & 0x7, y + (n >= 8));
- if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
- Max7219_LED_On(n & 0x7, y + (n >= 8));
-}
-
-// Apply changes to update a quantity
-inline void Max7219_Quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv) {
- for (uint8_t i = MIN(nv, ov); i < MAX(nv, ov); i++)
- Max7219_LED_Set(i >> 1, y + (i & 1), nv >= ov);
-}
-
-void Max7219_idle_tasks() {
- #define MAX7219_USE_HEAD (defined(MAX7219_DEBUG_PLANNER_HEAD) || defined(MAX7219_DEBUG_PLANNER_QUEUE))
- #define MAX7219_USE_TAIL (defined(MAX7219_DEBUG_PLANNER_TAIL) || defined(MAX7219_DEBUG_PLANNER_QUEUE))
- #if MAX7219_USE_HEAD || MAX7219_USE_TAIL
- CRITICAL_SECTION_START;
- #if MAX7219_USE_HEAD
- const uint8_t head = planner.block_buffer_head;
- #endif
- #if MAX7219_USE_TAIL
- const uint8_t tail = planner.block_buffer_tail;
- #endif
- CRITICAL_SECTION_END;
- #endif
-
- #if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE)
- static uint8_t refresh_cnt; // = 0
- constexpr uint16_t refresh_limit = 5;
- static millis_t next_blink = 0;
- const millis_t ms = millis();
- const bool do_blink = ELAPSED(ms, next_blink);
- #else
- static uint16_t refresh_cnt; // = 0
- constexpr bool do_blink = true;
- constexpr uint16_t refresh_limit = 50000;
- #endif
-
- // Some Max7219 units are vulnerable to electrical noise, especially
- // with long wires next to high current wires. If the display becomes
- // corrupted, this will fix it within a couple seconds.
- if (do_blink && ++refresh_cnt >= refresh_limit) {
- refresh_cnt = 0;
- Max7219_register_setup();
- }
-
- #if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE)
- if (do_blink) {
- Max7219_LED_Toggle(7, 7);
- next_blink = ms + 1000;
- }
- #endif
-
- #if defined(MAX7219_DEBUG_PLANNER_HEAD) && defined(MAX7219_DEBUG_PLANNER_TAIL) && MAX7219_DEBUG_PLANNER_HEAD == MAX7219_DEBUG_PLANNER_TAIL
-
- static int16_t last_head_cnt = 0xF, last_tail_cnt = 0xF;
-
- if (last_head_cnt != head || last_tail_cnt != tail) {
- Max7219_Range16(MAX7219_DEBUG_PLANNER_HEAD, last_tail_cnt, tail, last_head_cnt, head);
- last_head_cnt = head;
- last_tail_cnt = tail;
- }
-
- #else
-
- #ifdef MAX7219_DEBUG_PLANNER_HEAD
- static int16_t last_head_cnt = 0x1;
- if (last_head_cnt != head) {
- Max7219_Mark16(MAX7219_DEBUG_PLANNER_HEAD, last_head_cnt, head);
- last_head_cnt = head;
- }
- #endif
-
- #ifdef MAX7219_DEBUG_PLANNER_TAIL
- static int16_t last_tail_cnt = 0x1;
- if (last_tail_cnt != tail) {
- Max7219_Mark16(MAX7219_DEBUG_PLANNER_TAIL, last_tail_cnt, tail);
- last_tail_cnt = tail;
- }
- #endif
-
- #endif
-
- #ifdef MAX7219_DEBUG_PLANNER_QUEUE
- static int16_t last_depth = 0;
- const int16_t current_depth = (head - tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1) & 0xF;
- if (current_depth != last_depth) {
- Max7219_Quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth);
- last_depth = current_depth;
- }
- #endif
-}
-
-#endif // MAX7219_DEBUG
diff --git a/Marlin/Max7219_Debug_LEDs.h b/Marlin/Max7219_Debug_LEDs.h
deleted file mode 100644
index f00f231749..0000000000
--- a/Marlin/Max7219_Debug_LEDs.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-/**
- * This module is off by default, but can be enabled to facilitate the display of
- * extra debug information during code development.
- *
- * Just connect up 5V and GND to give it power, then connect up the pins assigned
- * in Configuration_adv.h. For example, on the Re-ARM you could use:
- *
- * #define MAX7219_CLK_PIN 77
- * #define MAX7219_DIN_PIN 78
- * #define MAX7219_LOAD_PIN 79
- *
- * Max7219_init() is called automatically at startup, and then there are a number of
- * support functions available to control the LEDs in the 8x8 grid.
- */
-
-#ifndef __MAX7219_DEBUG_LEDS_H__
-#define __MAX7219_DEBUG_LEDS_H__
-
-//
-// MAX7219 registers
-//
-#define max7219_reg_noop 0x00
-#define max7219_reg_digit0 0x01
-#define max7219_reg_digit1 0x02
-#define max7219_reg_digit2 0x03
-#define max7219_reg_digit3 0x04
-#define max7219_reg_digit4 0x05
-#define max7219_reg_digit5 0x06
-#define max7219_reg_digit6 0x07
-#define max7219_reg_digit7 0x08
-
-#define max7219_reg_decodeMode 0x09
-#define max7219_reg_intensity 0x0A
-#define max7219_reg_scanLimit 0x0B
-#define max7219_reg_shutdown 0x0C
-#define max7219_reg_displayTest 0x0F
-
-void Max7219_init();
-void Max7219_PutByte(uint8_t data);
-
-// Set a single register (e.g., a whole native row)
-void Max7219(const uint8_t reg, const uint8_t data);
-
-// Set a single LED by XY coordinate
-void Max7219_LED_Set(const uint8_t x, const uint8_t y, const bool on);
-void Max7219_LED_On(const uint8_t x, const uint8_t y);
-void Max7219_LED_Off(const uint8_t x, const uint8_t y);
-void Max7219_LED_Toggle(const uint8_t x, const uint8_t y);
-
-// Set all 8 LEDs in a single column
-void Max7219_Set_Column(const uint8_t col, const uint8_t val);
-void Max7219_Clear_Column(const uint8_t col);
-
-// Set all 8 LEDs in a single row
-void Max7219_Set_Row(const uint8_t row, const uint8_t val);
-void Max7219_Clear_Row(const uint8_t row);
-
-// Quickly clear the whole matrix
-void Max7219_Clear();
-
-// Apply custom code to update the matrix
-void Max7219_idle_tasks();
-
-#endif // __MAX7219_DEBUG_LEDS_H__
diff --git a/Marlin/SdFatUtil.cpp b/Marlin/SdFatUtil.cpp
deleted file mode 100644
index 2bd471bc67..0000000000
--- a/Marlin/SdFatUtil.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-/**
- * Arduino SdFat Library
- * Copyright (C) 2008 by William Greiman
- *
- * This file is part of the Arduino Sd2Card Library
- */
-#include "MarlinConfig.h"
-
-#if ENABLED(SDSUPPORT)
-
-#include "SdFatUtil.h"
-#include "serial.h"
-
-/**
- * Amount of free RAM
- * \return The number of free bytes.
- */
-#ifdef __arm__
-extern "C" char* sbrk(int incr);
-int SdFatUtil::FreeRam() {
- char top;
- return &top - reinterpret_cast(sbrk(0));
-}
-#else // __arm__
-extern char* __brkval;
-extern char __bss_end;
-/**
- * Amount of free RAM
- * \return The number of free bytes.
- */
-int SdFatUtil::FreeRam() {
- char top;
- return __brkval ? &top - __brkval : &top - &__bss_end;
-}
-#endif // __arm
-
-/**
- * %Print a string in flash memory.
- *
- * \param[in] pr Print object for output.
- * \param[in] str Pointer to string stored in flash memory.
- */
-void SdFatUtil::print_P(PGM_P str) {
- for (uint8_t c; (c = pgm_read_byte(str)); str++) SERIAL_CHAR(c);
-}
-
-/**
- * %Print a string in flash memory followed by a CR/LF.
- *
- * \param[in] pr Print object for output.
- * \param[in] str Pointer to string stored in flash memory.
- */
-void SdFatUtil::println_P(PGM_P str) { print_P(str); SERIAL_EOL(); }
-
-/**
- * %Print a string in flash memory to Serial.
- *
- * \param[in] str Pointer to string stored in flash memory.
- */
-void SdFatUtil::SerialPrint_P(PGM_P str) { print_P(str); }
-
-/**
- * %Print a string in flash memory to Serial followed by a CR/LF.
- *
- * \param[in] str Pointer to string stored in flash memory.
- */
-void SdFatUtil::SerialPrintln_P(PGM_P str) { println_P(str); }
-
-#endif // SDSUPPORT
diff --git a/Marlin/_Statusscreen.h b/Marlin/_Statusscreen.h
index 8a3811c111..6a06a49016 100644
--- a/Marlin/_Statusscreen.h
+++ b/Marlin/_Statusscreen.h
@@ -29,7 +29,7 @@
* Use the Marlin Bitmap Converter to make your own:
* http://marlinfw.org/tools/u8glib/converter.html
*/
-#include "MarlinConfig.h"
+
//============================================
diff --git a/Marlin/delay.h b/Marlin/delay.h
deleted file mode 100644
index 5689b2b4c1..0000000000
--- a/Marlin/delay.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-/**
- * AVR busy wait delay Cycles routines:
- *
- * DELAY_CYCLES(count): Delay execution in cycles
- * DELAY_NS(count): Delay execution in nanoseconds
- * DELAY_US(count): Delay execution in microseconds
- */
-
-#ifndef MARLIN_DELAY_H
-#define MARLIN_DELAY_H
-
-#define nop() __asm__ __volatile__("nop;\n\t":::)
-
-FORCE_INLINE static void __delay_4cycles(uint8_t cy) {
- __asm__ __volatile__(
- L("1")
- A("dec %[cnt]")
- A("nop")
- A("brne 1b")
- : [cnt] "+r"(cy) // output: +r means input+output
- : // input:
- : "cc" // clobbers:
- );
-}
-
-/* ---------------- Delay in cycles */
-FORCE_INLINE static void DELAY_CYCLES(uint16_t x) {
-
- if (__builtin_constant_p(x)) {
- #define MAXNOPS 4
-
- if (x <= (MAXNOPS)) {
- switch (x) { case 4: nop(); case 3: nop(); case 2: nop(); case 1: nop(); }
- }
- else {
- const uint32_t rem = (x) % (MAXNOPS);
- switch (rem) { case 3: nop(); case 2: nop(); case 1: nop(); }
- if ((x = (x) / (MAXNOPS)))
- __delay_4cycles(x); // if need more then 4 nop loop is more optimal
- }
-
- #undef MAXNOPS
- }
- else
- __delay_4cycles(x / 4);
-}
-#undef nop
-
-/* ---------------- Delay in nanoseconds */
-#define DELAY_NS(x) DELAY_CYCLES( (x) * (F_CPU/1000000L) / 1000L )
-
-/* ---------------- Delay in microseconds */
-#define DELAY_US(x) DELAY_CYCLES( (x) * (F_CPU/1000000L) )
-
-#endif // MARLIN_DELAY_H
diff --git a/Marlin/dogm_font_data_HD44780_C.h b/Marlin/dogm_font_data_HD44780_C.h
deleted file mode 100644
index 21d4aaabe2..0000000000
--- a/Marlin/dogm_font_data_HD44780_C.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-/**
- Fontname: HD44780_C v1.2
- Copyright: A. Hardtung, public domain
- Capital A Height: 7, '1' Height: 7
- Calculated Max Values w= 5 h= 8 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 8
- Font Bounding box w= 6 h= 9 x= 0 y=-2
- Calculated Min Values x= 0 y=-1 dx= 0 dy= 0
- Pure Font ascent = 7 descent=-1
- X Font ascent = 7 descent=-1
- Max Font ascent = 8 descent=-1
-*/
-#include
-const u8g_fntpgm_uint8_t HD44780_C_5x7[2522] U8G_SECTION(".progmem.HD44780_C_5x7") = {
- 0, 6, 9, 0, 254, 7, 1, 145, 3, 34, 32, 255, 255, 8, 255, 7,
- 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128,
- 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6,
- 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32,
- 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32,
- 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104,
- 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32,
- 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32,
- 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5,
- 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192,
- 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192,
- 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6,
- 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64,
- 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112,
- 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240,
- 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7,
- 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0,
- 48, 64, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16,
- 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136,
- 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5,
- 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192,
- 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64,
- 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1,
- 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136,
- 8, 16, 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168,
- 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7,
- 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0,
- 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144,
- 136, 136, 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128,
- 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5,
- 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6,
- 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128,
- 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16,
- 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136,
- 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7,
- 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0,
- 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136,
- 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128,
- 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7,
- 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0,
- 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32,
- 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136,
- 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5,
- 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6,
- 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136,
- 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32,
- 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224,
- 5, 7, 7, 6, 0, 0, 32, 112, 160, 160, 168, 112, 32, 3, 7, 7,
- 6, 1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4,
- 32, 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5,
- 128, 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7,
- 6, 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0,
- 112, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136,
- 136, 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7,
- 6, 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255,
- 112, 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200,
- 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128,
- 3, 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7,
- 7, 6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1,
- 0, 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168,
- 168, 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5,
- 5, 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240,
- 136, 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8,
- 8, 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6,
- 0, 0, 112, 128, 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224,
- 64, 64, 72, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5,
- 5, 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0,
- 136, 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136,
- 5, 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6,
- 0, 0, 248, 16, 32, 64, 248, 5, 5, 5, 6, 0, 2, 184, 168, 168,
- 168, 184, 5, 5, 5, 6, 0, 2, 184, 136, 184, 160, 184, 5, 5, 5,
- 6, 0, 2, 184, 160, 184, 136, 184, 5, 6, 6, 6, 0, 1, 8, 40,
- 72, 248, 64, 32, 5, 5, 5, 6, 0, 0, 56, 112, 224, 136, 240, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
- 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
- 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
- 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
- 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
- 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
- 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
- 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
- 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 5,
- 7, 7, 6, 0, 0, 248, 136, 128, 240, 136, 136, 240, 5, 7, 7, 6,
- 0, 0, 248, 136, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 80,
- 0, 248, 128, 240, 128, 248, 5, 7, 7, 6, 0, 0, 168, 168, 168, 112,
- 168, 168, 168, 5, 7, 7, 6, 0, 0, 240, 8, 8, 112, 8, 8, 240,
- 5, 7, 7, 6, 0, 0, 136, 136, 152, 168, 200, 136, 136, 5, 8, 8,
- 6, 0, 0, 80, 32, 136, 152, 168, 168, 200, 136, 5, 7, 7, 6, 0,
- 0, 120, 40, 40, 40, 40, 168, 72, 5, 7, 7, 6, 0, 0, 248, 136,
- 136, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 136, 136, 136, 80, 32,
- 64, 128, 5, 7, 7, 6, 0, 0, 32, 112, 168, 168, 168, 112, 32, 5,
- 7, 7, 6, 0, 0, 136, 136, 136, 120, 8, 8, 8, 5, 7, 7, 6,
- 0, 0, 168, 168, 168, 168, 168, 168, 248, 5, 7, 7, 6, 0, 0, 192,
- 64, 64, 112, 72, 72, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 200,
- 168, 168, 200, 5, 7, 7, 6, 0, 0, 112, 136, 8, 56, 8, 136, 112,
- 5, 7, 7, 6, 0, 0, 144, 168, 168, 232, 168, 168, 144, 5, 7, 7,
- 6, 0, 0, 120, 136, 136, 120, 40, 72, 136, 5, 7, 7, 6, 0, 0,
- 24, 96, 128, 240, 136, 136, 112, 4, 5, 5, 6, 0, 0, 224, 144, 224,
- 144, 224, 5, 5, 5, 6, 0, 0, 248, 136, 128, 128, 128, 5, 7, 7,
- 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, 5, 5, 5, 6, 0, 0,
- 168, 168, 112, 168, 168, 5, 5, 5, 6, 0, 0, 240, 8, 48, 8, 240,
- 5, 5, 5, 6, 0, 0, 136, 152, 168, 200, 136, 5, 7, 7, 6, 0,
- 0, 80, 32, 136, 152, 168, 200, 136, 4, 5, 5, 6, 0, 0, 144, 160,
- 192, 160, 144, 5, 5, 5, 6, 0, 0, 248, 40, 40, 168, 72, 5, 5,
- 5, 6, 0, 0, 136, 216, 168, 136, 136, 5, 5, 5, 6, 0, 0, 136,
- 136, 248, 136, 136, 5, 5, 5, 6, 0, 0, 248, 136, 136, 136, 136, 5,
- 5, 5, 6, 0, 0, 248, 32, 32, 32, 32, 5, 5, 5, 6, 0, 0,
- 136, 136, 120, 8, 8, 5, 5, 5, 6, 0, 0, 168, 168, 168, 168, 248,
- 5, 5, 5, 6, 0, 0, 192, 64, 112, 72, 112, 5, 5, 5, 6, 0,
- 0, 136, 136, 200, 168, 200, 4, 5, 5, 6, 0, 0, 128, 128, 224, 144,
- 224, 5, 5, 5, 6, 0, 0, 112, 136, 56, 136, 112, 5, 5, 5, 6,
- 0, 0, 144, 168, 232, 168, 144, 5, 5, 5, 6, 0, 0, 120, 136, 120,
- 40, 72, 5, 5, 5, 6, 0, 1, 32, 72, 144, 72, 32, 5, 5, 5,
- 6, 0, 1, 32, 144, 72, 144, 32, 5, 3, 3, 6, 0, 0, 72, 144,
- 216, 5, 3, 3, 6, 0, 4, 216, 72, 144, 5, 7, 7, 6, 0, 0,
- 144, 208, 176, 144, 56, 40, 56, 5, 7, 7, 6, 0, 0, 32, 0, 32,
- 64, 128, 136, 112, 5, 7, 7, 6, 0, 0, 24, 32, 32, 112, 32, 32,
- 192, 5, 7, 7, 6, 0, 0, 32, 80, 64, 240, 64, 64, 120, 1, 2,
- 2, 6, 2, 0, 128, 128, 1, 4, 4, 6, 2, 0, 128, 128, 128, 128,
- 3, 5, 5, 6, 1, 0, 160, 160, 160, 0, 224, 3, 5, 5, 6, 1,
- 0, 160, 160, 160, 0, 160, 5, 7, 7, 6, 0, 0, 160, 0, 232, 16,
- 32, 64, 128, 5, 5, 5, 6, 0, 1, 216, 112, 32, 112, 216, 5, 7,
- 7, 6, 0, 0, 160, 64, 168, 16, 32, 64, 128, 3, 6, 6, 6, 1,
- 1, 224, 64, 64, 64, 64, 224, 5, 6, 6, 6, 0, 1, 248, 80, 80,
- 80, 80, 248, 5, 7, 7, 6, 0, 0, 32, 112, 168, 32, 32, 32, 32,
- 5, 7, 7, 6, 0, 0, 32, 32, 32, 32, 168, 112, 32, 5, 7, 7,
- 6, 0, 0, 128, 144, 176, 248, 176, 144, 128, 5, 7, 7, 6, 0, 0,
- 8, 72, 104, 248, 104, 72, 8, 5, 7, 7, 6, 0, 0, 128, 136, 168,
- 248, 168, 136, 128, 5, 7, 7, 6, 0, 0, 128, 224, 136, 16, 32, 64,
- 128, 2, 2, 2, 6, 2, 2, 192, 192, 5, 8, 8, 6, 0, 255, 120,
- 40, 40, 40, 72, 136, 248, 136, 5, 8, 8, 6, 0, 255, 136, 136, 136,
- 136, 136, 136, 248, 8, 5, 8, 8, 6, 0, 255, 168, 168, 168, 168, 168,
- 168, 248, 8, 5, 6, 6, 6, 0, 255, 120, 40, 72, 136, 248, 136, 5,
- 7, 7, 6, 0, 255, 32, 32, 112, 168, 168, 112, 32, 5, 6, 6, 6,
- 0, 255, 136, 136, 136, 136, 248, 8, 5, 6, 6, 6, 0, 255, 168, 168,
- 168, 168, 248, 8, 2, 2, 2, 6, 2, 6, 64, 128, 3, 1, 1, 6,
- 1, 7, 160, 5, 2, 2, 6, 0, 6, 72, 176, 5, 8, 8, 6, 0,
- 0, 16, 32, 0, 112, 136, 248, 128, 112, 5, 6, 6, 6, 0, 255, 112,
- 128, 136, 112, 32, 96, 3, 7, 7, 6, 1, 0, 160, 0, 160, 160, 160,
- 32, 192, 5, 6, 6, 6, 0, 1, 32, 112, 112, 112, 248, 32, 5, 5,
- 5, 6, 0, 1, 80, 0, 136, 0, 80, 5, 5, 5, 6, 0, 1, 112,
- 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 144, 168, 88, 184, 8,
- 8, 5, 7, 7, 6, 0, 0, 136, 144, 184, 72, 184, 8, 56, 5, 7,
- 7, 6, 0, 0, 136, 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0,
- 0, 192, 64, 192, 72, 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 136,
- 248, 136, 248, 136, 248, 136, 4, 5, 5, 6, 0, 2, 192, 0, 48, 0,
- 96, 5, 8, 8, 6, 0, 0, 64, 160, 224, 168, 8, 40, 120, 32, 5,
- 8, 8, 6, 0, 0, 64, 112, 64, 120, 64, 112, 64, 224, 5, 8, 8,
- 6, 0, 0, 32, 112, 32, 248, 32, 112, 32, 112, 5, 7, 7, 6, 0,
- 0, 104, 0, 232, 0, 104, 16, 56, 5, 8, 8, 6, 0, 0, 16, 112,
- 16, 240, 16, 112, 16, 56, 5, 7, 7, 6, 0, 1, 32, 112, 32, 248,
- 32, 112, 32, 5, 8, 8, 6, 0, 0, 16, 144, 80, 48, 80, 144, 16,
- 56, 5, 8, 8, 6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 5,
- 7, 7, 6, 0, 0, 120, 168, 168, 120, 40, 40, 40, 5, 8, 8, 6,
- 0, 0, 248, 248, 248, 248, 248, 248, 248, 248
-};
diff --git a/Marlin/dogm_font_data_HD44780_J.h b/Marlin/dogm_font_data_HD44780_J.h
deleted file mode 100644
index e4884c7cbc..0000000000
--- a/Marlin/dogm_font_data_HD44780_J.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-/**
- Fontname: HD44780_J
- Copyright: A. Hardtung, public domain
- Capital A Height: 7, '1' Height: 7
- Calculated Max Values w= 6 h=10 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 8
- Font Bounding box w= 6 h= 9 x= 0 y=-2
- Calculated Min Values x= 0 y=-2 dx= 0 dy= 0
- Pure Font ascent = 7 descent=-1
- X Font ascent = 7 descent=-1
- Max Font ascent = 8 descent=-2
-*/
-#include
-const u8g_fntpgm_uint8_t HD44780_J_5x7[2492] U8G_SECTION(".progmem.HD44780_J_5x7") = {
- 0, 6, 9, 0, 254, 7, 1, 145, 3, 34, 32, 255, 255, 8, 254, 7,
- 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128,
- 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6,
- 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32,
- 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32,
- 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104,
- 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32,
- 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32,
- 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5,
- 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192,
- 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192,
- 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6,
- 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64,
- 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112,
- 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240,
- 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7,
- 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0,
- 48, 64, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16,
- 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136,
- 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5,
- 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192,
- 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64,
- 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1,
- 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136,
- 8, 16, 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168,
- 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7,
- 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0,
- 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144,
- 136, 136, 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128,
- 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5,
- 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6,
- 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128,
- 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16,
- 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136,
- 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7,
- 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0,
- 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136,
- 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128,
- 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7,
- 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0,
- 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32,
- 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136,
- 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5,
- 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6,
- 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136,
- 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32,
- 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224,
- 5, 7, 7, 6, 0, 0, 136, 80, 248, 32, 248, 32, 32, 3, 7, 7,
- 6, 1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4,
- 32, 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5,
- 128, 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7,
- 6, 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0,
- 112, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136,
- 136, 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7,
- 6, 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255,
- 112, 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200,
- 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128,
- 3, 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7,
- 7, 6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1,
- 0, 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168,
- 168, 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5,
- 5, 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240,
- 136, 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8,
- 8, 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6,
- 0, 0, 112, 128, 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224,
- 64, 64, 72, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5,
- 5, 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0,
- 136, 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136,
- 5, 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6,
- 0, 0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64,
- 128, 64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128,
- 128, 3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 5,
- 5, 6, 0, 1, 32, 16, 248, 16, 32, 5, 5, 5, 6, 0, 1, 32,
- 64, 248, 64, 32, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
- 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
- 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
- 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
- 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 3, 3, 3, 6, 0, 0,
- 224, 160, 224, 3, 4, 4, 6, 2, 3, 224, 128, 128, 128, 3, 4, 4,
- 6, 0, 0, 32, 32, 32, 224, 3, 3, 3, 6, 0, 0, 128, 64, 32,
- 2, 2, 2, 6, 1, 2, 192, 192, 5, 6, 6, 6, 0, 0, 248, 8,
- 248, 8, 16, 32, 5, 5, 5, 6, 0, 0, 248, 8, 48, 32, 64, 4,
- 5, 5, 6, 0, 0, 16, 32, 96, 160, 32, 5, 5, 5, 6, 0, 0,
- 32, 248, 136, 8, 48, 5, 4, 4, 6, 0, 0, 248, 32, 32, 248, 5,
- 5, 5, 6, 0, 0, 16, 248, 48, 80, 144, 5, 5, 5, 6, 0, 0,
- 64, 248, 72, 80, 64, 5, 4, 4, 6, 0, 0, 112, 16, 16, 248, 4,
- 5, 5, 6, 0, 0, 240, 16, 240, 16, 240, 5, 4, 4, 6, 0, 0,
- 168, 168, 8, 48, 5, 1, 1, 6, 0, 3, 248, 5, 7, 7, 6, 0,
- 0, 248, 8, 40, 48, 32, 32, 64, 5, 7, 7, 6, 0, 0, 8, 16,
- 32, 96, 160, 32, 32, 5, 7, 7, 6, 0, 0, 32, 248, 136, 136, 8,
- 16, 32, 5, 6, 6, 6, 0, 0, 248, 32, 32, 32, 32, 248, 5, 7,
- 7, 6, 0, 0, 16, 248, 16, 48, 80, 144, 16, 5, 7, 7, 6, 0,
- 0, 64, 248, 72, 72, 72, 72, 144, 5, 7, 7, 6, 0, 0, 32, 248,
- 32, 248, 32, 32, 32, 5, 6, 6, 6, 0, 0, 120, 72, 136, 8, 16,
- 96, 5, 7, 7, 6, 0, 0, 64, 120, 144, 16, 16, 16, 32, 5, 6,
- 6, 6, 0, 0, 248, 8, 8, 8, 8, 248, 5, 7, 7, 6, 0, 0,
- 80, 248, 80, 80, 16, 32, 64, 5, 6, 6, 6, 0, 0, 192, 8, 200,
- 8, 16, 224, 5, 6, 6, 6, 0, 0, 248, 8, 16, 32, 80, 136, 5,
- 7, 7, 6, 0, 0, 64, 248, 72, 80, 64, 64, 56, 5, 6, 6, 6,
- 0, 0, 136, 136, 72, 8, 16, 96, 5, 6, 6, 6, 0, 0, 120, 72,
- 168, 24, 16, 96, 5, 7, 7, 6, 0, 0, 16, 224, 32, 248, 32, 32,
- 64, 5, 6, 6, 6, 0, 0, 168, 168, 168, 8, 16, 32, 5, 7, 7,
- 6, 0, 0, 112, 0, 248, 32, 32, 32, 64, 3, 7, 7, 6, 1, 0,
- 128, 128, 128, 192, 160, 128, 128, 5, 7, 7, 6, 0, 0, 32, 32, 248,
- 32, 32, 64, 128, 5, 6, 6, 6, 0, 0, 112, 0, 0, 0, 0, 248,
- 5, 6, 6, 6, 0, 0, 248, 8, 80, 32, 80, 128, 5, 7, 7, 6,
- 0, 0, 32, 248, 16, 32, 112, 168, 32, 3, 7, 7, 6, 1, 0, 32,
- 32, 32, 32, 32, 64, 128, 5, 6, 6, 6, 0, 0, 32, 16, 136, 136,
- 136, 136, 5, 7, 7, 6, 0, 0, 128, 128, 248, 128, 128, 128, 120, 5,
- 6, 6, 6, 0, 0, 248, 8, 8, 8, 16, 96, 5, 5, 5, 6, 0,
- 1, 64, 160, 16, 8, 8, 5, 7, 7, 6, 0, 0, 32, 248, 32, 32,
- 168, 168, 32, 5, 6, 6, 6, 0, 0, 248, 8, 8, 80, 32, 16, 4,
- 6, 6, 6, 1, 0, 224, 0, 224, 0, 224, 16, 5, 6, 6, 6, 0,
- 0, 32, 64, 128, 136, 248, 8, 5, 6, 6, 6, 0, 0, 8, 8, 80,
- 32, 80, 128, 5, 6, 6, 6, 0, 0, 248, 64, 248, 64, 64, 56, 5,
- 7, 7, 6, 0, 0, 64, 64, 248, 72, 80, 64, 64, 5, 7, 7, 6,
- 0, 0, 112, 16, 16, 16, 16, 16, 248, 5, 6, 6, 6, 0, 0, 248,
- 8, 248, 8, 8, 248, 5, 7, 7, 6, 0, 0, 112, 0, 248, 8, 8,
- 16, 32, 4, 7, 7, 6, 0, 0, 144, 144, 144, 144, 16, 32, 64, 5,
- 6, 6, 6, 0, 0, 32, 160, 160, 168, 168, 176, 5, 7, 7, 6, 0,
- 0, 128, 128, 128, 136, 144, 160, 192, 5, 6, 6, 6, 0, 0, 248, 136,
- 136, 136, 136, 248, 5, 6, 6, 6, 0, 0, 248, 136, 136, 8, 16, 32,
- 5, 6, 6, 6, 0, 0, 192, 0, 8, 8, 16, 224, 4, 3, 3, 6,
- 0, 4, 32, 144, 64, 3, 3, 3, 6, 0, 4, 224, 160, 224, 5, 5,
- 5, 6, 0, 1, 72, 168, 144, 144, 104, 5, 7, 7, 6, 0, 0, 80,
- 0, 112, 8, 120, 136, 120, 4, 8, 8, 6, 1, 255, 96, 144, 144, 224,
- 144, 144, 224, 128, 5, 5, 5, 6, 0, 0, 112, 128, 96, 136, 112, 5,
- 6, 6, 6, 0, 255, 136, 136, 152, 232, 136, 128, 5, 5, 5, 6, 0,
- 0, 120, 160, 144, 136, 112, 5, 7, 7, 6, 0, 254, 48, 72, 136, 136,
- 240, 128, 128, 5, 8, 8, 6, 0, 254, 120, 136, 136, 136, 120, 8, 8,
- 112, 5, 5, 5, 6, 0, 1, 56, 32, 32, 160, 64, 4, 3, 3, 6,
- 0, 3, 16, 208, 16, 4, 8, 8, 6, 0, 255, 16, 0, 48, 16, 16,
- 16, 144, 96, 3, 3, 3, 6, 0, 4, 160, 64, 160, 5, 7, 7, 6,
- 0, 0, 32, 112, 160, 160, 168, 112, 32, 5, 7, 7, 6, 0, 0, 64,
- 64, 224, 64, 224, 64, 120, 5, 7, 7, 6, 0, 0, 112, 0, 176, 200,
- 136, 136, 136, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 136, 136, 112,
- 5, 7, 7, 6, 0, 255, 176, 200, 136, 136, 240, 128, 128, 5, 7, 7,
- 6, 0, 255, 104, 152, 136, 136, 120, 8, 8, 5, 6, 6, 6, 0, 0,
- 112, 136, 248, 136, 136, 112, 5, 3, 3, 6, 0, 2, 88, 168, 208, 5,
- 5, 5, 6, 0, 0, 112, 136, 136, 80, 216, 5, 7, 7, 6, 0, 0,
- 80, 0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 248, 128, 64,
- 32, 64, 128, 248, 5, 5, 5, 6, 0, 0, 248, 80, 80, 80, 152, 5,
- 7, 7, 6, 0, 0, 248, 0, 136, 80, 32, 80, 136, 5, 7, 7, 6,
- 0, 255, 136, 136, 136, 136, 120, 8, 112, 5, 6, 6, 6, 0, 0, 8,
- 240, 32, 248, 32, 32, 5, 5, 5, 6, 0, 0, 248, 64, 120, 72, 136,
- 5, 5, 5, 6, 0, 0, 248, 168, 248, 136, 136, 5, 5, 5, 6, 0,
- 1, 32, 0, 248, 0, 32, 0, 0, 0, 6, 0, 0, 6, 10, 10, 6,
- 0, 254, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252
-};
diff --git a/Marlin/dogm_font_data_HD44780_W.h b/Marlin/dogm_font_data_HD44780_W.h
deleted file mode 100644
index 86b4bf4bff..0000000000
--- a/Marlin/dogm_font_data_HD44780_W.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-/**
- Fontname: HD44780_W
- Copyright: A.Hardtung, public domain
- Capital A Height: 7, '1' Height: 7
- Calculated Max Values w= 5 h= 9 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 9
- Font Bounding box w= 6 h= 9 x= 0 y=-2
- Calculated Min Values x= 0 y=-1 dx= 0 dy= 0
- Pure Font ascent = 7 descent=-1
- X Font ascent = 7 descent=-1
- Max Font ascent = 8 descent=-1
-*/
-#include
-const u8g_fntpgm_uint8_t HD44780_W_5x7[3034] U8G_SECTION(".progmem.HD44780_W_5x7") = {
- 0, 6, 9, 0, 254, 7, 2, 79, 3, 222, 16, 255, 255, 8, 255, 7,
- 255, 4, 7, 7, 6, 0, 0, 16, 48, 112, 240, 112, 48, 16, 4, 7,
- 7, 6, 1, 0, 128, 192, 224, 240, 224, 192, 128, 5, 3, 3, 6, 0,
- 4, 216, 72, 144, 5, 3, 3, 6, 0, 4, 216, 144, 72, 5, 7, 7,
- 6, 0, 0, 32, 112, 248, 0, 32, 112, 248, 5, 7, 7, 6, 0, 0,
- 248, 112, 32, 0, 248, 112, 32, 5, 5, 5, 6, 0, 1, 112, 248, 248,
- 248, 112, 5, 7, 7, 6, 0, 0, 8, 8, 40, 72, 248, 64, 32, 5,
- 7, 7, 6, 0, 0, 32, 112, 168, 32, 32, 32, 32, 5, 7, 7, 6,
- 0, 0, 32, 32, 32, 32, 168, 112, 32, 5, 5, 5, 6, 0, 1, 32,
- 64, 248, 64, 32, 5, 5, 5, 6, 0, 1, 32, 16, 248, 16, 32, 5,
- 7, 7, 6, 0, 0, 16, 32, 64, 32, 16, 0, 248, 5, 7, 7, 6,
- 0, 0, 64, 32, 16, 32, 64, 0, 248, 5, 5, 5, 6, 0, 1, 32,
- 32, 112, 112, 248, 5, 5, 5, 6, 0, 0, 248, 112, 112, 32, 32, 0,
- 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128,
- 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, 0, 0,
- 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, 120, 160,
- 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, 64, 152,
- 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, 2, 3,
- 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, 64, 128,
- 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, 32, 64,
- 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, 5, 6,
- 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, 64, 128,
- 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, 192, 5,
- 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0,
- 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, 192, 64,
- 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, 128, 128,
- 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, 5, 7,
- 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, 6, 0,
- 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, 48, 64,
- 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, 32,
- 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, 112, 5,
- 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5, 5, 6,
- 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, 192, 0,
- 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, 32, 16,
- 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, 0, 128,
- 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, 8, 16,
- 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168, 112, 5,
- 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7, 7, 6,
- 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, 0, 112,
- 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144, 136, 136,
- 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 248,
- 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5, 7, 7,
- 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6, 0, 0,
- 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, 128, 128,
- 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, 16, 144,
- 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136, 5, 7,
- 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7, 6, 0,
- 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 136, 136,
- 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 136,
- 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128, 128, 5,
- 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7, 7, 6,
- 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0, 0, 120,
- 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32, 32, 32,
- 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 136, 112,
- 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5, 7, 7,
- 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6, 0, 0,
- 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136, 136, 136,
- 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, 64, 128,
- 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224, 5, 5,
- 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, 1, 0, 224,
- 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, 80, 136, 5,
- 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, 64, 5, 5,
- 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, 0, 128,
- 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, 128, 128, 136,
- 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, 120, 5, 5,
- 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, 0, 0, 48,
- 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, 136, 136, 120,
- 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, 136, 136, 1,
- 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, 8, 8, 6,
- 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, 6, 0, 0,
- 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, 192, 64, 64,
- 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, 168, 168, 5,
- 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, 6, 0, 0,
- 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, 136, 240, 128,
- 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, 5, 5, 5,
- 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, 0, 112, 128,
- 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, 64, 64, 72, 48,
- 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, 5, 6, 0,
- 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, 136, 168, 168,
- 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, 6, 6, 6,
- 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, 0, 248, 16,
- 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, 64, 64, 32,
- 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, 3, 7, 7,
- 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 6, 6, 6, 0, 1,
- 8, 40, 72, 248, 64, 32, 5, 7, 7, 6, 0, 0, 32, 80, 136, 136,
- 136, 136, 248, 5, 7, 7, 6, 0, 0, 248, 136, 128, 240, 136, 136, 240,
- 5, 8, 8, 6, 0, 255, 120, 40, 40, 40, 72, 136, 248, 136, 5, 7,
- 7, 6, 0, 0, 168, 168, 168, 112, 168, 168, 168, 5, 7, 7, 6, 0,
- 0, 240, 8, 8, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 136, 136,
- 152, 168, 200, 136, 136, 5, 8, 8, 6, 0, 0, 80, 32, 136, 152, 168,
- 168, 200, 136, 5, 7, 7, 6, 0, 0, 120, 40, 40, 40, 40, 168, 72,
- 5, 7, 7, 6, 0, 0, 248, 136, 136, 136, 136, 136, 136, 5, 7, 7,
- 6, 0, 0, 136, 136, 136, 80, 32, 64, 128, 5, 8, 8, 6, 0, 255,
- 136, 136, 136, 136, 136, 136, 248, 8, 5, 7, 7, 6, 0, 0, 136, 136,
- 136, 120, 8, 8, 8, 5, 7, 7, 6, 0, 0, 168, 168, 168, 168, 168,
- 168, 248, 5, 8, 8, 6, 0, 255, 168, 168, 168, 168, 168, 168, 248, 8,
- 5, 7, 7, 6, 0, 0, 192, 64, 64, 112, 72, 72, 112, 5, 7, 7,
- 6, 0, 0, 136, 136, 136, 200, 168, 168, 200, 5, 7, 7, 6, 0, 0,
- 112, 136, 40, 80, 8, 136, 112, 5, 5, 5, 6, 0, 0, 64, 160, 144,
- 144, 104, 5, 7, 7, 6, 0, 0, 32, 48, 40, 40, 32, 224, 224, 5,
- 7, 7, 6, 0, 0, 248, 136, 128, 128, 128, 128, 128, 5, 5, 5, 6,
- 0, 0, 248, 80, 80, 80, 152, 5, 7, 7, 6, 0, 0, 248, 128, 64,
- 32, 64, 128, 248, 5, 5, 5, 6, 0, 0, 120, 144, 144, 144, 96, 5,
- 7, 7, 6, 0, 0, 48, 40, 56, 40, 200, 216, 24, 5, 6, 6, 6,
- 0, 0, 8, 112, 160, 32, 32, 16, 5, 6, 6, 6, 0, 1, 32, 112,
- 112, 112, 248, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136,
- 112, 5, 5, 5, 6, 0, 0, 112, 136, 136, 80, 216, 5, 7, 7, 6,
- 0, 0, 48, 72, 32, 80, 136, 136, 112, 5, 3, 3, 6, 0, 2, 88,
- 168, 208, 5, 6, 6, 6, 0, 0, 80, 248, 248, 248, 112, 32, 5, 5,
- 5, 6, 0, 0, 112, 128, 96, 136, 112, 5, 7, 7, 6, 0, 0, 112,
- 136, 136, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 216, 216, 216, 216,
- 216, 216, 216, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128,
- 5, 7, 7, 6, 0, 0, 32, 112, 160, 160, 168, 112, 32, 5, 7, 7,
- 6, 0, 0, 48, 64, 64, 224, 64, 80, 168, 5, 5, 5, 6, 0, 0,
- 136, 112, 80, 112, 136, 5, 7, 7, 6, 0, 0, 136, 80, 248, 32, 248,
- 32, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 0, 128, 128, 128, 5,
- 8, 8, 6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 5, 7, 7,
- 6, 0, 0, 24, 32, 32, 112, 32, 32, 192, 5, 7, 7, 6, 0, 0,
- 248, 136, 184, 184, 184, 136, 248, 5, 7, 7, 6, 0, 0, 112, 8, 120,
- 136, 120, 0, 248, 5, 5, 5, 6, 0, 1, 40, 80, 160, 80, 40, 5,
- 7, 7, 6, 0, 0, 144, 168, 168, 232, 168, 168, 144, 5, 7, 7, 6,
- 0, 0, 120, 136, 136, 120, 40, 72, 136, 5, 7, 7, 6, 0, 0, 248,
- 136, 168, 136, 152, 168, 248, 2, 3, 3, 6, 2, 4, 64, 128, 192, 4,
- 5, 5, 6, 0, 3, 96, 144, 144, 144, 96, 5, 7, 7, 6, 0, 0,
- 32, 32, 248, 32, 32, 0, 248, 4, 5, 5, 6, 0, 3, 96, 144, 32,
- 64, 240, 3, 5, 5, 6, 0, 3, 224, 32, 224, 32, 224, 5, 8, 8,
- 6, 0, 0, 224, 144, 224, 128, 144, 184, 144, 24, 5, 8, 8, 6, 0,
- 255, 136, 136, 136, 136, 152, 232, 128, 128, 5, 7, 7, 6, 0, 0, 120,
- 152, 152, 120, 24, 24, 24, 2, 2, 2, 6, 2, 2, 192, 192, 5, 5,
- 5, 6, 0, 0, 80, 136, 168, 168, 80, 3, 5, 5, 6, 0, 3, 64,
- 192, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 112, 0,
- 248, 5, 5, 5, 6, 0, 1, 160, 80, 40, 80, 160, 5, 7, 7, 6,
- 0, 0, 136, 144, 168, 88, 184, 8, 8, 5, 7, 7, 6, 0, 0, 136,
- 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, 0, 192, 64, 192, 72,
- 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 32, 0, 32, 64, 128, 136,
- 112, 5, 8, 8, 6, 0, 0, 64, 32, 32, 80, 136, 248, 136, 136, 5,
- 8, 8, 6, 0, 0, 16, 32, 32, 80, 136, 248, 136, 136, 5, 8, 8,
- 6, 0, 0, 32, 80, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6, 0,
- 0, 104, 144, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0, 80,
- 0, 32, 80, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0, 32, 80, 32,
- 112, 136, 248, 136, 136, 5, 7, 7, 6, 0, 0, 56, 96, 160, 184, 224,
- 160, 184, 5, 8, 8, 6, 0, 255, 112, 136, 128, 128, 136, 112, 32, 96,
- 5, 8, 8, 6, 0, 0, 64, 32, 0, 248, 128, 240, 128, 248, 5, 8,
- 8, 6, 0, 0, 8, 16, 0, 248, 128, 240, 128, 248, 5, 8, 8, 6,
- 0, 0, 32, 80, 0, 248, 128, 240, 128, 248, 5, 7, 7, 6, 0, 0,
- 80, 0, 248, 128, 240, 128, 248, 3, 8, 8, 6, 1, 0, 128, 64, 0,
- 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64, 0, 224, 64,
- 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 224, 64, 64, 64,
- 224, 3, 7, 7, 6, 1, 0, 160, 0, 224, 64, 64, 64, 224, 5, 7,
- 7, 6, 0, 0, 112, 72, 72, 232, 72, 72, 112, 5, 8, 8, 6, 0,
- 0, 104, 144, 0, 136, 200, 168, 152, 136, 5, 8, 8, 6, 0, 0, 64,
- 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 112,
- 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136,
- 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, 136, 136, 136,
- 112, 5, 8, 8, 6, 0, 0, 80, 0, 112, 136, 136, 136, 136, 112, 5,
- 5, 5, 6, 0, 1, 136, 80, 32, 80, 136, 5, 7, 7, 6, 0, 0,
- 112, 32, 112, 168, 112, 32, 112, 5, 8, 8, 6, 0, 0, 64, 32, 136,
- 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 136, 136, 136,
- 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 136, 136, 136, 136,
- 112, 5, 8, 8, 6, 0, 0, 80, 0, 136, 136, 136, 136, 136, 112, 5,
- 8, 8, 6, 0, 0, 16, 32, 136, 80, 32, 32, 32, 32, 5, 8, 8,
- 6, 0, 0, 192, 64, 112, 72, 72, 112, 64, 224, 5, 7, 7, 6, 0,
- 0, 48, 72, 72, 112, 72, 72, 176, 5, 8, 8, 6, 0, 0, 64, 32,
- 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112,
- 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 8, 120,
- 136, 120, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, 8, 120, 136, 120,
- 5, 7, 7, 6, 0, 0, 80, 0, 112, 8, 120, 136, 120, 5, 8, 8,
- 6, 0, 0, 32, 80, 32, 112, 8, 120, 136, 120, 5, 6, 6, 6, 0,
- 0, 208, 40, 120, 160, 168, 80, 5, 6, 6, 6, 0, 255, 112, 128, 136,
- 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248, 128,
- 112, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 248, 128, 112, 5,
- 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, 248, 128, 112, 5, 7, 7,
- 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, 3, 8, 8, 6, 1, 0,
- 128, 64, 0, 64, 192, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64,
- 0, 64, 192, 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 64,
- 192, 64, 64, 224, 3, 7, 7, 6, 1, 0, 160, 0, 64, 192, 64, 64,
- 224, 5, 7, 7, 6, 0, 0, 160, 64, 160, 16, 120, 136, 112, 5, 8,
- 8, 6, 0, 0, 104, 144, 0, 176, 200, 136, 136, 136, 5, 8, 8, 6,
- 0, 0, 64, 32, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0,
- 16, 32, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80,
- 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112,
- 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 136, 136,
- 112, 5, 5, 5, 6, 0, 1, 32, 0, 248, 0, 32, 5, 7, 7, 6,
- 0, 0, 16, 32, 112, 168, 112, 32, 64, 5, 8, 8, 6, 0, 0, 64,
- 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, 6, 0, 0, 16, 32, 0,
- 136, 136, 136, 152, 104, 5, 8, 8, 6, 0, 0, 32, 80, 0, 136, 136,
- 136, 152, 104, 5, 7, 7, 6, 0, 0, 80, 0, 136, 136, 136, 152, 104,
- 5, 9, 9, 6, 0, 255, 16, 32, 0, 136, 136, 136, 248, 8, 112, 4,
- 7, 7, 6, 1, 0, 192, 64, 96, 80, 96, 64, 224, 5, 8, 8, 6,
- 0, 255, 80, 0, 136, 136, 136, 248, 8, 112
-};
diff --git a/Marlin/dogm_font_data_ISO10646_1.h b/Marlin/dogm_font_data_ISO10646_1.h
deleted file mode 100644
index 5e12ea86ff..0000000000
--- a/Marlin/dogm_font_data_ISO10646_1.h
+++ /dev/null
@@ -1,286 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-/**
- Fontname: ISO10646-1
- Copyright: A.Hardtung, public domain
- Capital A Height: 7, '1' Height: 7
- Calculated Max Values w= 5 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9
- Font Bounding box w= 6 h= 9 x= 0 y=-2
- Calculated Min Values x= 0 y=-1 dx= 0 dy= 0
- Pure Font ascent = 7 descent=-1
- X Font ascent = 7 descent=-1
- Max Font ascent = 8 descent=-1
-*/
-#include
-
-#if defined(__AVR__) && ENABLED(NOT_EXTENDED_ISO10646_1_5X7)
-
- //
- // Reduced font (only symbols 32 - 127) - About 1400 bytes smaller
- //
- const u8g_fntpgm_uint8_t ISO10646_1_5x7[] U8G_SECTION(".progmem.ISO10646_1_5x7") = {
- 0,6,9,0,254,7,1,146,3,33,32,127,255,7,255,7,
- 255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128,
- 128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6,
- 0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32,
- 120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32,
- 64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104,
- 2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32,
- 64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32,
- 32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5,
- 5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192,
- 64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192,
- 192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6,
- 0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64,
- 192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112,
- 128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240,
- 5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7,
- 6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0,
- 112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16,
- 32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136,
- 112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5,
- 5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192,
- 192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64,
- 32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1,
- 0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136,
- 8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168,
- 168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5,
- 7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6,
- 0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240,
- 136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240,
- 128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128,
- 5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7,
- 6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0,
- 128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16,
- 16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144,
- 136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7,
- 7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0,
- 0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136,
- 136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128,
- 128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5,
- 7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6,
- 0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248,
- 32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136,
- 136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32,
- 5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7,
- 6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0,
- 136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16,
- 32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128,
- 224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6,
- 1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32,
- 80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128,
- 64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6,
- 0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112,
- 128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136,
- 120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6,
- 0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112,
- 136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136,
- 136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3,
- 8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7,
- 6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0,
- 192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168,
- 168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5,
- 6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136,
- 136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8,
- 5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0,
- 0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64,
- 64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5,
- 5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136,
- 136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5,
- 6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0,
- 0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128,
- 64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128,
- 3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2,
- 6,0,2,104,144,0,0,0,6,0,0};
-
-#else
-
- //
- // Extended (original) font (symbols 32 - 255)
- //
- const u8g_fntpgm_uint8_t ISO10646_1_5x7[] U8G_SECTION(".progmem.ISO10646_1_5x7") = {
- 0, 6, 9, 0, 254, 7, 1, 146, 3, 33, 32, 255, 255, 8, 255, 7,
- 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128,
- 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6,
- 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32,
- 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32,
- 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104,
- 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32,
- 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32,
- 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5,
- 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192,
- 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192,
- 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6,
- 0, 0, 112, 136, 136, 136, 136, 136, 112, 3, 7, 7, 6, 1, 0, 64,
- 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112,
- 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240,
- 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7,
- 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0,
- 112, 128, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16,
- 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136,
- 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 8, 112, 2, 5,
- 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192,
- 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64,
- 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1,
- 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136,
- 8, 16, 32, 0, 32, 5, 7, 7, 6, 0, 0, 112, 136, 8, 104, 168,
- 168, 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5,
- 7, 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6,
- 0, 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 240,
- 136, 136, 136, 136, 136, 240, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240,
- 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128,
- 5, 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7,
- 6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0,
- 128, 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16,
- 16, 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144,
- 136, 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7,
- 7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0,
- 0, 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136,
- 136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128,
- 128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5,
- 7, 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6,
- 0, 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248,
- 32, 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136,
- 136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32,
- 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7,
- 6, 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0,
- 136, 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16,
- 32, 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128,
- 224, 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6,
- 1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32,
- 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128,
- 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6,
- 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112,
- 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136,
- 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6,
- 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112,
- 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136,
- 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3,
- 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7,
- 6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0,
- 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168,
- 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5,
- 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136,
- 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8,
- 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0,
- 0, 112, 128, 112, 8, 240, 4, 7, 7, 6, 0, 0, 64, 64, 224, 64,
- 64, 64, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5,
- 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136,
- 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5,
- 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0,
- 0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128,
- 64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128,
- 3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2,
- 6, 0, 2, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
- 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
- 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
- 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
- 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
- 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
- 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
- 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
- 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
- 0, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 5, 7,
- 7, 6, 0, 0, 32, 112, 168, 160, 168, 112, 32, 5, 7, 7, 6, 0,
- 0, 48, 64, 64, 224, 64, 80, 168, 5, 5, 5, 6, 0, 0, 136, 112,
- 80, 112, 136, 5, 7, 7, 6, 0, 0, 136, 80, 32, 248, 32, 248, 32,
- 1, 7, 7, 6, 2, 0, 128, 128, 128, 0, 128, 128, 128, 5, 8, 8,
- 6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 3, 1, 1, 6, 1,
- 7, 160, 5, 7, 7, 6, 0, 0, 248, 136, 184, 184, 184, 136, 248, 5,
- 7, 7, 6, 0, 1, 112, 8, 120, 136, 120, 0, 248, 5, 5, 5, 6,
- 0, 1, 40, 80, 160, 80, 40, 5, 3, 3, 6, 0, 1, 248, 8, 8,
- 2, 2, 2, 6, 2, 6, 64, 128, 5, 7, 7, 6, 0, 0, 248, 136,
- 168, 136, 152, 168, 248, 5, 1, 1, 6, 0, 6, 248, 4, 4, 4, 6,
- 0, 3, 96, 144, 144, 96, 5, 7, 7, 6, 0, 0, 32, 32, 248, 32,
- 32, 0, 248, 4, 5, 5, 6, 0, 3, 96, 144, 32, 64, 240, 3, 5,
- 5, 6, 0, 3, 224, 32, 224, 32, 224, 2, 2, 2, 6, 2, 6, 64,
- 128, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 152, 232, 128, 128, 5,
- 7, 7, 6, 0, 0, 120, 152, 152, 120, 24, 24, 24, 2, 2, 2, 6,
- 2, 2, 192, 192, 2, 2, 2, 6, 2, 255, 64, 128, 3, 5, 5, 6,
- 0, 3, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 1, 112, 136, 136,
- 136, 112, 0, 248, 5, 5, 5, 6, 0, 1, 160, 80, 40, 80, 160, 5,
- 7, 7, 6, 0, 0, 136, 144, 168, 88, 184, 8, 8, 5, 7, 7, 6,
- 0, 0, 136, 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, 0, 192,
- 64, 192, 72, 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 32, 0, 32,
- 64, 128, 136, 112, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248,
- 136, 136, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 248, 136, 136,
- 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, 248, 136, 136, 5, 8,
- 8, 6, 0, 0, 104, 144, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6,
- 0, 0, 80, 0, 112, 136, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0,
- 32, 80, 32, 112, 136, 248, 136, 136, 5, 7, 7, 6, 0, 0, 56, 96,
- 160, 184, 224, 160, 184, 5, 8, 8, 6, 0, 255, 112, 136, 128, 128, 136,
- 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, 32, 0, 248, 128, 240, 128,
- 248, 5, 8, 8, 6, 0, 0, 8, 16, 0, 248, 128, 240, 128, 248, 5,
- 8, 8, 6, 0, 0, 32, 80, 0, 248, 128, 240, 128, 248, 5, 7, 7,
- 6, 0, 0, 80, 0, 248, 128, 240, 128, 248, 3, 8, 8, 6, 1, 0,
- 128, 64, 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64,
- 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 224,
- 64, 64, 64, 224, 3, 7, 7, 6, 1, 0, 160, 0, 224, 64, 64, 64,
- 224, 5, 7, 7, 6, 0, 0, 112, 72, 72, 232, 72, 72, 112, 5, 8,
- 8, 6, 0, 0, 104, 144, 0, 136, 200, 168, 152, 136, 5, 8, 8, 6,
- 0, 0, 64, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0,
- 16, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80,
- 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112,
- 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 112, 136, 136, 136,
- 136, 112, 5, 5, 5, 6, 0, 1, 136, 80, 32, 80, 136, 5, 8, 8,
- 6, 0, 255, 16, 112, 168, 168, 168, 168, 112, 64, 5, 8, 8, 6, 0,
- 0, 64, 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16,
- 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0,
- 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 136, 136, 136,
- 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 136, 80, 32, 32, 32,
- 32, 5, 9, 9, 6, 0, 255, 192, 64, 112, 72, 72, 112, 64, 64, 224,
- 4, 8, 8, 6, 1, 255, 96, 144, 144, 160, 144, 144, 224, 128, 5, 8,
- 8, 6, 0, 0, 64, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6,
- 0, 0, 16, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0,
- 32, 80, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 104, 144,
- 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, 0, 80, 0, 112, 8,
- 120, 136, 120, 5, 8, 8, 6, 0, 0, 32, 80, 32, 112, 8, 120, 136,
- 120, 5, 6, 6, 6, 0, 0, 208, 40, 120, 160, 168, 80, 5, 6, 6,
- 6, 0, 255, 112, 128, 136, 112, 32, 96, 5, 8, 8, 6, 0, 0, 64,
- 32, 0, 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 16, 32, 0,
- 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136,
- 248, 128, 112, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 248, 128, 112,
- 3, 8, 8, 6, 1, 0, 128, 64, 0, 64, 192, 64, 64, 224, 3, 8,
- 8, 6, 1, 0, 32, 64, 0, 64, 192, 64, 64, 224, 3, 8, 8, 6,
- 1, 0, 64, 160, 0, 64, 192, 64, 64, 224, 3, 7, 7, 6, 1, 0,
- 160, 0, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 0, 160, 64, 160,
- 16, 120, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 176, 200, 136,
- 136, 136, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 136, 136, 112,
- 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 136, 136, 112, 5, 8,
- 8, 6, 0, 0, 32, 80, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6,
- 0, 0, 104, 144, 0, 112, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0,
- 80, 0, 112, 136, 136, 136, 112, 5, 5, 5, 6, 0, 1, 32, 0, 248,
- 0, 32, 5, 7, 7, 6, 0, 255, 16, 112, 168, 168, 168, 112, 64, 5,
- 8, 8, 6, 0, 0, 64, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8,
- 6, 0, 0, 16, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, 6, 0,
- 0, 32, 80, 0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 80,
- 0, 136, 136, 136, 152, 104, 5, 9, 9, 6, 0, 255, 16, 32, 0, 136,
- 136, 136, 248, 8, 112, 4, 7, 7, 6, 1, 255, 192, 64, 96, 80, 96,
- 64, 224, 5, 8, 8, 6, 0, 255, 80, 0, 136, 136, 136, 120, 8, 112
- };
-
-#endif
diff --git a/Marlin/dogm_font_data_ISO10646_1_PL.h b/Marlin/dogm_font_data_ISO10646_1_PL.h
deleted file mode 100644
index 47b0bbb065..0000000000
--- a/Marlin/dogm_font_data_ISO10646_1_PL.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- Fontname: ISO10646-1-PL
- Copyright: A.Hardtung, public domain
- Capital A Height: 7, '1' Height: 7
- Calculated Max Values w= 5 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9
- Font Bounding box w= 6 h= 9 x= 0 y=-2
- Calculated Min Values x= 0 y=-2 dx= 0 dy= 0
- Pure Font ascent = 7 descent=-1
- X Font ascent = 7 descent=-1
- Max Font ascent = 8 descent=-2
-*/
-#include
-const u8g_fntpgm_uint8_t ISO10646_1_PL_5x7[2732] U8G_FONT_SECTION(".progmem.ISO10646_1_PL_5x7") = {
- 0,6,9,0,254,7,1,146,3,33,32,255,255,8,254,7,
- 255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128,
- 128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6,
- 0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32,
- 120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32,
- 64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104,
- 2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32,
- 64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32,
- 32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5,
- 5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192,
- 64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192,
- 192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6,
- 0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64,
- 192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112,
- 128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240,
- 5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7,
- 6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0,
- 112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16,
- 32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136,
- 112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5,
- 5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192,
- 192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64,
- 32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1,
- 0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136,
- 8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168,
- 168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5,
- 7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6,
- 0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240,
- 136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240,
- 128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128,
- 5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7,
- 6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0,
- 128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16,
- 16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144,
- 136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7,
- 7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0,
- 0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136,
- 136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128,
- 128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5,
- 7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6,
- 0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248,
- 32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136,
- 136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32,
- 5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7,
- 6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0,
- 136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16,
- 32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128,
- 224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6,
- 1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32,
- 80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128,
- 64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6,
- 0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112,
- 128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136,
- 120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6,
- 0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112,
- 136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136,
- 136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3,
- 8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7,
- 6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0,
- 192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168,
- 168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5,
- 6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136,
- 136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8,
- 5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0,
- 0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64,
- 64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5,
- 5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136,
- 136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5,
- 6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0,
- 0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128,
- 64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128,
- 3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2,
- 6,0,2,104,144,0,0,0,6,0,0,5,9,9,6,0,
- 254,112,136,136,248,136,136,136,16,32,5,7,7,6,0,254,
- 112,8,120,136,120,16,32,5,8,8,6,0,0,16,32,112,
- 136,128,128,136,112,5,7,7,6,0,0,16,32,112,128,128,
- 136,112,5,9,9,6,0,254,248,128,128,240,128,128,248,8,
- 16,5,7,7,6,0,254,112,136,248,128,112,16,32,5,7,
- 7,6,0,0,128,144,160,192,128,128,248,5,7,7,6,0,
- 0,96,40,48,96,160,32,112,5,8,8,6,0,0,16,168,
- 136,200,168,152,136,136,5,8,8,6,0,0,8,16,0,176,
- 200,136,136,136,5,8,8,6,0,0,16,32,112,136,136,136,
- 136,112,5,8,8,6,0,0,16,32,0,112,136,136,136,112,
- 5,8,8,6,0,0,16,120,128,128,112,8,8,240,5,8,
- 8,6,0,0,16,32,0,112,128,112,8,240,5,8,8,6,
- 0,0,32,248,8,16,32,64,128,248,5,8,8,6,0,0,
- 16,32,0,248,16,32,64,248,5,7,7,6,0,0,248,8,
- 16,248,64,128,248,5,8,8,6,0,0,48,48,0,248,16,
- 32,64,248,0,0,0,6,0,0,0,0,0,6,0,0,0,
- 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
- 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
- 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
- 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
- 0,0,0,0,6,0,0,0,0,0,6,0,0,1,7,7,
- 6,2,0,128,0,128,128,128,128,128,5,7,7,6,0,0,
- 32,112,168,160,168,112,32,5,7,7,6,0,0,48,64,64,
- 224,64,80,168,5,5,5,6,0,0,136,112,80,112,136,5,
- 7,7,6,0,0,136,80,32,248,32,248,32,1,7,7,6,
- 2,0,128,128,128,0,128,128,128,5,8,8,6,0,0,48,
- 72,32,80,80,32,144,96,3,1,1,6,1,7,160,5,7,
- 7,6,0,0,248,136,184,184,184,136,248,5,7,7,6,0,
- 1,112,8,120,136,120,0,248,5,5,5,6,0,1,40,80,
- 160,80,40,5,3,3,6,0,1,248,8,8,2,2,2,6,
- 2,6,64,128,5,7,7,6,0,0,248,136,168,136,152,168,
- 248,5,1,1,6,0,6,248,4,4,4,6,0,3,96,144,
- 144,96,5,7,7,6,0,0,32,32,248,32,32,0,248,4,
- 5,5,6,0,3,96,144,32,64,240,3,5,5,6,0,3,
- 224,32,224,32,224,2,2,2,6,2,6,64,128,5,8,8,
- 6,0,255,136,136,136,136,152,232,128,128,5,7,7,6,0,
- 0,120,152,152,120,24,24,24,2,2,2,6,2,2,192,192,
- 2,2,2,6,2,255,64,128,3,5,5,6,0,3,64,192,
- 64,64,224,5,7,7,6,0,1,112,136,136,136,112,0,248,
- 5,5,5,6,0,1,160,80,40,80,160,5,7,7,6,0,
- 0,136,144,168,88,184,8,8,5,7,7,6,0,0,136,144,
- 184,72,152,32,56,5,8,8,6,0,0,192,64,192,72,216,
- 56,8,8,5,7,7,6,0,0,32,0,32,64,128,136,112,
- 5,8,8,6,0,0,64,32,0,112,136,248,136,136,5,8,
- 8,6,0,0,16,32,0,112,136,248,136,136,5,8,8,6,
- 0,0,32,80,0,112,136,248,136,136,5,8,8,6,0,0,
- 104,144,0,112,136,248,136,136,5,8,8,6,0,0,80,0,
- 112,136,136,248,136,136,5,8,8,6,0,0,32,80,32,112,
- 136,248,136,136,5,7,7,6,0,0,56,96,160,184,224,160,
- 184,5,8,8,6,0,255,112,136,128,128,136,112,32,96,5,
- 8,8,6,0,0,64,32,0,248,128,240,128,248,5,8,8,
- 6,0,0,8,16,0,248,128,240,128,248,5,8,8,6,0,
- 0,32,80,0,248,128,240,128,248,5,7,7,6,0,0,80,
- 0,248,128,240,128,248,3,8,8,6,1,0,128,64,0,224,
- 64,64,64,224,3,8,8,6,1,0,32,64,0,224,64,64,
- 64,224,3,8,8,6,1,0,64,160,0,224,64,64,64,224,
- 3,7,7,6,1,0,160,0,224,64,64,64,224,5,7,7,
- 6,0,0,112,72,72,232,72,72,112,5,8,8,6,0,0,
- 104,144,0,136,200,168,152,136,5,8,8,6,0,0,64,32,
- 112,136,136,136,136,112,5,8,8,6,0,0,16,32,112,136,
- 136,136,136,112,5,8,8,6,0,0,32,80,0,112,136,136,
- 136,112,5,8,8,6,0,0,104,144,0,112,136,136,136,112,
- 5,8,8,6,0,0,80,0,112,136,136,136,136,112,5,5,
- 5,6,0,1,136,80,32,80,136,5,8,8,6,0,255,16,
- 112,168,168,168,168,112,64,5,8,8,6,0,0,64,32,136,
- 136,136,136,136,112,5,8,8,6,0,0,16,32,136,136,136,
- 136,136,112,5,8,8,6,0,0,32,80,0,136,136,136,136,
- 112,5,8,8,6,0,0,80,0,136,136,136,136,136,112,5,
- 8,8,6,0,0,16,32,136,80,32,32,32,32,5,9,9,
- 6,0,255,192,64,112,72,72,112,64,64,224,4,8,8,6,
- 1,255,96,144,144,160,144,144,224,128,5,8,8,6,0,0,
- 64,32,0,112,8,120,136,120,5,8,8,6,0,0,16,32,
- 0,112,8,120,136,120,5,8,8,6,0,0,32,80,0,112,
- 8,120,136,120,5,8,8,6,0,0,104,144,0,112,8,120,
- 136,120,5,7,7,6,0,0,80,0,112,8,120,136,120,5,
- 8,8,6,0,0,32,80,32,112,8,120,136,120,5,6,6,
- 6,0,0,208,40,120,160,168,80,5,6,6,6,0,255,112,
- 128,136,112,32,96,5,8,8,6,0,0,64,32,0,112,136,
- 248,128,112,5,8,8,6,0,0,16,32,0,112,136,248,128,
- 112,5,8,8,6,0,0,32,80,0,112,136,248,128,112,5,
- 7,7,6,0,0,80,0,112,136,248,128,112,3,8,8,6,
- 1,0,128,64,0,64,192,64,64,224,3,8,8,6,1,0,
- 32,64,0,64,192,64,64,224,3,8,8,6,1,0,64,160,
- 0,64,192,64,64,224,3,7,7,6,1,0,160,0,64,192,
- 64,64,224,5,7,7,6,0,0,160,64,160,16,120,136,112,
- 5,8,8,6,0,0,104,144,0,176,200,136,136,136,5,8,
- 8,6,0,0,64,32,0,112,136,136,136,112,5,8,8,6,
- 0,0,16,32,0,112,136,136,136,112,5,8,8,6,0,0,
- 32,80,0,112,136,136,136,112,5,8,8,6,0,0,104,144,
- 0,112,136,136,136,112,5,7,7,6,0,0,80,0,112,136,
- 136,136,112,5,5,5,6,0,1,32,0,248,0,32,5,7,
- 7,6,0,255,16,112,168,168,168,112,64,5,8,8,6,0,
- 0,64,32,0,136,136,136,152,104,5,8,8,6,0,0,16,
- 32,0,136,136,136,152,104,5,8,8,6,0,0,32,80,0,
- 136,136,136,152,104,5,7,7,6,0,0,80,0,136,136,136,
- 152,104,5,9,9,6,0,255,16,32,0,136,136,136,248,8,
- 112,4,7,7,6,1,255,192,64,96,80,96,64,224,5,8,
- 8,6,0,255,80,0,136,136,136,120,8,112};
diff --git a/Marlin/dogm_font_data_ISO10646_1_tr.h b/Marlin/dogm_font_data_ISO10646_1_tr.h
deleted file mode 100644
index e32f59f958..0000000000
--- a/Marlin/dogm_font_data_ISO10646_1_tr.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-/*
- Fontname: ISO10646-1-tr
- Copyright: public domain
- Capital A Height: 7, '1' Height: 7
- Calculated Max Values w= 5 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9
- Font Bounding box w= 6 h= 9 x= 0 y=-2
- Calculated Min Values x= 0 y=-1 dx= 0 dy= 0
- Pure Font ascent = 7 descent=-1
- X Font ascent = 7 descent=-1
- Max Font ascent = 8 descent=-1
-*/
-#include
-const u8g_fntpgm_uint8_t ISO10646_TR[2591] U8G_SECTION(".progmem.ISO10646_TR") = {
- 0,6,9,0,254,7,1,146,3,33,32,255,255,8,255,7,
- 255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128,
- 128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6,
- 0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32,
- 120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32,
- 64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104,
- 2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32,
- 64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32,
- 32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5,
- 5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192,
- 64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192,
- 192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6,
- 0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64,
- 192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112,
- 128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240,
- 5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7,
- 6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0,
- 112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16,
- 32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136,
- 112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5,
- 5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192,
- 192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64,
- 32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1,
- 0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136,
- 8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168,
- 168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5,
- 7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6,
- 0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240,
- 136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240,
- 128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128,
- 5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7,
- 6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0,
- 128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16,
- 16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144,
- 136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7,
- 7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0,
- 0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136,
- 136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128,
- 128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5,
- 7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6,
- 0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248,
- 32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136,
- 136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32,
- 5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7,
- 6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0,
- 136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16,
- 32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128,
- 224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6,
- 1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32,
- 80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128,
- 64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6,
- 0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112,
- 128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136,
- 120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6,
- 0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112,
- 136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136,
- 136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3,
- 8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7,
- 6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0,
- 192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168,
- 168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5,
- 6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136,
- 136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8,
- 5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0,
- 0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64,
- 64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5,
- 5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136,
- 136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5,
- 6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0,
- 0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128,
- 64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128,
- 3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2,
- 6,0,2,104,144,0,0,0,6,0,0,0,0,0,6,0,
- 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
- 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
- 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
- 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
- 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
- 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
- 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
- 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
- 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
- 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
- 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
- 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
- 0,1,7,7,6,2,0,128,0,128,128,128,128,128,5,7,
- 7,6,0,0,32,112,168,160,168,112,32,5,7,7,6,0,
- 0,48,64,64,224,64,80,168,5,5,5,6,0,0,136,112,
- 80,112,136,5,7,7,6,0,0,136,80,32,248,32,248,32,
- 1,7,7,6,2,0,128,128,128,0,128,128,128,5,8,8,
- 6,0,0,48,72,32,80,80,32,144,96,3,1,1,6,1,
- 7,160,5,7,7,6,0,0,248,136,184,184,184,136,248,5,
- 7,7,6,0,1,112,8,120,136,120,0,248,5,5,5,6,
- 0,1,40,80,160,80,40,5,3,3,6,0,1,248,8,8,
- 2,2,2,6,2,6,64,128,5,7,7,6,0,0,248,136,
- 168,136,152,168,248,5,1,1,6,0,6,248,4,4,4,6,
- 0,3,96,144,144,96,5,7,7,6,0,0,32,32,248,32,
- 32,0,248,4,5,5,6,0,3,96,144,32,64,240,3,5,
- 5,6,0,3,224,32,224,32,224,2,2,2,6,2,6,64,
- 128,5,8,8,6,0,255,136,136,136,136,152,232,128,128,5,
- 7,7,6,0,0,120,152,152,120,24,24,24,2,2,2,6,
- 2,2,192,192,2,2,2,6,2,255,64,128,3,5,5,6,
- 0,3,64,192,64,64,224,5,7,7,6,0,1,112,136,136,
- 136,112,0,248,5,5,5,6,0,1,160,80,40,80,160,5,
- 7,7,6,0,0,136,144,168,88,184,8,8,5,7,7,6,
- 0,0,136,144,184,72,152,32,56,5,8,8,6,0,0,192,
- 64,192,72,216,56,8,8,5,7,7,6,0,0,32,0,32,
- 64,128,136,112,5,8,8,6,0,0,64,32,0,112,136,248,
- 136,136,5,8,8,6,0,0,16,32,0,112,136,248,136,136,
- 5,8,8,6,0,0,32,80,0,112,136,248,136,136,5,8,
- 8,6,0,0,104,144,0,112,136,248,136,136,5,8,8,6,
- 0,0,80,0,112,136,136,248,136,136,5,8,8,6,0,0,
- 32,80,32,112,136,248,136,136,5,7,7,6,0,0,56,96,
- 160,184,224,160,184,5,8,8,6,0,255,112,136,128,128,136,
- 112,32,96,5,8,8,6,0,0,64,32,0,248,128,240,128,
- 248,5,8,8,6,0,0,8,16,0,248,128,240,128,248,5,
- 8,8,6,0,0,32,80,0,248,128,240,128,248,5,7,7,
- 6,0,0,80,0,248,128,240,128,248,3,8,8,6,1,0,
- 128,64,0,224,64,64,64,224,3,8,8,6,1,0,32,64,
- 0,224,64,64,64,224,3,8,8,6,1,0,64,160,0,224,
- 64,64,64,224,3,7,7,6,1,0,160,0,224,64,64,64,
- 224,5,9,9,6,0,255,80,32,112,136,128,184,136,136,112,
- 5,8,8,6,0,0,104,144,0,136,200,168,152,136,5,8,
- 8,6,0,0,64,32,112,136,136,136,136,112,5,8,8,6,
- 0,0,16,32,112,136,136,136,136,112,5,8,8,6,0,0,
- 32,80,0,112,136,136,136,112,5,8,8,6,0,0,104,144,
- 0,112,136,136,136,112,5,8,8,6,0,0,80,0,112,136,
- 136,136,136,112,5,5,5,6,0,1,136,80,32,80,136,5,
- 8,8,6,0,255,16,112,168,168,168,168,112,64,5,8,8,
- 6,0,0,64,32,136,136,136,136,136,112,5,8,8,6,0,
- 0,16,32,136,136,136,136,136,112,5,8,8,6,0,0,32,
- 80,0,136,136,136,136,112,5,8,8,6,0,0,80,0,136,
- 136,136,136,136,112,1,7,7,6,2,0,128,0,128,128,128,
- 128,128,5,9,9,6,0,255,120,128,128,112,8,8,240,32,
- 96,4,8,8,6,1,255,96,144,144,160,144,144,224,128,5,
- 8,8,6,0,0,64,32,0,112,8,120,136,120,5,8,8,
- 6,0,0,16,32,0,112,8,120,136,120,5,8,8,6,0,
- 0,32,80,0,112,8,120,136,120,5,8,8,6,0,0,104,
- 144,0,112,8,120,136,120,5,7,7,6,0,0,80,0,112,
- 8,120,136,120,5,8,8,6,0,0,32,80,32,112,8,120,
- 136,120,5,6,6,6,0,0,208,40,120,160,168,80,5,7,
- 7,6,0,255,112,128,128,136,112,32,96,5,8,8,6,0,
- 0,64,32,0,112,136,248,128,112,5,8,8,6,0,0,16,
- 32,0,112,136,248,128,112,5,8,8,6,0,0,32,80,0,
- 112,136,248,128,112,5,7,7,6,0,0,80,0,112,136,248,
- 128,112,3,8,8,6,1,0,128,64,0,64,192,64,64,224,
- 3,8,8,6,1,0,32,64,0,64,192,64,64,224,3,8,
- 8,6,1,0,64,160,0,64,192,64,64,224,3,7,7,6,
- 1,0,160,0,64,192,64,64,224,5,8,8,6,0,255,80,
- 32,112,136,136,120,8,112,5,8,8,6,0,0,104,144,0,
- 176,200,136,136,136,5,8,8,6,0,0,64,32,0,112,136,
- 136,136,112,5,8,8,6,0,0,16,32,0,112,136,136,136,
- 112,5,8,8,6,0,0,32,80,0,112,136,136,136,112,5,
- 8,8,6,0,0,104,144,0,112,136,136,136,112,5,7,7,
- 6,0,0,80,0,112,136,136,136,112,5,5,5,6,0,1,
- 32,0,248,0,32,5,7,7,6,0,255,16,112,168,168,168,
- 112,64,5,8,8,6,0,0,64,32,0,136,136,136,152,104,
- 5,8,8,6,0,0,16,32,0,136,136,136,152,104,5,8,
- 8,6,0,0,32,80,0,136,136,136,152,104,5,7,7,6,
- 0,0,80,0,136,136,136,152,104,1,5,5,6,2,0,128,
- 128,128,128,128,5,7,7,6,0,255,112,128,112,8,240,32,
- 96,5,8,8,6,0,255,80,0,136,136,136,120,8,112};
diff --git a/Marlin/dogm_font_data_ISO10646_5_Cyrillic.h b/Marlin/dogm_font_data_ISO10646_5_Cyrillic.h
deleted file mode 100644
index 75e779fd0f..0000000000
--- a/Marlin/dogm_font_data_ISO10646_5_Cyrillic.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-/**
- Fontname: ISO10646_5_Cyrillic
- Copyright: A. Hardtung, public domain
- Capital A Height: 7, '1' Height: 7
- Calculated Max Values w= 5 h= 9 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 9
- Font Bounding box w= 6 h= 9 x= 0 y=-2
- Calculated Min Values x= 0 y=-1 dx= 0 dy= 0
- Pure Font ascent = 7 descent=-1
- X Font ascent = 7 descent=-1
- Max Font ascent = 8 descent=-1
-*/
-#include
-const u8g_fntpgm_uint8_t ISO10646_5_Cyrillic_5x7[2560] U8G_SECTION(".progmem.ISO10646_5_Cyrillic_5x7") = {
- 0, 6, 9, 0, 254, 7, 1, 145, 3, 32, 32, 255, 255, 8, 255, 7,
- 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128,
- 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6,
- 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32,
- 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32,
- 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104,
- 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32,
- 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32,
- 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5,
- 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192,
- 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192,
- 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6,
- 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64,
- 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112,
- 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240,
- 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7,
- 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0,
- 48, 64, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16,
- 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136,
- 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5,
- 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192,
- 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64,
- 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1,
- 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136,
- 8, 16, 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168,
- 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7,
- 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0,
- 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144,
- 136, 136, 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128,
- 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5,
- 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6,
- 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128,
- 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16,
- 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136,
- 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7,
- 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0,
- 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136,
- 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128,
- 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7,
- 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0,
- 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32,
- 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136,
- 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5,
- 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6,
- 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136,
- 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32,
- 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224,
- 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, 1,
- 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, 80,
- 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, 64,
- 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0,
- 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, 128,
- 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, 120,
- 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, 0,
- 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, 136,
- 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, 136,
- 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, 8,
- 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, 6,
- 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, 192,
- 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, 168,
- 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, 6,
- 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, 136,
- 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, 5,
- 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, 0,
- 112, 128, 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, 64, 64,
- 72, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, 5,
- 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, 136,
- 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, 6,
- 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, 0,
- 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, 64,
- 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, 3,
- 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2, 6,
- 0, 3, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
- 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
- 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
- 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
- 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 5, 8, 8, 6, 0, 0,
- 64, 248, 128, 128, 240, 128, 128, 248, 5, 8, 8, 6, 0, 0, 80, 248,
- 128, 128, 240, 128, 128, 248, 5, 7, 7, 6, 0, 0, 224, 64, 64, 112,
- 72, 72, 112, 5, 8, 8, 6, 0, 0, 16, 32, 248, 136, 128, 128, 128,
- 128, 5, 7, 7, 6, 0, 0, 48, 72, 128, 224, 128, 72, 48, 5, 7,
- 7, 6, 0, 0, 112, 136, 128, 112, 8, 136, 112, 3, 7, 7, 6, 1,
- 0, 224, 64, 64, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 160, 0,
- 224, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16,
- 16, 144, 96, 5, 7, 7, 6, 0, 0, 160, 160, 160, 184, 168, 168, 184,
- 5, 7, 7, 6, 0, 0, 160, 160, 160, 248, 168, 168, 184, 4, 7, 7,
- 6, 0, 0, 224, 64, 112, 80, 80, 80, 80, 5, 8, 8, 6, 0, 0,
- 16, 32, 136, 144, 160, 224, 144, 136, 5, 8, 8, 6, 0, 0, 64, 32,
- 136, 152, 168, 200, 136, 136, 5, 9, 9, 6, 0, 255, 80, 32, 136, 136,
- 136, 80, 32, 32, 32, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 136,
- 136, 248, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136,
- 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 136, 136, 240, 5, 7, 7,
- 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, 0,
- 248, 136, 128, 128, 128, 128, 128, 5, 8, 8, 6, 0, 255, 120, 40, 40,
- 40, 72, 136, 248, 136, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128,
- 128, 248, 5, 7, 7, 6, 0, 0, 168, 168, 168, 112, 168, 168, 168, 5,
- 7, 7, 6, 0, 0, 240, 8, 8, 112, 8, 8, 240, 5, 7, 7, 6,
- 0, 0, 136, 136, 152, 168, 200, 136, 136, 5, 8, 8, 6, 0, 0, 80,
- 32, 136, 152, 168, 168, 200, 136, 5, 7, 7, 6, 0, 0, 136, 144, 160,
- 192, 160, 144, 136, 5, 7, 7, 6, 0, 0, 120, 40, 40, 40, 40, 168,
- 72, 5, 7, 7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7,
- 7, 6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 5, 7, 7, 6, 0,
- 0, 112, 136, 136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 136,
- 136, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128,
- 128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 128, 128, 128, 136, 112, 5,
- 7, 7, 6, 0, 0, 248, 32, 32, 32, 32, 32, 32, 5, 7, 7, 6,
- 0, 0, 136, 136, 136, 80, 32, 64, 128, 5, 7, 7, 6, 0, 0, 32,
- 112, 168, 168, 168, 112, 32, 5, 7, 7, 6, 0, 0, 136, 136, 80, 32,
- 80, 136, 136, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 136, 136, 248,
- 8, 5, 7, 7, 6, 0, 0, 136, 136, 136, 152, 104, 8, 8, 5, 7,
- 7, 6, 0, 0, 168, 168, 168, 168, 168, 168, 248, 5, 8, 8, 6, 0,
- 255, 168, 168, 168, 168, 168, 168, 248, 8, 5, 7, 7, 6, 0, 0, 192,
- 64, 64, 112, 72, 72, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 200,
- 168, 168, 200, 5, 7, 7, 6, 0, 0, 128, 128, 128, 240, 136, 136, 240,
- 5, 7, 7, 6, 0, 0, 112, 136, 8, 56, 8, 136, 112, 5, 7, 7,
- 6, 0, 0, 144, 168, 168, 232, 168, 168, 144, 5, 7, 7, 6, 0, 0,
- 120, 136, 136, 120, 40, 72, 136, 5, 5, 5, 6, 0, 0, 112, 8, 120,
- 136, 120, 5, 7, 7, 6, 0, 0, 24, 96, 128, 240, 136, 136, 112, 4,
- 5, 5, 6, 0, 0, 224, 144, 224, 144, 224, 5, 5, 5, 6, 0, 0,
- 248, 136, 128, 128, 128, 5, 6, 6, 6, 0, 255, 120, 40, 72, 136, 248,
- 136, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 5, 5, 6,
- 0, 0, 168, 168, 112, 168, 168, 5, 5, 5, 6, 0, 0, 240, 8, 48,
- 8, 240, 5, 5, 5, 6, 0, 0, 136, 152, 168, 200, 136, 5, 7, 7,
- 6, 0, 0, 80, 32, 136, 152, 168, 200, 136, 4, 5, 5, 6, 0, 0,
- 144, 160, 192, 160, 144, 5, 5, 5, 6, 0, 0, 248, 40, 40, 168, 72,
- 5, 5, 5, 6, 0, 0, 136, 216, 168, 136, 136, 5, 5, 5, 6, 0,
- 0, 136, 136, 248, 136, 136, 5, 5, 5, 6, 0, 0, 112, 136, 136, 136,
- 112, 5, 5, 5, 6, 0, 0, 248, 136, 136, 136, 136, 5, 6, 6, 6,
- 0, 255, 240, 136, 136, 240, 128, 128, 5, 5, 5, 6, 0, 0, 112, 128,
- 128, 136, 112, 5, 5, 5, 6, 0, 0, 248, 32, 32, 32, 32, 5, 6,
- 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 6, 6, 6, 0, 0,
- 32, 112, 168, 168, 112, 32, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80,
- 136, 5, 6, 6, 6, 0, 255, 136, 136, 136, 136, 248, 8, 5, 5, 5,
- 6, 0, 0, 136, 136, 248, 8, 8, 5, 5, 5, 6, 0, 0, 168, 168,
- 168, 168, 248, 5, 6, 6, 6, 0, 255, 168, 168, 168, 168, 248, 8, 5,
- 5, 5, 6, 0, 0, 192, 64, 112, 72, 112, 5, 5, 5, 6, 0, 0,
- 136, 136, 200, 168, 200, 3, 5, 5, 6, 1, 0, 128, 128, 192, 160, 192,
- 5, 5, 5, 6, 0, 0, 112, 136, 56, 136, 112, 5, 5, 5, 6, 0,
- 0, 144, 168, 232, 168, 144, 5, 5, 5, 6, 0, 0, 120, 136, 120, 40,
- 72, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248, 128, 112, 5,
- 7, 7, 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, 5, 9, 9, 6,
- 0, 255, 64, 224, 64, 64, 120, 72, 72, 72, 16, 5, 8, 8, 6, 0,
- 0, 16, 32, 0, 248, 136, 128, 128, 128, 5, 5, 5, 6, 0, 0, 112,
- 136, 96, 136, 112, 5, 5, 5, 6, 0, 0, 112, 128, 112, 8, 240, 1,
- 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, 7, 7, 6,
- 1, 0, 160, 0, 64, 64, 64, 64, 64, 3, 8, 8, 6, 1, 255, 32,
- 0, 32, 32, 32, 32, 160, 64, 5, 5, 5, 6, 0, 0, 160, 160, 184,
- 168, 184, 5, 5, 5, 6, 0, 0, 160, 160, 248, 168, 184, 5, 6, 6,
- 6, 0, 0, 64, 224, 64, 120, 72, 72, 4, 8, 8, 6, 0, 0, 16,
- 32, 0, 144, 160, 192, 160, 144, 5, 8, 8, 6, 0, 0, 64, 32, 0,
- 136, 152, 168, 200, 136, 5, 9, 9, 6, 0, 255, 80, 32, 0, 136, 136,
- 136, 120, 8, 112, 5, 6, 6, 6, 0, 255, 136, 136, 136, 136, 248, 32
-};
diff --git a/Marlin/dogm_font_data_ISO10646_CN.h b/Marlin/dogm_font_data_ISO10646_CN.h
deleted file mode 100644
index 11fdb2240b..0000000000
--- a/Marlin/dogm_font_data_ISO10646_CN.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see