Add fan abstraction
This commit is contained in:
committed by
Jeremy Soller
parent
788fa927ef
commit
d35e375277
@ -8,3 +8,72 @@ void fan_reset(void) {
|
||||
// Do not manually set fans to maximum speed
|
||||
fan_max = false;
|
||||
}
|
||||
|
||||
// Get duty cycle based on temperature, adapted from
|
||||
// https://github.com/pop-os/system76-power/blob/master/src/fan.rs
|
||||
uint8_t fan_duty(const struct Fan * fan, int16_t temp) __reentrant {
|
||||
for (int i = 0; i < fan->points_size; i++) {
|
||||
const struct FanPoint * cur = &fan->points[i];
|
||||
|
||||
// If exactly the current temp, return the current duty
|
||||
if (temp == cur->temp) {
|
||||
return cur->duty;
|
||||
} else if (temp < cur->temp) {
|
||||
// If lower than first temp, return 0%
|
||||
if (i == 0) {
|
||||
return PWM_DUTY(0);
|
||||
} else {
|
||||
const struct FanPoint * prev = &fan->points[i - 1];
|
||||
|
||||
if (fan->interpolate) {
|
||||
// If in between current temp and previous temp, interpolate
|
||||
if (temp > prev->temp) {
|
||||
int16_t dtemp = (cur->temp - prev->temp);
|
||||
int16_t dduty = ((int16_t)cur->duty) - ((int16_t)prev->duty);
|
||||
return (uint8_t)(
|
||||
((int16_t)prev->duty) +
|
||||
((temp - prev->temp) * dduty) / dtemp
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return prev->duty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no point is found, return 100%
|
||||
return PWM_DUTY(100);
|
||||
}
|
||||
|
||||
uint8_t fan_heatup(const struct Fan * fan, uint8_t duty) __reentrant {
|
||||
uint8_t lowest = duty;
|
||||
|
||||
int i;
|
||||
for (i = 0; (i + 1) < fan->heatup_size; i++) {
|
||||
uint8_t value = fan->heatup[i + 1];
|
||||
if (value < lowest) {
|
||||
lowest = value;
|
||||
}
|
||||
fan->heatup[i] = value;
|
||||
}
|
||||
fan->heatup[i] = duty;
|
||||
|
||||
return lowest;
|
||||
}
|
||||
|
||||
uint8_t fan_cooldown(const struct Fan * fan, uint8_t duty) __reentrant {
|
||||
uint8_t highest = duty;
|
||||
|
||||
int i;
|
||||
for (i = 0; (i + 1) < fan->cooldown_size; i++) {
|
||||
uint8_t value = fan->cooldown[i + 1];
|
||||
if (value > highest) {
|
||||
highest = value;
|
||||
}
|
||||
fan->cooldown[i] = value;
|
||||
}
|
||||
fan->cooldown[i] = duty;
|
||||
|
||||
return highest;
|
||||
}
|
||||
|
Reference in New Issue
Block a user