diff --git a/main/boards/board.cpp b/main/boards/board.cpp index 18c85a0b..84cc2936 100644 --- a/main/boards/board.cpp +++ b/main/boards/board.cpp @@ -45,6 +45,7 @@ void Board::loadSettings() m_vrFrequency = Config::getVrFrequency(m_defaultVrFrequency); for (int ch = 0; ch < 2; ch++) { + m_fanMode[ch] = Config::getFanMode(ch, m_fanMode[ch]); m_pidSettings[ch].targetTemp = Config::getFanPidTargetTemp(ch, m_pidSettings[ch].targetTemp); m_pidSettings[ch].p = Config::getFanPidP(ch, m_pidSettings[ch].p); m_pidSettings[ch].i = Config::getFanPidI(ch, m_pidSettings[ch].i); diff --git a/main/boards/board.h b/main/boards/board.h index 63dadc2e..9e217ad4 100644 --- a/main/boards/board.h +++ b/main/boards/board.h @@ -51,6 +51,11 @@ class Board { // ch1 base defaults (overridden in subclass ctors where needed): 65°C, p=6, i=0.1, d=10. PidSettings m_pidSettings[2] = {{}, {65, 600, 10, 1000}}; + // Fan control mode per channel (0=manual, 2=PID, 3=linked). Initialized to + // the default here and overwritten from NVS in loadSettings() — same + // handling as m_pidSettings. ch0 = global Kconfig default, ch1 = linked. + int m_fanMode[2] = {CONFIG_AUTO_FAN_SPEED_VALUE, 3}; + // Human-readable connector labels shown in the web UI const char* m_fanLabels[2] = {"Fan 1", "Fan 2"}; @@ -314,6 +319,10 @@ class Board { return &m_pidSettings[ch]; } + int getFanMode(int ch) { + return m_fanMode[ch]; + } + const char* getFanLabel(int ch) const { if (ch < 0 || ch >= m_numFans) return ""; return m_fanLabels[ch]; diff --git a/main/boards/q1373.cpp b/main/boards/q1373.cpp index e487d255..209dea8b 100644 --- a/main/boards/q1373.cpp +++ b/main/boards/q1373.cpp @@ -34,14 +34,14 @@ Q1373B::Q1373B() : Q1370B() m_asicFrequencies = {250, 275, 300, 325, 350, 375, 400, 425, 475, 500, 550}; m_asicVoltages = {980, 990, 1000, 1010, 1020, 1030, 1040, 1050, 1060, 1070, 1080}; - m_defaultAsicFrequency = m_asicFrequency = 350; + m_defaultAsicFrequency = m_asicFrequency = 425; m_defaultAsicVoltageMillis = m_asicVoltageMillis = 1010; m_absMaxAsicFrequency = 730; m_absMinAsicVoltageMillis = 900; m_absMaxAsicVoltageMillis = 1200; m_initVoltageMillis = 1050; - m_pidSettings[0].targetTemp = 55; + m_pidSettings[0].targetTemp = 60; m_pidSettings[0].p = 600; // 6.00 m_pidSettings[0].i = 10; // 0.10 m_pidSettings[0].d = 1000; // 10.00 @@ -51,6 +51,10 @@ Q1373B::Q1373B() : Q1370B() m_pidSettings[1].i = 10; // 0.10 m_pidSettings[1].d = 1000; // 10.00 + // ship with PID fan control by default (ch1 stays linked); with target 60°C + // the fan holds max(ASIC, VReg) for good out-of-the-box efficiency + m_fanMode[0] = 2; // PID + m_asicMaxDifficulty = 4096; m_asicMinDifficulty = 1024; m_asicMinDifficultyDualPool = 512; diff --git a/main/displays/displayDriver.cpp b/main/displays/displayDriver.cpp index ea7b7c12..790005da 100644 --- a/main/displays/displayDriver.cpp +++ b/main/displays/displayDriver.cpp @@ -76,7 +76,7 @@ DisplayDriver::DisplayDriver() { void DisplayDriver::loadSettings() { PThreadGuard lock(m_lvglMutex); m_isAutoScreenOffEnabled = Config::isAutoScreenOffEnabled(); - m_tempControlMode = Config::getTempControlMode(); + m_tempControlMode = SYSTEM_MODULE.getBoard()->getFanMode(0); m_fanSpeed = Config::getFanSpeed(); m_showFoundBlockEnabled = Config::isShowBlockFoundEnabled(); diff --git a/main/fan_controller.cpp b/main/fan_controller.cpp index 15997ece..ce09c3d2 100644 --- a/main/fan_controller.cpp +++ b/main/fan_controller.cpp @@ -72,7 +72,7 @@ void FanController::loadSettings() for (int ch = 0; ch < m_numChannels; ch++) { PidSettings* bp = m_board->getPidSettings(ch); - m_config[ch].mode = static_cast(Config::getFanMode(ch)); + m_config[ch].mode = static_cast(m_board->getFanMode(ch)); m_config[ch].manualSpeed = Config::getFanManualSpeed(ch); m_config[ch].overheatTemp = Config::getFanOverheatTemp(ch); m_config[ch].pid.targetTemp = Config::getFanPidTargetTemp(ch, bp->targetTemp); diff --git a/main/http_server/handler_can_swarm.cpp b/main/http_server/handler_can_swarm.cpp index a2ead928..403d92ac 100644 --- a/main/http_server/handler_can_swarm.cpp +++ b/main/http_server/handler_can_swarm.cpp @@ -99,7 +99,7 @@ esp_err_t GET_can_nodes(httpd_req_t *req) JsonArray fans = master["fans"].to(); for (int ch = 0; ch < numFans; ch++) { JsonObject fan = fans.add(); - fan["mode"] = Config::getFanMode(ch); + fan["mode"] = board->getFanMode(ch); fan["manualSpeed"] = Config::getFanManualSpeed(ch); fan["overheatTemp"]= Config::getFanOverheatTemp(ch); fan["targetTemp"] = board->getPidSettings(ch)->targetTemp; diff --git a/main/http_server/handler_system.cpp b/main/http_server/handler_system.cpp index 0aeb59c4..8cbd6166 100644 --- a/main/http_server/handler_system.cpp +++ b/main/http_server/handler_system.cpp @@ -187,7 +187,7 @@ esp_err_t GET_system_info(httpd_req_t *req) PidSettings* fanPid = board->getPidSettings(ch); JsonObject fan = fans.add(); fan["label"] = board->getFanLabel(ch); - fan["mode"] = Config::getFanMode(ch); + fan["mode"] = board->getFanMode(ch); fan["manualSpeed"] = Config::getFanManualSpeed(ch); fan["overheatTemp"] = Config::getFanOverheatTemp(ch); fan["rpm"] = POWER_MANAGEMENT_MODULE.getFanRPM(ch); @@ -228,7 +228,7 @@ esp_err_t GET_system_info(httpd_req_t *req) doc["invertscreen"] = Config::isInvertScreenEnabled() ? 1 : 0; // unused? doc["autoscreenoff"] = Config::isAutoScreenOffEnabled() ? 1 : 0; doc["invertfanpolarity"] = board->isInvertFanPolarityEnabled() ? 1 : 0; - doc["autofanspeed"] = Config::getTempControlMode(); + doc["autofanspeed"] = board->getFanMode(0); doc["stratum_keep"] = Config::isStratumKeepaliveEnabled() ? 1 : 0; #ifdef VR_FREQUENCY_ENABLED doc["vrFrequency"] = board->getVrFrequency(); diff --git a/main/http_server/v2/handler_v2_settings.cpp b/main/http_server/v2/handler_v2_settings.cpp index 0a3b2ea7..db6516e3 100644 --- a/main/http_server/v2/handler_v2_settings.cpp +++ b/main/http_server/v2/handler_v2_settings.cpp @@ -131,7 +131,7 @@ esp_err_t GET_V2_settings(httpd_req_t *req) PidSettings* fanPid = board->getPidSettings(ch); JsonObject fan = fans.add(); fan["label"] = board->getFanLabel(ch); - fan["mode"] = Config::getFanMode(ch); + fan["mode"] = board->getFanMode(ch); fan["manualSpeed"] = Config::getFanManualSpeed(ch); fan["overheatTemp"] = Config::getFanOverheatTemp(ch); JsonObject pid_obj = fan["pid"].to(); diff --git a/main/nvs_config.h b/main/nvs_config.h index 6ac142d1..47b44360 100644 --- a/main/nvs_config.h +++ b/main/nvs_config.h @@ -189,7 +189,6 @@ namespace Config { inline uint16_t getFanSpeed() { return cfgGetU16(NVS_CONFIG_FAN_SPEED, CONFIG_FAN_SPEED); } inline uint16_t getOverheatTemp() { return cfgGetU16(NVS_CONFIG_OVERHEAT_TEMP, CONFIG_OVERHEAT_TEMP); } inline uint16_t getInfluxPort() { return cfgGetU16(NVS_CONFIG_INFLUX_PORT, CONFIG_INFLUX_PORT); } - inline uint16_t getTempControlMode() { return cfgGetU16(NVS_CONFIG_AUTO_FAN_SPEED, CONFIG_AUTO_FAN_SPEED_VALUE); } inline uint16_t getPoolMode() { return cfgGetU16(NVS_CONFIG_POOL_MODE, 0); } inline uint16_t getPoolBalance() { return cfgGetU16(NVS_CONFIG_POOL_MODE_BALANCE, 50); } @@ -214,9 +213,9 @@ namespace Config { // Indexed fan-channel getters (ch=0 → ch0 NVS keys, ch=1 → fan1 NVS keys) // ch0 defaults: mode=CONFIG_AUTO_FAN_SPEED_VALUE, speed=CONFIG_FAN_SPEED, overheat=CONFIG_OVERHEAT_TEMP // ch1 defaults: mode=3 (linked), speed=100%, overheat=80°C - inline uint16_t getFanMode(int ch) { - return ch == 0 ? cfgGetU16(NVS_CONFIG_AUTO_FAN_SPEED, CONFIG_AUTO_FAN_SPEED_VALUE) - : cfgGetU16(NVS_CONFIG_FAN1_MODE, 3); + inline uint16_t getFanMode(int ch, uint16_t def) { + return ch == 0 ? cfgGetU16(NVS_CONFIG_AUTO_FAN_SPEED, def) + : cfgGetU16(NVS_CONFIG_FAN1_MODE, def); } inline uint16_t getFanManualSpeed(int ch) { return ch == 0 ? cfgGetU16(NVS_CONFIG_FAN_SPEED, CONFIG_FAN_SPEED) diff --git a/main/tasks/can_slave_task.cpp b/main/tasks/can_slave_task.cpp index b87ca0c7..4eca5bf9 100644 --- a/main/tasks/can_slave_task.cpp +++ b/main/tasks/can_slave_task.cpp @@ -106,11 +106,11 @@ static void send_slave_config(uint8_t slave_id) strncpy(c.fwVersion, app->version, sizeof(c.fwVersion) - 1); c.freqMhz = (uint16_t) Config::getAsicFrequency(board->getDefaultAsicFrequency()); c.voltageMv = (uint16_t) Config::getAsicVoltage(board->getDefaultAsicVoltageMillis()); - c.fan0Mode = (uint8_t) Config::getFanMode(0); + c.fan0Mode = (uint8_t) board->getFanMode(0); c.fan0Speed = (uint8_t) Config::getFanManualSpeed(0); c.fan0TargetTemp = (uint8_t) Config::getFanPidTargetTemp(0, board->getPidSettings(0)->targetTemp); c.fan0Overheat = (uint8_t) Config::getFanOverheatTemp(0); - c.fan1Mode = (uint8_t) Config::getFanMode(1); + c.fan1Mode = (uint8_t) board->getFanMode(1); c.fan1Speed = (uint8_t) Config::getFanManualSpeed(1); c.fan1TargetTemp = (uint8_t) Config::getFanPidTargetTemp(1, board->getPidSettings(1)->targetTemp); c.fan1Overheat = (uint8_t) Config::getFanOverheatTemp(1);