Compare commits

...

4 commits

Author SHA1 Message Date
erril007
533d752707
EVENT_GCODE_(BEFORE|AFTER)_G34 (#27930)
Some checks failed
CI - Build Tests / Build Test (STM32F103VE_longer_maple) (push) Has been cancelled
CI - Build Tests / Build Test (STM32F401RC_creality) (push) Has been cancelled
CI - Build Tests / Build Test (STM32F407VE_black) (push) Has been cancelled
CI - Build Tests / Build Test (STM32F446VE_fysetc) (push) Has been cancelled
CI - Build Tests / Build Test (STM32G0B1RE_btt) (push) Has been cancelled
CI - Build Tests / Build Test (STM32H743VI_btt) (push) Has been cancelled
CI - Build Tests / Build Test (at90usb1286_dfu) (push) Has been cancelled
CI - Build Tests / Build Test (chitu_f103) (push) Has been cancelled
CI - Build Tests / Build Test (esp32) (push) Has been cancelled
CI - Build Tests / Build Test (jgaurora_a5s_a1_maple) (push) Has been cancelled
CI - Build Tests / Build Test (linux_native) (push) Has been cancelled
CI - Build Tests / Build Test (malyan_M300) (push) Has been cancelled
CI - Build Tests / Build Test (mega1280) (push) Has been cancelled
CI - Build Tests / Build Test (mega2560) (push) Has been cancelled
CI - Build Tests / Build Test (melzi_optiboot) (push) Has been cancelled
CI - Build Tests / Build Test (mks_robin) (push) Has been cancelled
CI - Build Tests / Build Test (mks_robin_lite_maple) (push) Has been cancelled
CI - Build Tests / Build Test (mks_robin_nano_v1v2) (push) Has been cancelled
CI - Build Tests / Build Test (mks_robin_pro2) (push) Has been cancelled
CI - Build Tests / Build Test (mks_robin_pro_maple) (push) Has been cancelled
CI - Build Tests / Build Test (mks_tinybee) (push) Has been cancelled
CI - Build Tests / Build Test (rambo) (push) Has been cancelled
CI - Build Tests / Build Test (rumba32) (push) Has been cancelled
CI - Build Tests / Build Test (sanguino1284p) (push) Has been cancelled
CI - Build Tests / Build Test (sanguino644p) (push) Has been cancelled
CI - Build Tests / Build Test (simulator_linux_release) (push) Has been cancelled
CI - Build Tests / Build Test (teensy31) (push) Has been cancelled
CI - Build Tests / Build Test (teensy35) (push) Has been cancelled
CI - Build Tests / Build Test (teensy41) (push) Has been cancelled
CI - Unit Tests / Unit Test (push) Has been cancelled
2025-06-20 20:50:13 -05:00
thinkyhead
037b0096e2 [cron] Bump distribution date (2025-06-21) 2025-06-21 00:32:24 +00:00
ellensp
eefd63e408
🐛 Fix Hotend > 0 Preheat (#27932) 2025-06-20 16:18:40 -05:00
Scott Lahteine
5e410e35ab 🩹 Minor fixes, updates, comments 2025-06-20 16:05:06 -05:00
14 changed files with 152 additions and 113 deletions

View file

@ -1081,11 +1081,26 @@
#define G34_MAX_GRADE 5 // (%) Maximum incline that G34 will handle
#define Z_STEPPER_ALIGN_ITERATIONS 5 // Number of iterations to apply during alignment
#define Z_STEPPER_ALIGN_ACC 0.02 // Stop iterating early if the accuracy is better than this
#define RESTORE_LEVELING_AFTER_G34 // Restore leveling after G34 is done?
// After G34, re-home Z (G28 Z) or just calculate it from the last probe heights?
// Re-homing might be more precise in reproducing the actual 'G28 Z' homing height, especially on an uneven bed.
#define HOME_AFTER_G34
#endif
/**
* Commands to execute at the start of G34 probing,
* after switching to the PROBING_TOOL.
*/
//#define EVENT_GCODE_BEFORE_G34 "M300 P440 S200"
/**
* Commands to execute at the end of G34 probing.
* Useful to retract or move the Z probe out of the way.
*/
//#define EVENT_GCODE_AFTER_G34 "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10"
#endif // Z_STEPPER_AUTO_ALIGN
/**
* Assisted Tramming

View file

@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
//#define STRING_DISTRIBUTION_DATE "2025-06-17"
//#define STRING_DISTRIBUTION_DATE "2025-06-21"
/**
* The protocol for communication to the host. Protocol indicates communication

View file

@ -152,8 +152,8 @@
#include "feature/encoder_i2c.h"
#endif
#if (HAS_TRINAMIC_CONFIG || HAS_TMC_SPI) && DISABLED(PSU_DEFAULT_OFF)
#include "feature/tmc_util.h"
#if HAS_TRINAMIC_CONFIG
#include "module/stepper/trinamic.h"
#endif
#if HAS_CUTTER

View file

@ -24,6 +24,12 @@
#if HAS_TRINAMIC_CONFIG
/**
* feature/tmc_util.cpp - Functions for debugging Trinamic stepper drivers.
* The main entry point is `tmc_report_all` which is called by M122 to collect
* and report diagnostic information about each enabled TMC driver.
*/
#include "tmc_util.h"
#include "../MarlinCore.h"
@ -710,14 +716,8 @@
case TMC_FSACTIVE: if (st.fsactive()) SERIAL_CHAR('*'); break;
case TMC_DRV_CS_ACTUAL: if (st.CS_ACTUAL()) SERIAL_CHAR('*'); break;
case TMC_STALLGUARD: if (st.stallguard()) SERIAL_CHAR('*'); break;
//case TMC_OT: if (st.ot()) SERIAL_CHAR('*'); break;
case TMC_DEBUG_OTPW: print_true_or_false(st.otpw()); break;
//case TMC_S2GA: if (st.s2ga()) SERIAL_CHAR('*'); break;
//case TMC_S2GB: if (st.s2gb()) SERIAL_CHAR('*'); break;
//case TMC_OLA: if (st.ola()) SERIAL_CHAR('*'); break;
//case TMC_OLB: if (st.olb()) SERIAL_CHAR('*'); break;
case TMC_OT: if (st.ot()) SERIAL_CHAR('*'); break;
case TMC_SG_RESULT: SERIAL_ECHO(st.SG_RESULT()); break;
case TMC_STST: if (!st.stst()) SERIAL_CHAR('*'); break;
default: break; // other...
}
}
@ -844,7 +844,8 @@
case TMC_OT: if (st.ot()) SERIAL_CHAR('*'); break;
case TMC_DRV_STATUS_HEX: {
const uint32_t drv_status = st.DRV_STATUS();
SERIAL_CHAR('\t'); st.printLabel(); SERIAL_CHAR('\t'); print_hex_long(drv_status, ':', true);
SERIAL_CHAR('\t'); st.printLabel();
SERIAL_CHAR('\t'); print_hex_long(drv_status, ':', true);
if (drv_status == 0xFFFFFFFF || drv_status == 0) SERIAL_ECHOPGM("\t Bad response!");
SERIAL_EOL();
} break;
@ -1167,6 +1168,9 @@
bool tmc_enable_stallguard(TMC2240Stepper &st) {
const bool stealthchop_was_enabled = st.en_pwm_mode();
// TODO: Use StallGuard4 when stealthChop is enabled
// and leave stealthChop state unchanged.
st.TCOOLTHRS(0xFFFFF);
st.en_pwm_mode(false);
st.diag0_stall(true);
@ -1250,75 +1254,3 @@ void test_tmc_connection(LOGICAL_AXIS_ARGS_LC(const bool)) {
}
#endif // HAS_TRINAMIC_CONFIG
#if HAS_TMC_SPI
#define SET_CS_PIN(st) OUT_WRITE(st##_CS_PIN, HIGH)
void tmc_init_cs_pins() {
#if AXIS_HAS_SPI(X)
SET_CS_PIN(X);
#endif
#if AXIS_HAS_SPI(Y)
SET_CS_PIN(Y);
#endif
#if AXIS_HAS_SPI(Z)
SET_CS_PIN(Z);
#endif
#if AXIS_HAS_SPI(X2)
SET_CS_PIN(X2);
#endif
#if AXIS_HAS_SPI(Y2)
SET_CS_PIN(Y2);
#endif
#if AXIS_HAS_SPI(Z2)
SET_CS_PIN(Z2);
#endif
#if AXIS_HAS_SPI(Z3)
SET_CS_PIN(Z3);
#endif
#if AXIS_HAS_SPI(Z4)
SET_CS_PIN(Z4);
#endif
#if AXIS_HAS_SPI(I)
SET_CS_PIN(I);
#endif
#if AXIS_HAS_SPI(J)
SET_CS_PIN(J);
#endif
#if AXIS_HAS_SPI(K)
SET_CS_PIN(K);
#endif
#if AXIS_HAS_SPI(U)
SET_CS_PIN(U);
#endif
#if AXIS_HAS_SPI(V)
SET_CS_PIN(V);
#endif
#if AXIS_HAS_SPI(W)
SET_CS_PIN(W);
#endif
#if AXIS_HAS_SPI(E0)
SET_CS_PIN(E0);
#endif
#if AXIS_HAS_SPI(E1)
SET_CS_PIN(E1);
#endif
#if AXIS_HAS_SPI(E2)
SET_CS_PIN(E2);
#endif
#if AXIS_HAS_SPI(E3)
SET_CS_PIN(E3);
#endif
#if AXIS_HAS_SPI(E4)
SET_CS_PIN(E4);
#endif
#if AXIS_HAS_SPI(E5)
SET_CS_PIN(E5);
#endif
#if AXIS_HAS_SPI(E6)
SET_CS_PIN(E6);
#endif
#if AXIS_HAS_SPI(E7)
SET_CS_PIN(E7);
#endif
}
#endif // HAS_TMC_SPI

View file

@ -474,7 +474,3 @@ void test_tmc_connection(LOGICAL_AXIS_DECL_LC(const bool, true));
#endif // HAS_HOMING_CURRENT
#endif // HAS_TRINAMIC_CONFIG
#if HAS_TMC_SPI
void tmc_init_cs_pins();
#endif

View file

@ -143,6 +143,11 @@ void GcodeSuite::G34() {
probe.use_probing_tool();
#ifdef EVENT_GCODE_BEFORE_G34
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Before G34 G-code: ", F(EVENT_GCODE_BEFORE_G34));
gcode.process_subcommands_now(F(EVENT_GCODE_BEFORE_G34));
#endif
TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false));
// Compute a worst-case clearance height to probe from. After the first
@ -214,19 +219,20 @@ void GcodeSuite::G34() {
// Probing sanity check is disabled, as it would trigger even in normal cases because
// current_position.z has been manually altered in the "dirty trick" above.
if (DEBUGGING(LEVELING))
DEBUG_ECHOLNPGM(
"Z_PROBE_LOW_POINT: ", p_float_t(Z_PROBE_LOW_POINT, 2),
"z_probe: ", p_float_t(z_probe, 2),
"Probe Tgt: ", p_float_t((Z_PROBE_LOW_POINT) - z_probe * 0.5f, 2)
);
const float minz = (Z_PROBE_LOW_POINT) - (z_probe * 0.5f);
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOPGM("Z_PROBE_LOW_POINT: " STRINGIFY(Z_PROBE_LOW_POINT));
DEBUG_ECHOLNPGM(" z_probe: ", p_float_t(z_probe, 3),
" Probe Tgt: ", p_float_t(minz, 3));
}
const float z_probed_height = probe.probe_at_point(
DIFF_TERN(HAS_HOME_OFFSET, ppos, xy_pos_t(home_offset)), // xy
raise_after, // raise_after
(DEBUGGING(LEVELING) || DEBUGGING(INFO)) ? 3 : 0, // verbose_level
true, false, // probe_relative, sanity_check
(Z_PROBE_LOW_POINT) - (z_probe * 0.5f), // z_min_point
minz, // z_min_point
Z_TWEEN_SAFE_CLEARANCE // z_clearance
);
@ -303,7 +309,7 @@ void GcodeSuite::G34() {
SERIAL_EOL();
SString<15 + TERN0(TRIPLE_Z, 30) + TERN0(QUAD_Z, 45)> msg(F("1:2="), p_float_t(ABS(z_measured[1] - z_measured[0]), 3));
SString<15 + TERN0(TRIPLE_Z, 30) + TERN0(QUAD_Z, 45)> msg(F("2-1="), p_float_t(ABS(z_measured[1] - z_measured[0]), 3));
#if TRIPLE_Z
msg.append(F(" 3-2="), p_float_t(ABS(z_measured[2] - z_measured[1]), 3))
.append(F(" 3-1="), p_float_t(ABS(z_measured[2] - z_measured[0]), 3));
@ -414,7 +420,7 @@ void GcodeSuite::G34() {
SERIAL_ECHOLNPGM("G34 aborted.");
else {
SERIAL_ECHOLNPGM("Did ", iteration + (iteration != z_auto_align_iterations), " of ", z_auto_align_iterations);
SERIAL_ECHOLNPGM("Accuracy: ", p_float_t(z_maxdiff, 2));
SERIAL_ECHOLNPGM("Accuracy: ", p_float_t(z_maxdiff, 3));
}
// Stow the probe because the last call to probe.probe_at_point(...)
@ -430,9 +436,9 @@ void GcodeSuite::G34() {
// Ideally, this would be equal to the 'z_probe * 0.5f' which was added earlier.
if (DEBUGGING(LEVELING))
DEBUG_ECHOLNPGM(
"z_measured_min: ", p_float_t(z_measured_min, 2),
"Z_TWEEN_SAFE_CLEARANCE: ", p_float_t(Z_TWEEN_SAFE_CLEARANCE, 2),
"zoffs: ", p_float_t(zoffs, 2)
"z_measured_min: ", p_float_t(z_measured_min, 3),
"Z_TWEEN_SAFE_CLEARANCE: ", p_float_t(Z_TWEEN_SAFE_CLEARANCE, 3),
"zoffs: ", p_float_t(zoffs, 3)
);
if (!err_break)
@ -440,6 +446,12 @@ void GcodeSuite::G34() {
sync_plan_position();
#endif
#ifdef EVENT_GCODE_AFTER_G34
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("After G34 G-code: ", F(EVENT_GCODE_AFTER_G34));
planner.synchronize();
process_subcommands_now(F(EVENT_GCODE_AFTER_G34));
#endif
probe.use_probing_tool(false);
#if ALL(HAS_LEVELING, RESTORE_LEVELING_AFTER_G34)

View file

@ -36,8 +36,9 @@
*
* With TMC_DEBUG:
* V - Report raw register data. Refer to the datasheet to decipher the report.
* S - Flag to enable/disable continuous debug reporting.
* P<ms> - Interval between continuous debug reports, in milliseconds.
* S0 - Disable continuous debug reporting.
* S1 - Enable continuous debug reporting with the default interval.
* P<ms> - Enable continuous debug reporting with the given interval in ms.
*/
void GcodeSuite::M122() {
xyze_bool_t print_axis = ARRAY_N_1(LOGICAL_AXES, false);
@ -51,12 +52,12 @@ void GcodeSuite::M122() {
#if ENABLED(TMC_DEBUG)
#if ENABLED(MONITOR_DRIVER_STATUS)
const bool sflag = parser.seen_test('S'), sval = sflag && parser.value_bool();
if (sflag && !sval)
const bool sflag = parser.seen('S'), sval = sflag && parser.value_bool();
if (sflag && !sval) // "S0"
tmc_set_report_interval(0);
else if (parser.seenval('P'))
else if (parser.seenval('P')) // "P<ms>"
tmc_set_report_interval(_MAX(uint16_t(250), parser.value_ushort()));
else if (sval)
else if (sval) // "S" or "S1"
tmc_set_report_interval(MONITOR_DRIVER_STATUS_INTERVAL_MS);
#endif

View file

@ -42,7 +42,7 @@
* version was tagged.
*/
#ifndef STRING_DISTRIBUTION_DATE
#define STRING_DISTRIBUTION_DATE "2025-06-17"
#define STRING_DISTRIBUTION_DATE "2025-06-21"
#endif
/**

View file

@ -656,7 +656,7 @@ public:
static FSTR_P get_preheat_label(const uint8_t m);
static void apply_preheat(const uint8_t m, const uint8_t pmask, const uint8_t e=active_extruder);
static void preheat_set_fan(const uint8_t m) { TERN_(HAS_FAN, apply_preheat(m, _BV(PT_FAN))); }
static void preheat_hotend(const uint8_t m, const uint8_t e=active_extruder) { TERN_(HAS_HOTEND, apply_preheat(m, _BV(PT_HOTEND))); }
static void preheat_hotend(const uint8_t m, const uint8_t e=active_extruder) { TERN_(HAS_HOTEND, apply_preheat(m, _BV(PT_HOTEND), e)); }
static void preheat_hotend_and_fan(const uint8_t m, const uint8_t e=active_extruder) { preheat_hotend(m, e); preheat_set_fan(m); }
static void preheat_bed(const uint8_t m) { TERN_(HAS_HEATED_BED, apply_preheat(m, _BV(PT_BED))); }
static void preheat_chamber(const uint8_t m) { TERN_(HAS_HEATED_CHAMBER, apply_preheat(m, _BV(PT_CHAMBER))); }

View file

@ -154,6 +154,82 @@ enum StealthIndex : uint8_t {
TMC_SPI_DEFINE_E(7);
#endif
#if HAS_TMC_SPI
// Init CS pins (active-low) for TMC SPI drivers.
#define INIT_CS_PIN(st) OUT_WRITE(st##_CS_PIN, HIGH)
void tmc_init_cs_pins() {
#if AXIS_HAS_SPI(X)
INIT_CS_PIN(X);
#endif
#if AXIS_HAS_SPI(Y)
INIT_CS_PIN(Y);
#endif
#if AXIS_HAS_SPI(Z)
INIT_CS_PIN(Z);
#endif
#if AXIS_HAS_SPI(X2)
INIT_CS_PIN(X2);
#endif
#if AXIS_HAS_SPI(Y2)
INIT_CS_PIN(Y2);
#endif
#if AXIS_HAS_SPI(Z2)
INIT_CS_PIN(Z2);
#endif
#if AXIS_HAS_SPI(Z3)
INIT_CS_PIN(Z3);
#endif
#if AXIS_HAS_SPI(Z4)
INIT_CS_PIN(Z4);
#endif
#if AXIS_HAS_SPI(I)
INIT_CS_PIN(I);
#endif
#if AXIS_HAS_SPI(J)
INIT_CS_PIN(J);
#endif
#if AXIS_HAS_SPI(K)
INIT_CS_PIN(K);
#endif
#if AXIS_HAS_SPI(U)
INIT_CS_PIN(U);
#endif
#if AXIS_HAS_SPI(V)
INIT_CS_PIN(V);
#endif
#if AXIS_HAS_SPI(W)
INIT_CS_PIN(W);
#endif
#if AXIS_HAS_SPI(E0)
INIT_CS_PIN(E0);
#endif
#if AXIS_HAS_SPI(E1)
INIT_CS_PIN(E1);
#endif
#if AXIS_HAS_SPI(E2)
INIT_CS_PIN(E2);
#endif
#if AXIS_HAS_SPI(E3)
INIT_CS_PIN(E3);
#endif
#if AXIS_HAS_SPI(E4)
INIT_CS_PIN(E4);
#endif
#if AXIS_HAS_SPI(E5)
INIT_CS_PIN(E5);
#endif
#if AXIS_HAS_SPI(E6)
INIT_CS_PIN(E6);
#endif
#if AXIS_HAS_SPI(E7)
INIT_CS_PIN(E7);
#endif
}
#endif // HAS_TMC_SPI
#ifndef TMC_BAUD_RATE
// Reduce baud rate for boards not already overriding TMC_BAUD_RATE for software serial.
// Testing has shown that 115200 is not 100% reliable on AVR platforms, occasionally
@ -313,6 +389,7 @@ enum StealthIndex : uint8_t {
// TMC2208/2209 Driver objects and inits
//
#if HAS_TMC_UART
#if AXIS_HAS_UART(X)
#ifdef X_HARDWARE_SERIAL
TMC_UART_DEFINE(HW, X, X);
@ -685,7 +762,8 @@ enum StealthIndex : uint8_t {
#endif
#endif
}
#endif
#endif // HAS_TMC_UART
#if HAS_DRIVER(TMC2208)
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>

View file

@ -109,6 +109,10 @@
#define CHOPPER_TIMING_E CHOPPER_TIMING
#endif
#if HAS_TMC_SPI
void tmc_init_cs_pins();
#endif
#if HAS_TMC_UART
void tmc_serial_begin();
#endif

View file

@ -83,7 +83,8 @@ opt_set MOTHERBOARD BOARD_BTT_SKR_V1_4_TURBO SERIAL_PORT -1 \
Z_MIN_ENDSTOP_HIT_STATE HIGH
opt_enable PIDTEMPBED \
FILAMENT_RUNOUT_SENSOR NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE \
BLTOUCH BLTOUCH_FORCE_SW_MODE USE_PROBE_FOR_Z_HOMING Z_SAFE_HOMING QUICK_HOME Z_STEPPER_AUTO_ALIGN \
BLTOUCH BLTOUCH_FORCE_SW_MODE USE_PROBE_FOR_Z_HOMING Z_SAFE_HOMING QUICK_HOME \
Z_STEPPER_AUTO_ALIGN EVENT_GCODE_BEFORE_G34 EVENT_GCODE_AFTER_G34 \
AUTO_BED_LEVELING_BILINEAR EXTRAPOLATE_BEYOND_GRID RESTORE_LEVELING_AFTER_G28 LCD_BED_LEVELING MESH_EDIT_MENU \
EEPROM_SETTINGS EEPROM_AUTO_INIT \
SDSUPPORT CR10_STOCKDISPLAY SPEAKER LCD_INFO_MENU STATUS_MESSAGE_SCROLLING \

View file

@ -20,7 +20,7 @@ MARLIN_TEST_BUILD = build_src_filter=+<src/tests>
POSTMORTEM_DEBUGGING = build_src_filter=+<src/HAL/shared/cpu_exception> +<src/HAL/shared/backtrace>
build_flags=-funwind-tables
MKS_WIFI_MODULE = QRCode=https://github.com/makerbase-mks/QRCode/archive/261c5a696a.zip
HAS_TRINAMIC_CONFIG = TMCStepper=https://github.com/MarlinFirmware/TMCStepper/archive/v0.8.7.zip
HAS_TRINAMIC_CONFIG = TMCStepper=https://github.com/MarlinFirmware/TMCStepper/archive/v0.8.8.zip
build_src_filter=+<src/module/stepper/trinamic.cpp> +<src/gcode/feature/trinamic/M122.cpp> +<src/gcode/feature/trinamic/M906.cpp> +<src/gcode/feature/trinamic/M911-M914.cpp> +<src/gcode/feature/trinamic/M919.cpp>
HAS_STEPPER_CONTROL = build_src_filter=+<src/module/stepper/control.cpp>
HAS_T(RINAMIC_CONFIG|MC_SPI) = build_src_filter=+<src/feature/tmc_util.cpp>

View file

@ -320,7 +320,7 @@ build_unflags = ${env:STM32F407VG_btt.build_unflags} -DUSBD_USE_CDC
[env:STM32F407VG_btt_USB_debug]
extends = env:STM32F407VG_btt_USB
build_flags = ${env:STM32F407VG_btt_USB.build_flags} -O0
build_unflags = ${env:STM32F407VG_btt_USB.build_unflags} -Os -NDEBUG
build_unflags = ${env:STM32F407VG_btt_USB.build_unflags} -Os -DNDEBUG
#
# Bigtreetech SKR V2.0 (STM32F429VGT6 ARM Cortex-M4) with USB Flash Drive Support
@ -340,7 +340,7 @@ build_unflags = ${env:STM32F429VG_btt.build_unflags} -DUSBD_USE_CDC
[env:STM32F429VG_btt_USB_debug]
extends = env:STM32F429VG_btt_USB
build_flags = ${env:STM32F429VG_btt_USB.build_flags} -O0
build_unflags = ${env:STM32F429VG_btt_USB.build_unflags} -Os -NDEBUG
build_unflags = ${env:STM32F429VG_btt_USB.build_unflags} -Os -DNDEBUG
#
# BigTreeTech Octopus V1.0/1.1 / Octopus Pro V1.0 (STM32F446ZET6 ARM Cortex-M4)