diff --git a/main_fw/src/main.c b/main_fw/src/main.c index 3e9852e869c7030e8d7f38441c884a9797a9098d..cd3d8d368086f6b58582fdf80bef15b887fb73ec 100644 --- a/main_fw/src/main.c +++ b/main_fw/src/main.c @@ -52,8 +52,15 @@ static uint16_t iter __xMR; static uint16_t fan_ramp_up_count __xMR = 0; #endif +/* MAX Speed Datasheet: 3600 */ +#define FAN_MAX_RPMS 3600 +#define FAN_MAX_FAIL_CNT 25 +/* The equivalent to float is 65536.0 */ +#define FAN_DEAD_WORD 0x3A00 static volatile uint16_t tacho_cnt[3] __xMR; static volatile uint16_t tacho_rpm[3] __xMR; +static volatile uint16_t tacho_rpm_prev[3] __xMR; +static volatile uint16_t tacho_rpm_fail_cnt[3] __xMR; // when fan_cmdrpm is 0, setfrpms and temp_curve_points_y represent // duty cycle (0 to 1000) @@ -230,30 +237,69 @@ int16_t sign(int16_t x) void __xMR update_rpm() { // 2 sensor periods = 1 revolution + /* FAN 0 Control */ if (fan_installed[0]) { tacho_rpm[0] = 60*tacho_cnt[0]/(1+fan_ppr[0]); tacho_cnt[0] = 0; - frpms_lin[0] = float_to_linear(tacho_rpm[0]); + if (tacho_rpm[0] <= FAN_MAX_RPMS) { + frpms_lin[0] = float_to_linear(tacho_rpm[0]); + tacho_rpm_prev[0] = tacho_rpm[0]; + tacho_rpm_fail_cnt[0] = 0; + } else { + tacho_rpm_fail_cnt[0]++; + if (tacho_rpm_fail_cnt[0] >= FAN_MAX_FAIL_CNT) { + frpms_lin[0] = FAN_DEAD_WORD; + } else { + frpms_lin[0] = float_to_linear(tacho_rpm_prev[0]); + } + tacho_rpm[0] = tacho_rpm_prev[0]; + } } else { tacho_rpm[0] = 0; tacho_cnt[0] = 0; frpms_lin[0] = float_to_linear(0); } + /* FAN 1 Control */ if (fan_installed[1]) { tacho_rpm[1] = 60*tacho_cnt[1]/(1+fan_ppr[1]); tacho_cnt[1] = 0; - frpms_lin[1] = float_to_linear(tacho_rpm[1]); + if (tacho_rpm[1] <= FAN_MAX_RPMS) { + frpms_lin[1] = float_to_linear(tacho_rpm[1]); + tacho_rpm_prev[1] = tacho_rpm[1]; + tacho_rpm_fail_cnt[1] = 0; + } else { + tacho_rpm_fail_cnt[1]++; + if (tacho_rpm_fail_cnt[1] >= FAN_MAX_FAIL_CNT) { + frpms_lin[1] = FAN_DEAD_WORD; + } else { + frpms_lin[1] = float_to_linear(tacho_rpm_prev[1]); + } + tacho_rpm[1] = tacho_rpm_prev[1]; + } } else { tacho_rpm[1] = 0; tacho_cnt[1] = 0; frpms_lin[1] = float_to_linear(0); } + /* FAN 2 Control */ if (fan_installed[2]) { tacho_rpm[2] = 60*tacho_cnt[2]/(1+fan_ppr[2]); tacho_cnt[2] = 0; - frpms_lin[2] = float_to_linear(tacho_rpm[2]); + if (tacho_rpm[2] <= FAN_MAX_RPMS) { + frpms_lin[2] = float_to_linear(tacho_rpm[2]); + tacho_rpm_prev[2] = tacho_rpm[2]; + tacho_rpm_fail_cnt[2] = 0; + } else { + tacho_rpm_fail_cnt[2]++; + if (tacho_rpm_fail_cnt[2] >= FAN_MAX_FAIL_CNT) { + frpms_lin[2] = FAN_DEAD_WORD; + } else { + frpms_lin[2] = float_to_linear(tacho_rpm_prev[2]); + } + tacho_rpm[2] = tacho_rpm_prev[2]; + } } else { tacho_rpm[2] = 0; tacho_cnt[2] = 0; @@ -578,12 +624,18 @@ endless_loop(void) int main(void) { + /* Initializes MCU, drivers and middleware */ atmel_start_init(); gpio_set_pin_pull_mode(ADDR0, GPIO_PULL_UP); gpio_set_pin_pull_mode(ADDR1, GPIO_PULL_UP); gpio_set_pin_pull_mode(ADDR2, GPIO_PULL_UP); + /* initialize counters to 0 */ + tacho_rpm_fail_cnt[0] = 0; + tacho_rpm_fail_cnt[1] = 0; + tacho_rpm_fail_cnt[2] = 0; + #if defined(MMFANT) || defined(MMPROT) ext_irq_register(PIN_PA17, inc_tacho1); ext_irq_register(PIN_PA16, inc_tacho2); @@ -592,6 +644,11 @@ int main(void) ext_irq_enable(PIN_PA16); ext_irq_enable(PIN_PA13); + /* initialize previous value to 0 */ + tacho_rpm_prev[0] = 0; + tacho_rpm_prev[1] = 0; + tacho_rpm_prev[2] = 0; + load_fan_config(); update_pwm(); @@ -599,6 +656,12 @@ int main(void) pwm_enable(&PWM_1); pwm_enable(&PWM_2); #else + /* initialize previous value to 0 */ + tacho_rpm_prev[0] = 0; + tacho_rpm_prev[1] = 0; + tacho_rpm_prev[2] = 0; + + /* RPM always 0 */ frpms_lin[0] = float_to_linear(0); frpms_lin[1] = float_to_linear(0); frpms_lin[2] = float_to_linear(0);