mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-03 12:32:06 +08:00
33d5cfc393
date: 2025-12-18T23:23:16 master commit: 3cdee7b54718ee14bd85befd6c5bad3d699c5479
80 lines
2.4 KiB
C
80 lines
2.4 KiB
C
#include "fan_declarations.h"
|
|
|
|
struct fan_state_t fan_state;
|
|
|
|
static const uint8_t FAN_TICK_FREQ = 8U;
|
|
static const uint8_t FAN_STALL_THRESHOLD_MIN = 3U;
|
|
|
|
|
|
void fan_set_power(uint8_t percentage) {
|
|
if (percentage > 0U) {
|
|
fan_state.power = CLAMP(percentage, 20U, 100U);
|
|
} else {
|
|
fan_state.power = 0U;
|
|
}
|
|
}
|
|
|
|
void fan_init(void) {
|
|
fan_state.stall_threshold = FAN_STALL_THRESHOLD_MIN;
|
|
fan_state.cooldown_counter = current_board->fan_enable_cooldown_time * FAN_TICK_FREQ;
|
|
llfan_init();
|
|
}
|
|
|
|
// Call this at FAN_TICK_FREQ
|
|
void fan_tick(void) {
|
|
const uint8_t FAN_STALL_THRESHOLD_MAX = 8U;
|
|
|
|
if (current_board->has_fan) {
|
|
// Measure fan RPM
|
|
uint16_t fan_rpm_fast = fan_state.tach_counter * (60U * FAN_TICK_FREQ / 4U); // 4 interrupts per rotation
|
|
fan_state.tach_counter = 0U;
|
|
fan_state.rpm = (fan_rpm_fast + (3U * fan_state.rpm)) / 4U;
|
|
|
|
// Stall detection
|
|
bool fan_stalled = false;
|
|
if (current_board->fan_stall_recovery) {
|
|
if (fan_state.power > 0U) {
|
|
if (fan_rpm_fast == 0U) {
|
|
fan_state.stall_counter = MIN(fan_state.stall_counter + 1U, 254U);
|
|
} else {
|
|
fan_state.stall_counter = 0U;
|
|
}
|
|
|
|
if (fan_state.stall_counter > (fan_state.stall_threshold*FAN_TICK_FREQ)) {
|
|
fan_stalled = true;
|
|
fan_state.stall_counter = 0U;
|
|
fan_state.stall_threshold = CLAMP(fan_state.stall_threshold + 2U, FAN_STALL_THRESHOLD_MIN, FAN_STALL_THRESHOLD_MAX);
|
|
fan_state.total_stall_count += 1U;
|
|
|
|
// datasheet gives this range as the minimum startup duty
|
|
fan_state.error_integral = CLAMP(fan_state.error_integral, 20.0f, 45.0f);
|
|
}
|
|
} else {
|
|
fan_state.stall_counter = 0U;
|
|
fan_state.stall_threshold = FAN_STALL_THRESHOLD_MIN;
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG_FAN
|
|
puth(fan_state.target_rpm);
|
|
print(" "); puth(fan_rpm_fast);
|
|
print(" "); puth(fan_state.power);
|
|
print(" "); puth(fan_state.stall_counter);
|
|
print("\n");
|
|
#endif
|
|
|
|
// Cooldown counter to prevent noise on tachometer line.
|
|
if (fan_state.power > 0U) {
|
|
fan_state.cooldown_counter = current_board->fan_enable_cooldown_time * FAN_TICK_FREQ;
|
|
} else {
|
|
if (fan_state.cooldown_counter > 0U) {
|
|
fan_state.cooldown_counter--;
|
|
}
|
|
}
|
|
|
|
// Set PWM and enable line
|
|
pwm_set(TIM3, 3, fan_state.power);
|
|
current_board->set_fan_enabled(!fan_stalled && ((fan_state.power > 0U) || (fan_state.cooldown_counter > 0U)));
|
|
}
|
|
}
|