diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index e0007ab7b3f6..4f15621a254b 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2567,10 +2567,21 @@ #if ANY(HAS_AUTO_FAN_0, HAS_AUTO_FAN_1, HAS_AUTO_FAN_2, HAS_AUTO_FAN_3, HAS_AUTO_FAN_4, HAS_AUTO_FAN_5, HAS_AUTO_FAN_6, HAS_AUTO_FAN_7, HAS_AUTO_CHAMBER_FAN, HAS_AUTO_COOLER_FAN) #define HAS_AUTO_FAN 1 -#endif -#define _FANOVERLAP(A,B) (A##_AUTO_FAN_PIN == E##B##_AUTO_FAN_PIN) -#if HAS_AUTO_FAN && (_FANOVERLAP(CHAMBER,0) || _FANOVERLAP(CHAMBER,1) || _FANOVERLAP(CHAMBER,2) || _FANOVERLAP(CHAMBER,3) || _FANOVERLAP(CHAMBER,4) || _FANOVERLAP(CHAMBER,5) || _FANOVERLAP(CHAMBER,6) || _FANOVERLAP(CHAMBER,7)) - #define AUTO_CHAMBER_IS_E 1 + #define _FANOVERLAP(I,T) (T##_AUTO_FAN_PIN == E##I##_AUTO_FAN_PIN) + #if HAS_AUTO_CHAMBER_FAN + #define _CHFANOVERLAP(I) || _FANOVERLAP(I,CHAMBER) + #if (0 REPEAT(8, _CHFANOVERLAP)) + #define AUTO_CHAMBER_IS_E 1 + #endif + #undef _CHFANOVERLAP + #endif + #if HAS_AUTO_COOLER_FAN + #define _COFANOVERLAP(I) || _FANOVERLAP(I,COOLER) + #if (0 REPEAT(8, _COFANOVERLAP)) + #define AUTO_COOLER_IS_E 1 + #endif + #undef _COFANOVERLAP + #endif #endif // Fans check @@ -2615,6 +2626,9 @@ #if !HAS_AUTO_CHAMBER_FAN || AUTO_CHAMBER_IS_E #undef AUTO_POWER_CHAMBER_FAN #endif +#if !HAS_AUTO_COOLER_FAN || AUTO_COOLER_IS_E + #undef AUTO_POWER_COOLER_FAN +#endif // Print Cooling fans (limit) #ifdef NUM_M106_FANS diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 49fa1ea1a4a0..3db20987780c 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -2948,24 +2948,9 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE, "Movement bounds (X_MIN_POS, X_MAX_POS * Auto Fan check for PWM pins */ #if HAS_AUTO_FAN && EXTRUDER_AUTO_FAN_SPEED != 255 - #define AF_ERR_SUFF "_AUTO_FAN_PIN is not a PWM pin. Set EXTRUDER_AUTO_FAN_SPEED to 255." - #if HAS_AUTO_FAN_0 - static_assert(_TEST_PWM(E0_AUTO_FAN_PIN), "E0" AF_ERR_SUFF); - #elif HAS_AUTO_FAN_1 - static_assert(_TEST_PWM(E1_AUTO_FAN_PIN), "E1" AF_ERR_SUFF); - #elif HAS_AUTO_FAN_2 - static_assert(_TEST_PWM(E2_AUTO_FAN_PIN), "E2" AF_ERR_SUFF); - #elif HAS_AUTO_FAN_3 - static_assert(_TEST_PWM(E3_AUTO_FAN_PIN), "E3" AF_ERR_SUFF); - #elif HAS_AUTO_FAN_4 - static_assert(_TEST_PWM(E4_AUTO_FAN_PIN), "E4" AF_ERR_SUFF); - #elif HAS_AUTO_FAN_5 - static_assert(_TEST_PWM(E5_AUTO_FAN_PIN), "E5" AF_ERR_SUFF); - #elif HAS_AUTO_FAN_6 - static_assert(_TEST_PWM(E6_AUTO_FAN_PIN), "E6" AF_ERR_SUFF); - #elif HAS_AUTO_FAN_7 - static_assert(_TEST_PWM(E7_AUTO_FAN_PIN), "E7" AF_ERR_SUFF); - #endif + #define AF_ASSERT(N) OPTCODE(HAS_AUTO_FAN_##N, static_assert(_TEST_PWM(E##N##_AUTO_FAN_PIN), "E" STRINGIFY(N) "_AUTO_FAN_PIN is not a PWM pin. Set EXTRUDER_AUTO_FAN_SPEED to 255.")) + REPEAT(8, AF_ASSERT) + #undef AF_ASSERT #endif /** diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 07a4752002c4..ffe3dcc03dae 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -1166,44 +1166,55 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { } } -#define _EFANOVERLAP(A,B) _FANOVERLAP(E##A,B) - #if HAS_AUTO_FAN + #define _EFANOVERLAP(I,N) ((I != N) && _FANOVERLAP(I,E##N)) + #if EXTRUDER_AUTO_FAN_SPEED != 255 - #define INIT_E_AUTO_FAN_PIN(P) do{ if (P == FAN1_PIN || P == FAN2_PIN) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) + #define INIT_E_AUTO_FAN_PIN(P) do{ if (PWM_PIN(P)) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) #else #define INIT_E_AUTO_FAN_PIN(P) SET_OUTPUT(P) #endif #if CHAMBER_AUTO_FAN_SPEED != 255 - #define INIT_CHAMBER_AUTO_FAN_PIN(P) do{ if (P == FAN1_PIN || P == FAN2_PIN) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) + #define INIT_CHAMBER_AUTO_FAN_PIN(P) do{ if (PWM_PIN(P)) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) #else #define INIT_CHAMBER_AUTO_FAN_PIN(P) SET_OUTPUT(P) #endif + #if COOLER_AUTO_FAN_SPEED != 255 + #define INIT_COOLER_AUTO_FAN_PIN(P) do{ if (PWM_PIN(P)) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) + #else + #define INIT_COOLER_AUTO_FAN_PIN(P) SET_OUTPUT(P) + #endif #ifndef CHAMBER_FAN_INDEX #define CHAMBER_FAN_INDEX HOTENDS #endif void Temperature::update_autofans() { - #define _EFAN(B,A) _EFANOVERLAP(A,B) ? B : + #define _EFAN(I,N) _EFANOVERLAP(I,N) ? I : static const uint8_t fanBit[] PROGMEM = { 0 #if HAS_MULTI_HOTEND #define _NEXT_FAN(N) , REPEAT2(N,_EFAN,N) N RREPEAT_S(1, HOTENDS, _NEXT_FAN) #endif + #define _NFAN HOTENDS #if HAS_AUTO_CHAMBER_FAN - #define _CFAN(B) _FANOVERLAP(CHAMBER,B) ? B : - , REPEAT(HOTENDS,_CFAN) (HOTENDS) + #define _CHFAN(I) _FANOVERLAP(I,CHAMBER) ? I : + , (REPEAT(HOTENDS,_CHFAN) (_NFAN)) + #undef _NFAN + #define _NFAN INCREMENT(HOTENDS) + #endif + #if HAS_AUTO_COOLER_FAN + #define _COFAN(I) _FANOVERLAP(I,COOLER) ? I : + , (REPEAT(HOTENDS,_COFAN) (_NFAN)) #endif }; uint8_t fanState = 0; HOTEND_LOOP() { - if (temp_hotend[e].celsius >= EXTRUDER_AUTO_FAN_TEMPERATURE) { + if (temp_hotend[e].celsius >= EXTRUDER_AUTO_FAN_TEMPERATURE) SBI(fanState, pgm_read_byte(&fanBit[e])); - } } #if HAS_AUTO_CHAMBER_FAN @@ -1234,6 +1245,11 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { chamberfan_speed = fan_on ? CHAMBER_AUTO_FAN_SPEED : 0; break; #endif + #if ENABLED(AUTO_POWER_COOLER_FAN) + case COOLER_FAN_INDEX: + coolerfan_speed = fan_on ? COOLER_AUTO_FAN_SPEED : 0; + break; + #endif default: #if EITHER(AUTO_POWER_E_FANS, HAS_FANCHECK) autofan_speed[realFan] = fan_on ? EXTRUDER_AUTO_FAN_SPEED : 0; @@ -1247,35 +1263,16 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { #define _AUTOFAN_SPEED() EXTRUDER_AUTO_FAN_SPEED #endif #define _AUTOFAN_CASE(N) case N: _UPDATE_AUTO_FAN(E##N, fan_on, _AUTOFAN_SPEED()); break + #define AUTOFAN_CASE(N) OPTCODE(HAS_AUTO_FAN_##N, _AUTOFAN_CASE(N)) switch (f) { - #if HAS_AUTO_FAN_0 - _AUTOFAN_CASE(0); - #endif - #if HAS_AUTO_FAN_1 - _AUTOFAN_CASE(1); - #endif - #if HAS_AUTO_FAN_2 - _AUTOFAN_CASE(2); - #endif - #if HAS_AUTO_FAN_3 - _AUTOFAN_CASE(3); - #endif - #if HAS_AUTO_FAN_4 - _AUTOFAN_CASE(4); - #endif - #if HAS_AUTO_FAN_5 - _AUTOFAN_CASE(5); - #endif - #if HAS_AUTO_FAN_6 - _AUTOFAN_CASE(6); - #endif - #if HAS_AUTO_FAN_7 - _AUTOFAN_CASE(7); - #endif + REPEAT(8, AUTOFAN_CASE) #if HAS_AUTO_CHAMBER_FAN && !AUTO_CHAMBER_IS_E case CHAMBER_FAN_INDEX: _UPDATE_AUTO_FAN(CHAMBER, fan_on, CHAMBER_AUTO_FAN_SPEED); break; #endif + #if HAS_AUTO_COOLER_FAN && !AUTO_COOLER_IS_E + case COOLER_FAN_INDEX: _UPDATE_AUTO_FAN(COOLER, fan_on, COOLER_AUTO_FAN_SPEED); break; + #endif } SBI(fanDone, realFan); } @@ -2704,33 +2701,39 @@ void Temperature::init() { HAL_timer_start(MF_TIMER_TEMP, TEMP_TIMER_FREQUENCY); ENABLE_TEMPERATURE_INTERRUPT(); - #if HAS_AUTO_FAN_0 - INIT_E_AUTO_FAN_PIN(E0_AUTO_FAN_PIN); - #endif - #if HAS_AUTO_FAN_1 && !_EFANOVERLAP(1,0) - INIT_E_AUTO_FAN_PIN(E1_AUTO_FAN_PIN); - #endif - #if HAS_AUTO_FAN_2 && !(_EFANOVERLAP(2,0) || _EFANOVERLAP(2,1)) - INIT_E_AUTO_FAN_PIN(E2_AUTO_FAN_PIN); - #endif - #if HAS_AUTO_FAN_3 && !(_EFANOVERLAP(3,0) || _EFANOVERLAP(3,1) || _EFANOVERLAP(3,2)) - INIT_E_AUTO_FAN_PIN(E3_AUTO_FAN_PIN); - #endif - #if HAS_AUTO_FAN_4 && !(_EFANOVERLAP(4,0) || _EFANOVERLAP(4,1) || _EFANOVERLAP(4,2) || _EFANOVERLAP(4,3)) - INIT_E_AUTO_FAN_PIN(E4_AUTO_FAN_PIN); - #endif - #if HAS_AUTO_FAN_5 && !(_EFANOVERLAP(5,0) || _EFANOVERLAP(5,1) || _EFANOVERLAP(5,2) || _EFANOVERLAP(5,3) || _EFANOVERLAP(5,4)) - INIT_E_AUTO_FAN_PIN(E5_AUTO_FAN_PIN); - #endif - #if HAS_AUTO_FAN_6 && !(_EFANOVERLAP(6,0) || _EFANOVERLAP(6,1) || _EFANOVERLAP(6,2) || _EFANOVERLAP(6,3) || _EFANOVERLAP(6,4) || _EFANOVERLAP(6,5)) - INIT_E_AUTO_FAN_PIN(E6_AUTO_FAN_PIN); - #endif - #if HAS_AUTO_FAN_7 && !(_EFANOVERLAP(7,0) || _EFANOVERLAP(7,1) || _EFANOVERLAP(7,2) || _EFANOVERLAP(7,3) || _EFANOVERLAP(7,4) || _EFANOVERLAP(7,5) || _EFANOVERLAP(7,6)) - INIT_E_AUTO_FAN_PIN(E7_AUTO_FAN_PIN); - #endif - #if HAS_AUTO_CHAMBER_FAN && !AUTO_CHAMBER_IS_E - INIT_CHAMBER_AUTO_FAN_PIN(CHAMBER_AUTO_FAN_PIN); - #endif + #if HAS_AUTO_FAN + #define _OREFAN(I,N) || _EFANOVERLAP(I,N) + #if HAS_AUTO_FAN_0 + INIT_E_AUTO_FAN_PIN(E0_AUTO_FAN_PIN); + #endif + #if HAS_AUTO_FAN_1 && !_EFANOVERLAP(0,1) + INIT_E_AUTO_FAN_PIN(E1_AUTO_FAN_PIN); + #endif + #if HAS_AUTO_FAN_2 && !(0 REPEAT2(2, _OREFAN, 2)) + INIT_E_AUTO_FAN_PIN(E2_AUTO_FAN_PIN); + #endif + #if HAS_AUTO_FAN_3 && !(0 REPEAT2(3, _OREFAN, 3)) + INIT_E_AUTO_FAN_PIN(E3_AUTO_FAN_PIN); + #endif + #if HAS_AUTO_FAN_4 && !(0 REPEAT2(4, _OREFAN, 4)) + INIT_E_AUTO_FAN_PIN(E4_AUTO_FAN_PIN); + #endif + #if HAS_AUTO_FAN_5 && !(0 REPEAT2(5, _OREFAN, 5)) + INIT_E_AUTO_FAN_PIN(E5_AUTO_FAN_PIN); + #endif + #if HAS_AUTO_FAN_6 && !(0 REPEAT2(6, _OREFAN, 6)) + INIT_E_AUTO_FAN_PIN(E6_AUTO_FAN_PIN); + #endif + #if HAS_AUTO_FAN_7 && !(0 REPEAT2(7, _OREFAN, 7)) + INIT_E_AUTO_FAN_PIN(E7_AUTO_FAN_PIN); + #endif + #if HAS_AUTO_CHAMBER_FAN && !AUTO_CHAMBER_IS_E + INIT_CHAMBER_AUTO_FAN_PIN(CHAMBER_AUTO_FAN_PIN); + #endif + #if HAS_AUTO_COOLER_FAN && !AUTO_COOLER_IS_E + INIT_COOLER_AUTO_FAN_PIN(COOLER_AUTO_FAN_PIN); + #endif + #endif // HAS_AUTO_FAN #if HAS_HOTEND #define _TEMP_MIN_E(NR) do{ \