blob: d6e44ea2320df284e1054b0803e8859e502a7ab8 [file] [log] [blame]
// Copyright 2012 Google Inc. All Rights Reserved.
// Author: kedong@google.com (Ke Dong)
#include "bruno/logging.h"
#include "bruno/thread.h"
#include "fancontrol.h"
#include "peripheralmon.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
namespace bruno_platform_peripheral {
PeripheralMon::~PeripheralMon() {
}
void PeripheralMon::Probe(void) {
bruno_base::TimeStamp now = bruno_base::Time();
float soc_temperature;
uint16_t fan_speed;
std::string soc_voltage;
if (bruno_base::TimeIsLaterOrEqual(next_time_hdd_temp_check_, now)) {
fan_control_->GetHddTemperature(&hdd_temp_);
LOG(LS_INFO) << "hdd_temperature (new):" << hdd_temp_;
next_time_hdd_temp_check_ = bruno_base::TimeAfter(hdd_temp_interval_);
}
if (gpio_mailbox_ready == false)
gpio_mailbox_ready = CheckIfMailBoxIsReady();
if (gpio_mailbox_ready == true) {
ReadFanSpeed(&fan_speed);
bool read_soc_temperature = ReadSocTemperature(&soc_temperature);
ReadSocVoltage(&soc_voltage);
LOG(LS_INFO) << "voltage:" << soc_voltage
<< " soc_temperature:" << soc_temperature
<< " hdd_temperature:" << hdd_temp_
<< " fanspeed:" << fan_speed;
/* If failed to read soc_temperature, don't change PWM
* for both thin bruno and fat bruno
*/
if (read_soc_temperature == true) {
Overheating(soc_temperature);
fan_control_->AdjustSpeed(
static_cast<uint16_t>(soc_temperature),
hdd_temp_,
fan_speed);
} else {
LOG(LS_INFO) << "Not change PWM due to fail to read soc_temperature";
}
} else {
LOG(LS_INFO) << "gpio_mailbox is not ready";
}
last_time_ = now;
mgr_thread_->PostDelayed(interval_, this, static_cast<uint32>(EVENT_TIMEOUT));
}
void PeripheralMon::Overheating(float soc_temperature)
{
std::ostringstream message;
uint16_t overheat_value;
fan_control_->GetOverheatTemperature(&overheat_value);
if (soc_temperature < overheat_value) {
overheating_ = 0;
Common::ClrLED(Common::OVERHEATING, "");
}
else {
overheating_ ++;
if (overheating_ >= OVERHEATING_COUNT) {
message << "System power off: SOC overheating " << overheating_;
LOG(LS_ERROR) << message.str();
Common::ClrLED(Common::OVERHEATING, "");
overheating_ = 0;
Common::Poweroff();
}
else {
message << "SOC overheating detected " << overheating_;
LOG(LS_ERROR) << message.str();
Common::SetLED(Common::OVERHEATING, message.str());
}
}
}
void PeripheralMon::Init(bruno_base::Thread* mgr_thread, unsigned int interval,
unsigned int hdd_temp_interval) {
interval_ = interval;
hdd_temp_interval_ = hdd_temp_interval;
next_time_hdd_temp_check_ = bruno_base::Time(); // = now
overheating_ = 0;
mgr_thread_ = mgr_thread;
fan_control_->Init(&gpio_mailbox_ready);
Probe();
}
void PeripheralMon::OnMessage(bruno_base::Message* msg) {
LOG(LS_VERBOSE) << "Received message " << msg->message_id;
switch (msg->message_id) {
case EVENT_TIMEOUT:
Probe();
break;
default:
LOG(LS_WARNING) << "Invalid message type, ignore ... " << msg->message_id;
break;
}
}
} // namespace bruno_platform_peripheral