2 #include "devThermal.h"
4 #if defined(PLATFORM_ESP32)
8 #define THERMAL_DURATION 1000
14 #if defined(HAS_SMART_FAN)
15 bool is_smart_fan_control
= false;
16 bool is_smart_fan_working
= false;
19 #include "POWERMGNT.h"
21 constexpr uint8_t fanChannel
= 0;
23 #define FAN_MIN_CHANGETIME 10U // intervals (seconds)
25 static uint16_t currentRPM
= 0;
27 void init_rpm_counter(int pin
);
30 static bool initialize()
33 #if defined(PLATFORM_ESP32_S3)
37 if (OPT_HAS_THERMAL_LM75A
&& GPIO_PIN_SCL
!= UNDEF_PIN
&& GPIO_PIN_SDA
!= UNDEF_PIN
)
43 if (GPIO_PIN_FAN_EN
!= UNDEF_PIN
)
45 pinMode(GPIO_PIN_FAN_EN
, OUTPUT
);
51 static void timeoutThermal()
53 #if defined(TARGET_TX)
54 #if !defined(PLATFORM_ESP32_S3)
55 if(OPT_HAS_THERMAL_LM75A
)
60 if(is_smart_fan_control
& !is_smart_fan_working
){
61 is_smart_fan_working
= true;
62 thermal
.update_threshold(USER_SMARTFAN_OFF
);
64 if(!is_smart_fan_control
& is_smart_fan_working
){
65 is_smart_fan_working
= false;
67 thermal
.update_threshold(config
.GetFanMode());
75 #if defined(TARGET_TX) && defined(PLATFORM_ESP32)
76 static void setFanSpeed()
78 const uint8_t defaultFanSpeeds
[] = {
89 uint32_t speed
= GPIO_PIN_FAN_SPEEDS
== nullptr ? defaultFanSpeeds
[POWERMGNT::currPower()] : GPIO_PIN_FAN_SPEEDS
[POWERMGNT::currPower()-POWERMGNT::getMinPower()];
90 ledcWrite(fanChannel
, speed
);
91 DBGLN("Fan speed: %d (power) -> %u (pwm)", POWERMGNT::currPower(), speed
);
96 * For enable-only fans:
97 * Checks the PowerFanThreshold vs CurrPower and enables the fan if at or above the threshold
98 * using a hysteresis. To turn on it must be at/above the threshold for a small time
99 * and then to turn off it must be below the threshold for FAN_MIN_RUNTIME intervals.
101 * all of the above applies, but rather than just turning the fan on, the speed of the fan
102 * is set according to the power output level.
104 static void timeoutFan()
106 static uint8_t fanStateDuration
;
108 #if defined(TARGET_RX)
109 bool fanShouldBeOn
= true;
111 bool fanShouldBeOn
= POWERMGNT::currPower() >= (PowerLevels_e
)config
.GetPowerFanThreshold();
117 #if defined(TARGET_TX) && defined(PLATFORM_ESP32)
118 if (GPIO_PIN_FAN_PWM
!= UNDEF_PIN
)
120 static PowerLevels_e lastPower
= MinPower
;
121 if (POWERMGNT::currPower() < lastPower
&& fanStateDuration
< FAN_MIN_CHANGETIME
)
125 if (POWERMGNT::currPower() > lastPower
|| fanStateDuration
>= FAN_MIN_CHANGETIME
)
128 lastPower
= POWERMGNT::currPower();
129 fanStateDuration
= 0; // reset the timeout
135 fanStateDuration
= 0; // reset the timeout
138 else if (fanStateDuration
< firmwareOptions
.fan_min_runtime
)
140 ++fanStateDuration
; // counting to turn off
145 if (GPIO_PIN_FAN_EN
!= UNDEF_PIN
)
147 digitalWrite(GPIO_PIN_FAN_EN
, LOW
);
149 else if (GPIO_PIN_FAN_PWM
!= UNDEF_PIN
)
151 ledcWrite(fanChannel
, 0);
153 fanStateDuration
= 0;
157 // vv else fan is off currently vv
158 else if (fanShouldBeOn
)
160 // Delay turning the fan on for 4 cycles to be sure it really should be on
161 if (fanStateDuration
< 3)
163 ++fanStateDuration
; // counting to turn on
167 if (GPIO_PIN_FAN_EN
!= UNDEF_PIN
)
169 digitalWrite(GPIO_PIN_FAN_EN
, HIGH
);
170 fanStateDuration
= 0;
172 else if (GPIO_PIN_FAN_PWM
!= UNDEF_PIN
)
174 // bump the fan to full power for one cycle in case
175 // the PWM level is not sufficient to get it moving
176 ledcWrite(fanChannel
, 192);
177 fanStateDuration
= FAN_MIN_CHANGETIME
;
184 uint16_t getCurrentRPM()
189 #if !defined(PLATFORM_ESP32_C3)
190 static void timeoutTacho()
192 if (GPIO_PIN_FAN_TACHO
!= UNDEF_PIN
)
194 currentRPM
= get_rpm();
195 DBGVLN("RPM %d", currentRPM
);
202 if (GPIO_PIN_FAN_PWM
!= UNDEF_PIN
)
204 ledcSetup(fanChannel
, 25000, 8);
205 ledcAttachPin(GPIO_PIN_FAN_PWM
, fanChannel
);
206 ledcWrite(fanChannel
, 0);
208 #if !defined(PLATFORM_ESP32_C3)
209 if (GPIO_PIN_FAN_TACHO
!= UNDEF_PIN
)
211 init_rpm_counter(GPIO_PIN_FAN_TACHO
);
214 return DURATION_IMMEDIATELY
;
219 #if defined(TARGET_TX)
220 if (OPT_HAS_THERMAL_LM75A
&& GPIO_PIN_SCL
!= UNDEF_PIN
&& GPIO_PIN_SDA
!= UNDEF_PIN
)
223 if(!is_smart_fan_control
)
226 thermal
.update_threshold(config
.GetFanMode());
232 return DURATION_IGNORE
;
239 #if !defined(PLATFORM_ESP32_C3)
242 return THERMAL_DURATION
;
245 device_t Thermal_device
= {
246 .initialize
= initialize
,