2 #include "devThermal.h"
4 #if defined(HAS_THERMAL) || defined(HAS_FAN)
10 extern RxConfig config
;
12 extern TxConfig config
;
14 #define THERMAL_DURATION 1000
16 #if defined(HAS_THERMAL)
22 #if defined(HAS_SMART_FAN)
23 bool is_smart_fan_control
= false;
24 bool is_smart_fan_working
= false;
27 #ifdef HAS_THERMAL_LM75A
28 #ifndef OPT_HAS_THERMAL_LM75A
29 #define OPT_HAS_THERMAL_LM75A true
32 #define OPT_HAS_THERMAL_LM75A true
37 #include "POWERMGNT.h"
39 #if defined(GPIO_PIN_FAN_PWM)
40 constexpr uint8_t fanChannel
= 0;
43 #if !defined(FAN_MIN_RUNTIME)
44 #define FAN_MIN_RUNTIME 30U // intervals (seconds)
47 #define FAN_MIN_CHANGETIME 10U // intervals (seconds)
49 #if !defined(TACHO_PULSES_PER_REV)
50 #define TACHO_PULSES_PER_REV 4
53 static uint16_t currentRPM
= 0;
55 void init_rpm_counter(int pin
);
58 static void initialize()
60 #if defined(HAS_THERMAL)
61 #if defined(PLATFORM_ESP32_S3)
64 if (OPT_HAS_THERMAL_LM75A
&& GPIO_PIN_SCL
!= UNDEF_PIN
&& GPIO_PIN_SDA
!= UNDEF_PIN
)
70 if (GPIO_PIN_FAN_EN
!= UNDEF_PIN
)
72 pinMode(GPIO_PIN_FAN_EN
, OUTPUT
);
76 static void timeoutThermal()
78 #if defined(HAS_THERMAL)
79 #if !defined(PLATFORM_ESP32_S3)
80 if(OPT_HAS_THERMAL_LM75A
)
85 if(is_smart_fan_control
& !is_smart_fan_working
){
86 is_smart_fan_working
= true;
87 thermal
.update_threshold(USER_SMARTFAN_OFF
);
89 if(!is_smart_fan_control
& is_smart_fan_working
){
90 is_smart_fan_working
= false;
92 thermal
.update_threshold(config
.GetFanMode());
100 #if defined(PLATFORM_ESP32)
102 static void setFanSpeed()
104 const uint8_t defaultFanSpeeds
[] = {
115 uint32_t speed
= GPIO_PIN_FAN_SPEEDS
== nullptr ? defaultFanSpeeds
[POWERMGNT::currPower()] : GPIO_PIN_FAN_SPEEDS
[POWERMGNT::currPower()-POWERMGNT::getMinPower()];
116 ledcWrite(fanChannel
, speed
);
117 DBGLN("Fan speed: %d (power) -> %u (pwm)", POWERMGNT::currPower(), speed
);
123 * For enable-only fans:
124 * Checks the PowerFanThreshold vs CurrPower and enables the fan if at or above the threshold
125 * using a hysteresis. To turn on it must be at/above the threshold for a small time
126 * and then to turn off it must be below the threshold for FAN_MIN_RUNTIME intervals.
128 * all of the above applies, but rather than just turning the fan on, the speed of the fan
129 * is set according to the power output level.
131 static void timeoutFan()
134 static uint8_t fanStateDuration
;
136 #if defined(TARGET_RX)
137 bool fanShouldBeOn
= true;
139 bool fanShouldBeOn
= POWERMGNT::currPower() >= (PowerLevels_e
)config
.GetPowerFanThreshold();
145 #if defined(PLATFORM_ESP32)
147 if (GPIO_PIN_FAN_PWM
!= UNDEF_PIN
)
149 static PowerLevels_e lastPower
= MinPower
;
150 if (POWERMGNT::currPower() < lastPower
&& fanStateDuration
< FAN_MIN_CHANGETIME
)
154 if (POWERMGNT::currPower() > lastPower
|| fanStateDuration
>= FAN_MIN_CHANGETIME
)
157 lastPower
= POWERMGNT::currPower();
158 fanStateDuration
= 0; // reset the timeout
165 fanStateDuration
= 0; // reset the timeout
168 else if (fanStateDuration
< firmwareOptions
.fan_min_runtime
)
170 ++fanStateDuration
; // counting to turn off
175 if (GPIO_PIN_FAN_EN
!= UNDEF_PIN
)
177 digitalWrite(GPIO_PIN_FAN_EN
, LOW
);
179 #if defined(PLATFORM_ESP32)
180 else if (GPIO_PIN_FAN_PWM
!= UNDEF_PIN
)
182 ledcWrite(fanChannel
, 0);
185 fanStateDuration
= 0;
189 // vv else fan is off currently vv
190 else if (fanShouldBeOn
)
192 // Delay turning the fan on for 4 cycles to be sure it really should be on
193 if (fanStateDuration
< 3)
195 ++fanStateDuration
; // counting to turn on
199 if (GPIO_PIN_FAN_EN
!= UNDEF_PIN
)
201 digitalWrite(GPIO_PIN_FAN_EN
, HIGH
);
202 fanStateDuration
= 0;
204 #if defined(PLATFORM_ESP32)
205 else if (GPIO_PIN_FAN_PWM
!= UNDEF_PIN
)
207 // bump the fan to full power for one cycle in case
208 // the PWM level is not sufficient to get it moving
209 ledcWrite(fanChannel
, 192);
210 fanStateDuration
= FAN_MIN_CHANGETIME
;
219 uint16_t getCurrentRPM()
224 static void timeoutTacho()
226 #if defined(PLATFORM_ESP32)
227 if (GPIO_PIN_FAN_TACHO
!= UNDEF_PIN
)
229 currentRPM
= get_rpm();
230 DBGVLN("RPM %d", currentRPM
);
237 #if defined(PLATFORM_ESP32)
238 if (GPIO_PIN_FAN_PWM
!= UNDEF_PIN
)
240 ledcSetup(fanChannel
, 25000, 8);
241 ledcAttachPin(GPIO_PIN_FAN_PWM
, fanChannel
);
242 ledcWrite(fanChannel
, 0);
244 if (GPIO_PIN_FAN_TACHO
!= UNDEF_PIN
)
246 init_rpm_counter(GPIO_PIN_FAN_TACHO
);
249 return DURATION_IMMEDIATELY
;
254 #if defined(HAS_THERMAL)
255 if (OPT_HAS_THERMAL_LM75A
&& GPIO_PIN_SCL
!= UNDEF_PIN
&& GPIO_PIN_SDA
!= UNDEF_PIN
)
258 if(!is_smart_fan_control
)
261 thermal
.update_threshold(config
.GetFanMode());
267 return DURATION_IGNORE
;
275 return THERMAL_DURATION
;
278 device_t Thermal_device
= {
279 .initialize
= initialize
,
285 #endif // HAS_THERMAL || HAS_FAN