diff --git a/firmware/controller/src/constants.h b/firmware/controller/src/constants.h index 771ba06e0..d6b8a5b26 100644 --- a/firmware/controller/src/constants.h +++ b/firmware/controller/src/constants.h @@ -12,8 +12,11 @@ // Version 1.2 = CMD_EXECUTION_ERROR reported on failed moves + MOVETO_W2 command // Version 1.3 = strobe ISR latches illumination source at start (race fix when // channel switched during live HW-triggered acquisition) +// Version 1.4 = filter-wheel (W/W2) home resets xmin/xmax to full range (rotary +// axis has no travel end-stop); fixes intermittent post-home +// MOVETO_W CMD_EXECUTION_ERROR (home left xmin = L - C > offset) #define FIRMWARE_VERSION_MAJOR 1 -#define FIRMWARE_VERSION_MINOR 3 +#define FIRMWARE_VERSION_MINOR 4 #include "def/def_v1.h" diff --git a/firmware/controller/src/operations.cpp b/firmware/controller/src/operations.cpp index fdf3f611a..28785d860 100644 --- a/firmware/controller/src/operations.cpp +++ b/firmware/controller/src/operations.cpp @@ -375,6 +375,17 @@ void finalize_homing_w() tmc4361A_write_encoder(&tmc4361[w], 0); if (stage_PID_enabled[w]) tmc4361A_set_PID(&tmc4361[w], PID_BPG0); + // The filter wheel is ROTARY (no travel end-stop) -- the linear-stage + // [xmin,xmax] range gate in tmc4361A_moveTo does not apply to it. Homing + // leaves xmin = L - C (L = press-latch position, C = release-detect + // position); a stale/mis-ordered latch makes xmin exceed the small absolute + // post-home offset target, so MOVETO_W is wrongly rejected with + // CMD_EXECUTION_ERROR. Reset to full range so valid rotary moves are never + // range-rejected. Safe: W xmin/xmax are written only in check_homing_w and + // consumed only by the moveTo range check (check_limits acts on X/Y/Z only, + // stopping them on a limit-switch event, and never touches W/W2). + tmc4361[w].xmin = INT32_MIN; + tmc4361[w].xmax = INT32_MAX; } W_pos = 0; is_homing_W = false; @@ -393,6 +404,9 @@ void finalize_homing_w2() tmc4361A_write_encoder(&tmc4361[w2], 0); if (stage_PID_enabled[w2]) tmc4361A_set_PID(&tmc4361[w2], PID_BPG0); + // Rotary wheel: no travel end-stop -> full range (see finalize_homing_w). + tmc4361[w2].xmin = INT32_MIN; + tmc4361[w2].xmax = INT32_MAX; } W2_pos = 0; is_homing_W2 = false;