| // Copyright 2012 Google Inc. All Rights Reserved. |
| // Author: kedong@google.com (Ke Dong) |
| |
| #include "bruno/logging.h" |
| #include "platform.h" |
| #include "fancontrol.h" |
| #include <stdio.h> |
| #include <vector> |
| #include <string> |
| #include <sstream> |
| #include <iostream> |
| #include <string.h> |
| #include <stdint.h> |
| #include <fstream> |
| #include <unistd.h> |
| |
| namespace bruno_platform_peripheral { |
| |
| #define MAX(a,b) (((a) > (b) ? (a) : (b))) |
| |
| #define FAN_CONTROL_PARAMS_FILE "/user/sysmgr/fan_control_params.tbl" |
| |
| /* same as lm96063 spinup setting in barebox. */ |
| const unsigned int FanControl::kPwmDefaultStartup = 50; |
| const unsigned int FanControl::kPwmMinValue = 0; |
| const unsigned int FanControl::kPwmMaxValue = 100; |
| |
| const unsigned int FanControl::kFanSpeedNotSpinning = 0; |
| |
| /* |
| * Fan will start and increase speed at temp_setpt + temp_step + 1 |
| * Fan will start slowing at temp_setpt - temp_step - 1 |
| * In between, it will not change speed. |
| */ |
| |
| /* |
| * Defaults of Fan control parameters for GFMS100 (Bruno-IS) |
| * For GFMS100, Dmin and PWMsetp are used under FMS100_SOC settings. |
| */ |
| const FanControlParams FanControl::kGFMS100FanCtrlSocDefaults = { |
| temp_setpt : 90, |
| temp_max : 100, |
| temp_step : 2, |
| duty_cycle_min: 25, |
| duty_cycle_max: 100, |
| pwm_step : 1, |
| temp_overheat : 120, |
| }; |
| |
| const FanControlParams FanControl::kGFMS100FanCtrlHddDefaults = { |
| temp_setpt : 56, |
| temp_max : 60, |
| temp_step : 2, |
| duty_cycle_min: 25, |
| duty_cycle_max: 100, |
| pwm_step : 1, |
| temp_overheat : 120, |
| }; |
| |
| /* |
| * Defaults of Fan control parameters for GFRG200/210 (optimus/optimus+hdd) |
| * There is no direct SOC temp input, so we use the remote sensor. |
| * Mapping between external temp sensor and actual cpu temp was determined |
| * exterimentally. See b/14666398 spreadsheet attachment. |
| */ |
| const FanControlParams FanControl::kGFRG200FanCtrlSocDefaults = { |
| temp_setpt : 82, // fan on @ 85 (cpu =~ 93) |
| temp_max : 92, // cpu =~ 100 |
| temp_step : 2, |
| duty_cycle_min: 30, |
| duty_cycle_max: 100, |
| pwm_step : 1, |
| temp_overheat : 105, |
| }; |
| |
| const FanControlParams FanControl::kGFRG210FanCtrlSocDefaults = { |
| temp_setpt : 86, // fan on @ 89 (cpu =~ 93) |
| temp_max : 94, // cpu =~ 100 |
| temp_step : 2, |
| duty_cycle_min: 30, |
| duty_cycle_max: 100, |
| pwm_step : 1, |
| temp_overheat : 105, |
| }; |
| |
| const FanControlParams FanControl::kGFRG210FanCtrlHddDefaults = { |
| temp_setpt : 56, |
| temp_max : 60, |
| temp_step : 2, |
| duty_cycle_min: 30, |
| duty_cycle_max: 100, |
| pwm_step : 1, |
| temp_overheat : 105, |
| }; |
| |
| /* |
| * Defaults of Fan control parameters for GFSC100 (Spacecast). |
| * There is no direct SOC temp input, so we use the remote sensor. |
| * Mapping between external temp sensor and actual cpu temp was determined |
| * exterimentally. |
| */ |
| |
| const FanControlParams FanControl::kGFSC100FanCtrlSocDefaults = { |
| temp_setpt : 86, // fan on @ 89 (cpu =~ 93) |
| temp_max : 94, // cpu =~ 100 |
| temp_step : 2, |
| duty_cycle_min: 30, |
| duty_cycle_max: 100, |
| pwm_step : 1, |
| temp_overheat : 105, |
| }; |
| |
| const FanControlParams FanControl::kGFSC100FanCtrlHddDefaults = { |
| temp_setpt : 56, |
| temp_max : 60, |
| temp_step : 2, |
| duty_cycle_min: 30, |
| duty_cycle_max: 100, |
| pwm_step : 1, |
| temp_overheat : 105, |
| }; |
| /* |
| * Defaults of Fan control parameters for GFHD100 (Bruno) |
| * the original duty_cycle_min value is set to 25 |
| * but from the measurement, pwm = 25%, fan duty-cycle |
| * (or fan speed) is 45~50%. |
| * the original duty_cycle_max value is set to 100 |
| * but from the measurement, pwm = 40% or above, fan duty-cycle |
| * (or fan speed) is 99%. pwm is set to any value greater 40 |
| * it will only increase fan speed by less than 1%. |
| * Therefore Dmax is set to 40. |
| */ |
| const FanControlParams FanControl::kGFHD100FanCtrlSocDefaults = { |
| temp_setpt : 90, |
| temp_max : 100, |
| temp_step : 2, |
| duty_cycle_min: 12, |
| duty_cycle_max: 40, |
| pwm_step : 1, |
| temp_overheat : 120, |
| }; |
| |
| const FanControlParams FanControl::kGFHD200FanCtrlSocDefaults = { |
| temp_setpt : 0, /* No fan */ |
| temp_max : 0, |
| temp_step : 0, |
| duty_cycle_min: 0, |
| duty_cycle_max: 0, |
| pwm_step : 0, |
| temp_overheat : 120, |
| }; |
| |
| const FanControlParams FanControl::kGFLT110FanCtrlSocDefaults = { |
| temp_setpt : 0, /* No fan */ |
| temp_max : 0, |
| temp_step : 0, |
| duty_cycle_min: 0, |
| duty_cycle_max: 0, |
| pwm_step : 0, |
| temp_overheat : 97, |
| }; |
| |
| FanControl::~FanControl() { |
| Terminate(); |
| } |
| |
| bool FanControl::Init(bool *gpio_mailbox_ready) { |
| |
| /* Check if the platform instance has been initialized |
| * 1) If run sysmgr, the platformInstance_ would be initalized in |
| * platformperipheral module. |
| * 2) If run test_fan test util, the platformperipheral module won't be used. |
| */ |
| if (platformInstance_ == NULL) { |
| /* The global platform instance is not initialized. Let's handle it. */ |
| LOG(LS_VERBOSE) << "Init platformInstance_ in fancontrol"; |
| platformInstance_ = new Platform ("Unknown Platform", BRUNO_UNKNOWN, |
| false, false); |
| platformInstance_->Init(); |
| allocatedPlatformInstanceLocal_ = true; |
| } |
| |
| InitParams(); |
| |
| if (gpio_mailbox_ready != NULL) { |
| for (int loopno = 4; |
| (*gpio_mailbox_ready == false) && (loopno > 0); loopno--) { |
| sleep(2); |
| *gpio_mailbox_ready = CheckIfMailBoxIsReady(); |
| LOG(LS_VERBOSE) << "loopno=" << loopno; |
| } |
| } |
| |
| /* Get the current fan duty cycle */ |
| if (ReadFanDutyCycle(&duty_cycle_pwm_) == false) { |
| LOG(LS_ERROR) << __func__ << ": failed to get fan duty cycle"; |
| duty_cycle_pwm_ = pfan_ctrl_params_[BRUNO_SOC].duty_cycle_min; |
| } |
| LOG(LS_VERBOSE) << "duty_cycle_pwm_=" << duty_cycle_pwm_; |
| |
| /* Fan pwm has been initialized in nexus init script */ |
| return true; |
| } |
| |
| void FanControl::Terminate(void) { |
| if (pfan_ctrl_params_) { |
| delete [] pfan_ctrl_params_; |
| pfan_ctrl_params_ = NULL; |
| } |
| if ((allocatedPlatformInstanceLocal_ == true) && (platformInstance_)) { |
| delete platformInstance_; |
| platformInstance_ = NULL; |
| } |
| } |
| |
| void FanControl::InitParams() { |
| pfan_ctrl_params_ = new FanControlParams[BRUNO_PARAMS_TYPES]; |
| |
| uint8_t max; |
| switch (platform_ = platformInstance_->PlatformType()) { |
| case BRUNO_GFMS100: |
| /* Set thermal fan policy parameters of GFMS100 */ |
| pfan_ctrl_params_[BRUNO_SOC] = kGFMS100FanCtrlSocDefaults; |
| pfan_ctrl_params_[BRUNO_IS_HDD] = kGFMS100FanCtrlHddDefaults; |
| max = BRUNO_IS_HDD; |
| break; |
| case BRUNO_GFHD100: |
| /* Set thermal fan policy parameters of GFHD100 */ |
| pfan_ctrl_params_[BRUNO_SOC] = kGFHD100FanCtrlSocDefaults; |
| max = BRUNO_SOC; |
| break; |
| case BRUNO_GFHD200: |
| pfan_ctrl_params_[BRUNO_SOC] = kGFHD200FanCtrlSocDefaults; |
| max = BRUNO_SOC; |
| break; |
| case BRUNO_GFRG200: |
| /* Set thermal fan policy parameters of GFRG200 */ |
| pfan_ctrl_params_[BRUNO_SOC] = kGFRG200FanCtrlSocDefaults; |
| max = BRUNO_SOC; |
| break; |
| case BRUNO_GFRG210: |
| /* Set thermal fan policy parameters of GFRG210 */ |
| pfan_ctrl_params_[BRUNO_SOC] = kGFRG210FanCtrlSocDefaults; |
| pfan_ctrl_params_[BRUNO_IS_HDD] = kGFRG210FanCtrlHddDefaults; |
| max = BRUNO_IS_HDD; |
| break; |
| case BRUNO_GFSC100: |
| /* Set thermal fan policy parameters of GFSC100 */ |
| pfan_ctrl_params_[BRUNO_SOC] = kGFSC100FanCtrlSocDefaults; |
| pfan_ctrl_params_[BRUNO_IS_HDD] = kGFSC100FanCtrlHddDefaults; |
| max = BRUNO_IS_HDD; |
| break; |
| case BRUNO_GFLT110: |
| pfan_ctrl_params_[BRUNO_SOC] = kGFLT110FanCtrlSocDefaults; |
| max = BRUNO_SOC; |
| break; |
| default: |
| LOG(LS_ERROR) << "Invalid platform type, ignore ... " << platform_; |
| max = BRUNO_SOC; |
| break; |
| } |
| |
| /* Check if an external fan control parameter table existing */ |
| dbgUpdateFanControlParams(); |
| |
| FanControlParams *pfan_ctrl; |
| uint8_t idx; |
| /* Adjust the fan control parameters for calculation. */ |
| for (idx = 0, pfan_ctrl = pfan_ctrl_params_; idx <= max; idx++, pfan_ctrl++) { |
| LOG(LS_INFO) << platformInstance_->PlatformName() |
| << ((idx == BRUNO_SOC)? "_SOC" : "_HDD") << std::endl |
| << " Tsetpt: " << pfan_ctrl->temp_setpt << std::endl |
| << " Tmax: " << pfan_ctrl->temp_max << std::endl |
| << " Tstep: " << pfan_ctrl->temp_step << std::endl |
| << " Dmin: " << pfan_ctrl->duty_cycle_min << std::endl |
| << " Dmax: " << pfan_ctrl->duty_cycle_max << std::endl |
| << " PWMstep: " << pfan_ctrl->pwm_step << std::endl |
| << " Toverheat: " << pfan_ctrl->temp_overheat << std::endl; |
| } |
| } |
| |
| |
| bool FanControl::AdjustSpeed( |
| uint16_t soc_temp, uint16_t hdd_temp, uint16_t fan_speed) { |
| bool ret = true; |
| uint16_t new_duty_cycle_pwm; |
| |
| LOG(LS_VERBOSE) << __func__ << ": soc_temp=" << soc_temp |
| << " hdd_temp=" << hdd_temp << " fan_speed=" << fan_speed; |
| |
| do { |
| /* Get new SOC PWM per the current SOC and HDD temperatures */ |
| |
| /* Get new duty cycle per SOC and HDD temperatures */ |
| ComputeDutyCycle(soc_temp, hdd_temp, fan_speed, &new_duty_cycle_pwm); |
| |
| LOG(LS_INFO) << __func__ << ": duty_cycle_pwm = " << new_duty_cycle_pwm; |
| if (new_duty_cycle_pwm != duty_cycle_pwm_) { |
| /* When fan is not spinning and new_duty_cycle_pwm > duty_cycle_pwm_, |
| * 1) Set to higher pwm kPwmDefaultStartup for a period of time to |
| * make sure the fan starts spinning |
| * 2) then lower down to new_duty_cycle_pwm |
| */ |
| if (fan_speed == kFanSpeedNotSpinning) { |
| /* Fan is not rotating */ |
| if (new_duty_cycle_pwm > duty_cycle_pwm_) { |
| LOG(LS_INFO) << "Set higher pwm=" << kPwmDefaultStartup; |
| ret = DrivePwm(kPwmDefaultStartup); |
| if (!ret) { |
| LOG(LS_ERROR) << "DrivePwm failed" << kPwmDefaultStartup; |
| break; |
| } |
| /* Sleep before lower pwm down to new_duty_cycle_pwm */ |
| sleep(2); |
| } |
| } |
| |
| ret = DrivePwm(new_duty_cycle_pwm); |
| if (!ret) { |
| LOG(LS_ERROR) << "DrivePwm failed"; |
| break; |
| } |
| } |
| |
| } while (false); |
| |
| return ret; |
| } |
| |
| void FanControl::GetOverheatTemperature(uint16_t *poverheat_temp) { |
| FanControlParams *psoc = &pfan_ctrl_params_[BRUNO_SOC]; |
| *poverheat_temp = psoc->temp_overheat; |
| return; |
| } |
| |
| void FanControl::GetHddTemperature(uint16_t *phdd_temp) { |
| *phdd_temp = 0; |
| uint16_t hdd_temp; |
| |
| if (platformInstance_->PlatformHasHdd() == true) { |
| std::string buf = "hdd-temperature /dev/sda"; |
| /* Create vector to hold hdd temperature words */ |
| std::vector<std::string> tokens; |
| |
| /* Insert the HDD temperature string into a stream */ |
| std::string result = ExecCmd((char *)buf.c_str(), NULL); |
| if ((result == "ERROR") || (result.empty() == true)) { |
| /* Failed to get HDD temperature. Exit */ |
| LOG(LS_ERROR) << "GetHddTemperature: Can't get HDD temperature"; |
| return; |
| } |
| std::istringstream(result) >> hdd_temp; |
| /* LOG(LS_INFO) << "hdd_temp: " << hdd_temp << std::endl; */ |
| *phdd_temp = hdd_temp; |
| } |
| return; |
| } |
| |
| bool FanControl::DrivePwm(uint16_t duty_cycle) { |
| |
| LOG(LS_INFO) << "DrivePwm = " << duty_cycle; |
| duty_cycle_pwm_ = duty_cycle; |
| |
| if (WriteFanDutyCycle(duty_cycle) == false) { |
| LOG(LS_ERROR) << "WriteFanDutyCycle failed"; |
| return false; |
| } |
| |
| if (duty_cycle == 0) { |
| state_ = OFF; |
| } else if (duty_cycle == period_+1) { |
| state_ = FULL_SPEED; |
| } else { |
| state_ = VAR_SPEED; |
| } |
| |
| return true; |
| } |
| |
| |
| void FanControl::ComputeDutyCycle( |
| uint16_t soc_temp, |
| uint16_t hdd_temp, |
| uint16_t fan_speed, |
| uint16_t *new_duty_cycle_pwm) { |
| |
| uint16_t soc_compute_duty_cycle = 0; |
| uint16_t hdd_compute_duty_cycle = 0; |
| FanControlParams *psoc = &pfan_ctrl_params_[BRUNO_SOC]; |
| FanControlParams *phdd = get_hdd_fan_ctrl_parms(); |
| |
| LOG(LS_VERBOSE) << __func__ << " - duty_cycle_pwm_ = " << duty_cycle_pwm_ |
| << " i/p soc_temp=" << soc_temp |
| << " hdd_temp=" << hdd_temp |
| << " fan_speed=" << fan_speed; |
| |
| /* check SOC temps */ |
| if (psoc) { |
| soc_compute_duty_cycle = duty_cycle_pwm_; |
| if (soc_temp > psoc->temp_max) { |
| soc_compute_duty_cycle = psoc->duty_cycle_max; |
| } |
| else if (soc_temp > (psoc->temp_setpt + psoc->temp_step)) { |
| if (fan_speed == kFanSpeedNotSpinning) { |
| soc_compute_duty_cycle = psoc->duty_cycle_min; |
| } |
| else if (duty_cycle_pwm_ < psoc->duty_cycle_max) { |
| /* 1. Possibly, the fan still stops due to duty_cycle_pwm_ is not large |
| * enough. Continue increase the duty cycle. |
| * 2. Or the fan is running, but it's not fast enough to cool down |
| * the unit. |
| */ |
| soc_compute_duty_cycle = duty_cycle_pwm_ + psoc->pwm_step; |
| if (soc_compute_duty_cycle > psoc->duty_cycle_max) |
| soc_compute_duty_cycle = psoc->duty_cycle_max; |
| } |
| } |
| else if (soc_temp < (psoc->temp_setpt - psoc->temp_step)) { |
| if ((fan_speed == kFanSpeedNotSpinning) || |
| (duty_cycle_pwm_ < psoc->pwm_step)) { |
| soc_compute_duty_cycle = kPwmMinValue; |
| } |
| else { |
| /* Reduce fan pwm if soc_temp is lower than |
| * the (temp_setpt - temp_step) and plus fan is still spinning |
| */ |
| soc_compute_duty_cycle = duty_cycle_pwm_ - psoc->pwm_step; |
| } |
| } |
| } |
| |
| /* check HDD temps */ |
| if (phdd) { |
| hdd_compute_duty_cycle = duty_cycle_pwm_; |
| if (if_hdd_temp_over_temp_max(hdd_temp, phdd) == true) { |
| hdd_compute_duty_cycle = phdd->duty_cycle_max; |
| } |
| else if (if_hdd_temp_over_temp_setpt(hdd_temp, phdd) == true) { |
| if (fan_speed == kFanSpeedNotSpinning) { |
| hdd_compute_duty_cycle = phdd->duty_cycle_min; |
| } |
| else if (duty_cycle_pwm_ < phdd->duty_cycle_max) { |
| /* 1. Possibly, the fan still stops due to duty_cycle_pwm_ is not large |
| * enough. Continue increase the duty cycle. |
| * 2. Or the fan is running, but it's not fast enough to cool down |
| * the unit. |
| */ |
| hdd_compute_duty_cycle = duty_cycle_pwm_ + phdd->pwm_step; |
| if (hdd_compute_duty_cycle > phdd->duty_cycle_max) |
| hdd_compute_duty_cycle = phdd->duty_cycle_max; |
| } |
| } |
| else if (if_hdd_temp_lower_than_temp_setpt(hdd_temp, phdd) == true) { |
| if ((fan_speed == kFanSpeedNotSpinning) || |
| (duty_cycle_pwm_ < phdd->pwm_step)) { |
| hdd_compute_duty_cycle = kPwmMinValue; |
| } |
| else { |
| /* Reduce fan pwm if both soc_temp and hdd_temp are lower than |
| * their (temp_setpt - temp_step) and plus fan is still spinning |
| */ |
| hdd_compute_duty_cycle = duty_cycle_pwm_ - phdd->pwm_step; |
| } |
| } |
| } |
| |
| LOG(LS_INFO) << "soc_duty_cycle_pwm = " << soc_compute_duty_cycle << " " |
| << "hdd_duty_cycle_pwm = " << hdd_compute_duty_cycle; |
| |
| *new_duty_cycle_pwm = MAX(soc_compute_duty_cycle, hdd_compute_duty_cycle); |
| |
| LOG(LS_INFO) << "new_duty_cycle_pwm = " << *new_duty_cycle_pwm; |
| |
| return; |
| } |
| |
| |
| std::string FanControl::ExecCmd(char* cmd, std::string *pattern) { |
| char buffer[256]; |
| std::string result = ""; |
| FILE* pipe = popen(cmd, "r"); |
| |
| if (!pipe) { |
| LOG(LS_ERROR) << __func__ << ": ERROR"; |
| return "ERROR"; |
| } |
| |
| while(!feof(pipe)) { |
| if(fgets(buffer, sizeof(buffer), pipe) != NULL) { |
| /* pattern == NULL, read and return all of lines |
| * pattern != NULL, return the line if found the pattern in the line |
| */ |
| if (pattern != NULL) { |
| result = buffer; |
| if (result.compare(0, pattern->size(), *pattern) == 0) { |
| break; /* Found the pattern. Exit. */ |
| } |
| result.clear(); |
| } |
| else { |
| result += buffer; |
| } |
| } |
| } |
| pclose(pipe); |
| |
| return result; |
| } |
| |
| FanControlParams *FanControl::get_hdd_fan_ctrl_parms() { |
| FanControlParams *ptr = NULL; |
| if (platformInstance_->PlatformHasHdd() == true) { |
| ptr = &pfan_ctrl_params_[BRUNO_IS_HDD]; |
| } |
| return ptr; |
| } |
| |
| |
| bool FanControl::if_hdd_temp_over_temp_max(const uint16_t hdd_temp, const FanControlParams *phdd) const { |
| bool ret = false; /* if no hdd params, default is false */ |
| if ((phdd != NULL) && (hdd_temp > phdd->temp_max)) { |
| ret = true; |
| } |
| return ret; |
| } |
| |
| |
| bool FanControl::if_hdd_temp_over_temp_setpt(const uint16_t hdd_temp, const FanControlParams *phdd) const { |
| bool ret = false; /* if no hdd params, default is false */ |
| if ((phdd != NULL) && (hdd_temp > (phdd->temp_setpt + phdd->temp_step))) { |
| ret = true; |
| } |
| return ret; |
| } |
| |
| |
| bool FanControl::if_hdd_temp_lower_than_temp_setpt(const uint16_t hdd_temp, const FanControlParams *phdd) const { |
| bool ret = true; /* if no hdd params, default is true */ |
| if (phdd != NULL) { |
| if (hdd_temp < (phdd->temp_setpt - phdd->temp_step)) { |
| ret = true; |
| } |
| else { |
| ret = false; |
| } |
| } |
| return ret; |
| } |
| |
| |
| void FanControl::dbgUpdateFanControlParams(void) { |
| /* Check if the external fan control parameter table existing */ |
| std::ifstream params_table_file (FAN_CONTROL_PARAMS_FILE); |
| if (params_table_file.is_open()) { |
| LOG(LS_INFO) << FAN_CONTROL_PARAMS_FILE << " existing..."; |
| dbgGetFanControlParamsFromParamsFile(BRUNO_SOC); |
| if (platformInstance_->PlatformHasHdd() == true) { |
| dbgGetFanControlParamsFromParamsFile(BRUNO_IS_HDD); |
| } |
| } |
| } |
| |
| /* A debugging function: Allow hardware engineers to tune the fan |
| * control parameters |
| */ |
| bool FanControl::dbgGetFanControlParamsFromParamsFile(uint8_t fc_idx) { |
| /* Create vector to hold hdd temperature words */ |
| std::vector<std::string> tokens; |
| uint16_t max, min; |
| |
| /* TODO - Use protobuf to parse the fan control parameters. */ |
| |
| /* Get the search platform keyword in the table file: GFMS100_SOC, |
| * GFMS100_HDD... |
| */ |
| std::string buf = platformInstance_->PlatformName(); |
| switch (fc_idx) { |
| case BRUNO_SOC: |
| buf += "_SOC"; |
| break; |
| case BRUNO_IS_HDD: |
| buf += "_HDD"; |
| break; |
| default: |
| buf += "_UNKNOWN"; |
| LOG(LS_WARNING) << "Invalid fc_index: " << fc_idx << std::endl; |
| break; |
| } |
| |
| LOG(LS_INFO) << buf << std::endl; |
| |
| std::string result = platformInstance_->GetLine((char *)FAN_CONTROL_PARAMS_FILE, &buf); |
| if (result.empty() == true) |
| return false; |
| |
| /* Insert the fan control parameters string into a stream */ |
| std::stringstream ss(result); |
| while (ss >> buf) { |
| tokens.push_back(buf); |
| } |
| |
| /* LOG(LS_INFO) << "token.size = " << tokens.size() << std::endl; */ |
| |
| /* Each line in the fan control table must have 7 elements */ |
| if (tokens.size() < 7) { |
| LOG(LS_ERROR) << __func__ << "Incorrect number of params -->" << tokens.size() ; |
| return false; /* Incorrect length. Exit. */ |
| } |
| |
| /* Compare Tsetpt and Tmax */ |
| std::istringstream(tokens.at(1)) >> min; |
| std::istringstream(tokens.at(2)) >> max; |
| if (min > max) { |
| LOG(LS_ERROR) << __func__ << "Incorrect Tsettp: " << min << " and Tmax: " << max; |
| return false; /* Invalid. Exit */ |
| } |
| |
| std::istringstream(tokens.at(4)) >> min; |
| std::istringstream(tokens.at(5)) >> max; |
| if (min > max) { |
| LOG(LS_ERROR) << __func__ << "Dmin: " << min << " and Dmax: " << max; |
| return false; /* Invalid. Exit */ |
| } |
| |
| std::istringstream(tokens.at(1)) >> pfan_ctrl_params_[fc_idx].temp_setpt; |
| std::istringstream(tokens.at(2)) >> pfan_ctrl_params_[fc_idx].temp_max; |
| std::istringstream(tokens.at(3)) >> pfan_ctrl_params_[fc_idx].temp_step; |
| std::istringstream(tokens.at(4)) >> pfan_ctrl_params_[fc_idx].duty_cycle_min; |
| std::istringstream(tokens.at(5)) >> pfan_ctrl_params_[fc_idx].duty_cycle_max; |
| std::istringstream(tokens.at(6)) >> pfan_ctrl_params_[fc_idx].pwm_step; |
| return true; |
| } |
| |
| } // namespace bruno_platform_peripheral |