sane makefile, sane structure, lots of updates
This commit is contained in:
94
src/LCDDisplay.cpp
Normal file
94
src/LCDDisplay.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "LCDDisplay.hpp"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
/* lcd size hardcoded to 4x40 idgaf */
|
||||
LCDDisplay::LCDDisplay(std::string dev, uint32_t baud) {
|
||||
std::cout << "[LCDDisplay] Opening LCD at " << dev << std::endl;
|
||||
struct termios term;
|
||||
int lcd = open(dev.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
|
||||
// handle errors
|
||||
if (lcd < 0) {
|
||||
std::cerr << "[LCDDisplay] Error opening serial port " << dev << std::endl;
|
||||
exit(lcd);
|
||||
}
|
||||
|
||||
// Setup the serial port 8 data bits, no parity ,1 stopbit, no flow control
|
||||
term.c_cflag = baud | CS8 | CSTOPB | CLOCAL | CREAD;
|
||||
term.c_iflag = 0;
|
||||
term.c_oflag = 0;
|
||||
term.c_lflag = 0;
|
||||
tcflush(lcd, TCIFLUSH);
|
||||
tcsetattr(lcd, TCSANOW, &term);
|
||||
_lcd = lcd;
|
||||
}
|
||||
|
||||
LCDDisplay::~LCDDisplay() {
|
||||
std::cout << "[LCDDisplay] Closing LCD port" << std::endl;
|
||||
close(_lcd);
|
||||
}
|
||||
|
||||
void LCDDisplay::clear() {
|
||||
uint8_t cmdbuf[] = {254, 88};
|
||||
write(_lcd, cmdbuf, 2);
|
||||
}
|
||||
|
||||
void LCDDisplay::setContrast(uint8_t contrast) {
|
||||
std::cout << "[LCDDisplay] Set contrast to " << std::to_string(contrast) << std::endl;
|
||||
uint8_t cmdbuf[] = {254, 80, contrast};
|
||||
write(_lcd, cmdbuf, 3);
|
||||
}
|
||||
|
||||
void LCDDisplay::setBacklight(bool enabled) {
|
||||
std::cout << "[LCDDisplay] Backlight set to " << std::to_string(enabled) << std::endl;
|
||||
uint8_t cmdbuf[] = {254, (uint8_t)(enabled ? 66 : 70), 255};
|
||||
write(_lcd, cmdbuf, enabled ? 3 : 2);
|
||||
}
|
||||
|
||||
void LCDDisplay::setCursor(uint8_t row, uint8_t col) {
|
||||
uint8_t cmdbuf[] = {254, 71, (uint8_t)(col + 1), (uint8_t)(row + 1)};
|
||||
write(_lcd, cmdbuf, 4);
|
||||
}
|
||||
|
||||
void LCDDisplay::writeStr(std::string str) {
|
||||
write(_lcd, str.c_str(), str.size());
|
||||
}
|
||||
|
||||
void LCDDisplay::writeLines(std::array<std::string, 4> lines) {
|
||||
for (auto& line : lines) {
|
||||
if(line.size() > 40) {
|
||||
std::cerr << "Line " << line << " too long! (" << line.size() << " chars)" << std::endl;
|
||||
continue;
|
||||
}
|
||||
line.insert(line.end(), 40 - line.size(), ' ');
|
||||
}
|
||||
|
||||
setCursor(0, 0);
|
||||
writeStr(lines[0] + lines[1]);
|
||||
setCursor(2, 0);
|
||||
writeStr(lines[2] + lines[3]);
|
||||
}
|
||||
|
||||
void LCDDisplay::writeSStream(std::stringstream& ss) {
|
||||
std::string s = ss.str();
|
||||
if (s.size() != 160)
|
||||
std::cerr << "[LCDDisplay] stringstream wrong (" + std::to_string((int)(160 - s.size())) + " chars too short)" << std::endl;
|
||||
setCursor(0, 0);
|
||||
writeStr(s.substr(0, 80));
|
||||
setCursor(2, 0);
|
||||
writeStr(s.substr(80, 159));
|
||||
}
|
||||
|
||||
void LCDDisplay::setCustomChar(uint8_t index, std::array<uint8_t, 8> cchar) {
|
||||
uint8_t cmdbuf[11];
|
||||
cmdbuf[0] = 254; cmdbuf[1] = 78; cmdbuf[2] = index;
|
||||
for(uint8_t i = 0; i < 8; i++)
|
||||
cmdbuf[i+3] = cchar[i];
|
||||
write(_lcd, cmdbuf, 11);
|
||||
}
|
||||
151
src/gpu.cpp
Normal file
151
src/gpu.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <gpu.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <utils.hpp>
|
||||
|
||||
struct GpuMetricsHeader_t {
|
||||
uint16_t structure_size;
|
||||
uint8_t format_revision;
|
||||
uint8_t content_revision;
|
||||
};
|
||||
|
||||
struct GpuMetrics_v1_1_t {
|
||||
uint16_t temperature_edge;
|
||||
uint16_t temperature_hotspot;
|
||||
uint16_t temperature_mem;
|
||||
uint16_t temperature_vrgfx;
|
||||
uint16_t temperature_vrsoc;
|
||||
uint16_t temperature_vrmem;
|
||||
uint16_t average_gfx_activity;
|
||||
uint16_t average_umc_activity;
|
||||
uint16_t average_mm_activity;
|
||||
uint16_t average_socket_power;
|
||||
uint64_t energy_accumulator;
|
||||
uint64_t system_clock_counter;
|
||||
uint16_t average_gfxclk_frequency;
|
||||
uint16_t average_socclk_frequency;
|
||||
uint16_t average_uclk_frequency;
|
||||
uint16_t average_vclk0_frequency;
|
||||
uint16_t average_dclk0_frequency;
|
||||
uint16_t average_vclk1_frequency;
|
||||
uint16_t average_dclk1_frequency;
|
||||
uint16_t current_gfxclk;
|
||||
uint16_t current_socclk;
|
||||
uint16_t current_uclk;
|
||||
uint16_t current_vclk0;
|
||||
uint16_t current_dclk0;
|
||||
uint16_t current_vclk1;
|
||||
uint16_t current_dclk1;
|
||||
uint32_t throttle_status;
|
||||
uint16_t current_fan_speed;
|
||||
uint16_t pcie_link_width;
|
||||
uint16_t pcie_link_speed;
|
||||
uint16_t padding;
|
||||
uint32_t gfx_activity_acc;
|
||||
uint32_t mem_activity_acc;
|
||||
uint16_t temperature_hbm;
|
||||
};
|
||||
|
||||
struct GpuMetrics_v1_3_t {
|
||||
uint16_t temperature_edge;
|
||||
uint16_t temperature_hotspot;
|
||||
uint16_t temperature_mem;
|
||||
uint16_t temperature_vrgfx;
|
||||
uint16_t temperature_vrsoc;
|
||||
uint16_t temperature_vrmem;
|
||||
uint16_t average_gfx_activity;
|
||||
uint16_t average_umc_activity;
|
||||
uint16_t average_mm_activity;
|
||||
uint16_t average_socket_power;
|
||||
uint64_t energy_accumulator;
|
||||
uint64_t system_clock_counter;
|
||||
uint16_t average_gfxclk_frequency;
|
||||
uint16_t average_socclk_frequency;
|
||||
uint16_t average_uclk_frequency;
|
||||
uint16_t average_vclk0_frequency;
|
||||
uint16_t average_dclk0_frequency;
|
||||
uint16_t average_vclk1_frequency;
|
||||
uint16_t average_dclk1_frequency;
|
||||
uint16_t current_gfxclk;
|
||||
uint16_t current_socclk;
|
||||
uint16_t current_uclk;
|
||||
uint16_t current_vclk0;
|
||||
uint16_t current_dclk0;
|
||||
uint16_t current_vclk1;
|
||||
uint16_t current_dclk1;
|
||||
uint32_t throttle_status;
|
||||
uint16_t current_fan_speed;
|
||||
uint16_t pcie_link_width;
|
||||
uint16_t pcie_link_speed;
|
||||
uint16_t padding;
|
||||
uint32_t gfx_activity_acc;
|
||||
uint32_t mem_activity_acc;
|
||||
uint16_t temperature_hbm;
|
||||
uint64_t firmware_timestamp;
|
||||
uint16_t voltage_soc;
|
||||
uint16_t voltage_gfx;
|
||||
uint16_t voltage_mem;
|
||||
uint8_t padding1;
|
||||
};
|
||||
|
||||
GpuMetricsHeader_t getGpuMetricsRev(std::string path) {
|
||||
GpuMetricsHeader_t header;
|
||||
std::ifstream f(path, std::ios::binary);
|
||||
if (f.good()) {
|
||||
f.read(reinterpret_cast<char *>(&header), sizeof(header));
|
||||
std::cout << "[GpuMetrics] Read GpuMetrics format v" << std::to_string(header.format_revision) << "_" << std::to_string(header.content_revision);
|
||||
std::cout << ", size " << std::to_string(header.structure_size) << std::endl;
|
||||
f.close();
|
||||
} else {
|
||||
std::cerr << "[GpuMetrics] Error reading gpu metrics header" << std::endl;
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
auto getGpuMetrics(GpuMetricsHeader_t h, std::string path) {
|
||||
GpuMetrics_v1_3_t metrics;
|
||||
if (h.format_revision == 1 && h.content_revision == 3) {
|
||||
std::ifstream f(path, std::ios::binary);
|
||||
if (f.good()) {
|
||||
f.ignore(sizeof(h)); // skip header
|
||||
f.read(reinterpret_cast<char *>(&metrics), sizeof(metrics));
|
||||
f.close();
|
||||
}
|
||||
} else {
|
||||
std::cout << "[GpuMetrics] read failed, unsupported format" << std::endl;
|
||||
}
|
||||
|
||||
return metrics;
|
||||
}
|
||||
|
||||
// clean abstraction of gpu_metrics + extra metrics from fs
|
||||
gpu_t getGpu(std::string hw) {
|
||||
gpu_t gpu;
|
||||
auto h = getGpuMetricsRev(hw + "/gpu_metrics");
|
||||
auto metrics = getGpuMetrics(h, hw + "/gpu_metrics");
|
||||
|
||||
// we want as much data as posible from gpu_metrics so we dont read filesystem as much
|
||||
gpu.fan_speed = std::stol(readFile(hw + "/hwmon/hwmon2/fan1_input"));
|
||||
gpu.core_clock = metrics.average_vclk1_frequency; // why not gfxclock?
|
||||
gpu.mem_clock = metrics.average_gfxclk_frequency; // why gfxclock? min mem clock seems to be 96mhz, this is probably including time sleeping
|
||||
gpu.vcore = std::stod(readFile(hw + "/hwmon/hwmon2/in0_input")) / 1000.0;
|
||||
gpu.power_avg = metrics.average_socket_power;
|
||||
gpu.power_cap = std::stol(readFile(hw + "/hwmon/hwmon2/power1_cap", 6));
|
||||
gpu.power_max = std::stol(readFile(hw + "/hwmon/hwmon2/power1_cap_max", 6));
|
||||
// gpu.fan_pwm = std::stoi(readFile(hw + "/hwmon/hwmon2/pwm1")); // not super useful
|
||||
gpu.edge_temp = metrics.temperature_edge;
|
||||
gpu.hotspot_temp = metrics.temperature_hotspot;
|
||||
gpu.mem_temp = metrics.temperature_mem;
|
||||
gpu.gfx_vrm_temp = metrics.temperature_vrgfx;
|
||||
gpu.soc_vrm_temp = metrics.temperature_vrsoc;
|
||||
gpu.mem_vrm_temp = metrics.temperature_vrmem;
|
||||
gpu.vram_used = std::stoul(readFile(hw + "/mem_info_vram_used"));
|
||||
gpu.vram_total = std::stoul(readFile(hw + "/mem_info_vram_total"));
|
||||
gpu.core_usage = metrics.average_gfx_activity;
|
||||
gpu.media_usage = metrics.average_mm_activity;
|
||||
gpu.umc_usage = metrics.average_umc_activity;
|
||||
return gpu;
|
||||
}
|
||||
44
src/utils.cpp
Normal file
44
src/utils.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utils.hpp>
|
||||
|
||||
/* SENSOR GETTERS + UTILS*/
|
||||
std::string readFile(std::string path, uint8_t trim) {
|
||||
std::string ret;
|
||||
std::stringstream ss;
|
||||
std::ifstream fs(path);
|
||||
if (!fs.good()) {
|
||||
std::cerr << "Error reading " << path << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
ss << fs.rdbuf();
|
||||
fs.close();
|
||||
ret = ss.str();
|
||||
if (ret.size() < trim) return ret;
|
||||
return ret.substr(0, ret.size() - trim - 1);
|
||||
}
|
||||
|
||||
int get_val(const std::string &target, const std::string &content) {
|
||||
int result = -1;
|
||||
std::size_t start = content.find(target);
|
||||
if (start != std::string::npos) {
|
||||
int begin = start + target.length();
|
||||
std::size_t end = content.find("kB", start);
|
||||
std::string substr = content.substr(begin, end - begin);
|
||||
result = std::stoi(substr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string findHwmonPath(std::string module) {
|
||||
uint8_t id = 0;
|
||||
for (; id < 10; id++)
|
||||
if (readFile("/sys/class/hwmon/hwmon" + std::to_string(id) + "/name") == module) {
|
||||
std::cout << ("[Hwmon] Detected " + module + " path is " + "/sys/class/hwmon/hwmon" + std::to_string(id)) << std::endl;
|
||||
return "/sys/class/hwmon/hwmon" + std::to_string(id);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
Reference in New Issue
Block a user