blob: 6f315e132f2e0e5c73b04e4c10a62fb7fc4f47bb [file] [log] [blame] [edit]
#include "include/power_rail/max34451_utility.hpp"
#include "include/common_utility.hpp"
#include <nlohmann/json.hpp>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <optional>
#include <string>
namespace max34451
{
void Max34451Logger::loadConfig(std::string_view configFilePath)
{
std::ifstream file(configFilePath.data());
json jsonConfig;
file >> jsonConfig;
auto getValue = [&](const json& source, std::string_view key, auto& dest,
auto parseFunc) {
if (source.contains(key))
{
dest = parseFunc(source[key]);
return true;
}
lg2::info("{KEY} is not defined in the config file", "KEY", key);
return false;
};
if (!(getValue(jsonConfig, kBus, bus, util::parseDec) &&
getValue(jsonConfig, kAddress, address, util::parseHexByte) &&
getValue(jsonConfig, kSource, source,
[](const auto& val) { return val; })))
{
return;
}
if (jsonConfig.contains(kIncludeWarnings))
{
includeWarnings = jsonConfig[kIncludeWarnings];
}
if (jsonConfig.contains(kRegisters))
{
const auto& registers = jsonConfig[kRegisters];
getValue(registers, kMfrChannelConfigReg, mfrChannelConfigReg,
util::parseHexByte);
getValue(registers, kMfrPsenConfigReg, mfrPsenConfigReg,
util::parseHexByte);
getValue(registers, kMfrPwmConfigReg, mfrPwmConfigReg,
util::parseHexByte);
getValue(registers, kMfrNvFaultLogReg, mfrNvFaultLogReg,
util::parseHexByte);
getValue(registers, kMfrNvLogConfigReg, mfrNvLogConfigReg,
util::parseHexByte);
getValue(registers, kStatusWordReg, statusWordReg, util::parseHexByte);
getValue(registers, kStatusCmlReg, statusCmlReg, util::parseHexByte);
getValue(registers, kStatusMfrSpecificReg, statusMfrSpecificReg,
util::parseHexByte);
}
if (jsonConfig.contains(kFaultLogConfig))
{
const auto& faultLogConfig = jsonConfig[kFaultLogConfig];
getValue(faultLogConfig, kCommand, faultLogCommand, util::parseHexByte);
getValue(faultLogConfig, kOffset, faultLogOffset, util::parseDec);
}
if (jsonConfig.contains(kEnableBits))
{
const auto& enableBits = jsonConfig[kEnableBits];
getValue(enableBits, kForceLog, forceLogBit, util::parseDec);
if (enableBits.contains(kClearLog))
{
for (const auto& bit : enableBits[kClearLog])
{
clearLogBits.emplace_back(util::parseDec(bit));
}
}
}
if (jsonConfig.contains(kSequencerRegisters))
{
sequencerRegisters =
jsonConfig[kSequencerRegisters].get<std::vector<json>>();
}
if (jsonConfig.contains(kRailPriority))
{
railPriority =
jsonConfig[kRailPriority].get<std::vector<std::string>>();
}
}
std::vector<uint8_t> getMax34451BB(const Max34451Logger& logger)
{
const uint16_t faultLogSize = 256;
std::vector<uint8_t> command;
command.push_back(logger.faultLogCommand);
std::vector<uint8_t> faultLog = util::i2cWriteRead(
logger.bus, logger.address, command, command.size(), faultLogSize);
if (faultLog.empty())
{
lg2::error("Failed to read fault log from max34451");
return {};
}
if (faultLog[faultLogSize - 2] != 0xdd)
{
lg2::info("max34451 black box is empty!");
return {};
}
return faultLog;
}
void max34451PowerRailParser(const Max34451Logger& logger,
const std::vector<uint8_t>& faultLog,
std::ostream& logFile)
{
for (const auto& seqReg : logger.sequencerRegisters)
{
for (const auto& [page, railName] : seqReg[kPageToPowerRailMap].items())
{
uint8_t pageIndex = util::parseDec(page) + logger.faultLogOffset;
if (checkPowerRailFault(faultLog[pageIndex],
logger.includeWarnings))
{
logFile << " " << railName << "\n";
}
}
}
}
void setMfrNvLogConfig(const Max34451Logger& logger, const uint8_t enableBit)
{
try
{
std::vector<uint8_t> i2cReadBytesResult = util::i2cReadBytes(
logger.bus, logger.address, logger.mfrNvLogConfigReg, 1);
if (i2cReadBytesResult.empty())
{
lg2::error("Failed to read MFR NV Log Config");
return;
}
uint8_t mfrNvLogConfig = i2cReadBytesResult[0];
mfrNvLogConfig |= (1 << enableBit);
util::i2cWriteByte(logger.bus, logger.address, logger.mfrNvLogConfigReg,
mfrNvLogConfig);
}
catch (const std::exception& e)
{
lg2::error("Failed to set MFR NV Log Config: {ERR}", "ERR", e.what());
}
}
void forceMax34451Log(const Max34451Logger& logger)
{
setMfrNvLogConfig(logger, logger.forceLogBit);
usleep(500000);
}
void clearMax34451BB(const Max34451Logger& logger)
{
for (const auto& bit : logger.clearLogBits)
{
setMfrNvLogConfig(logger, bit);
usleep(500000);
}
}
uint16_t getWordAndLog(std::ostream& logFile, const std::vector<uint8_t>& data,
const uint8_t highIndex, const uint8_t lowIndex,
const std::string& label)
{
uint16_t word = (data[highIndex] << 8) | data[lowIndex];
logFile << label << "0x" << std::hex << std::setw(4) << std::setfill('0')
<< word << '\n';
return word;
}
} // namespace max34451