common/util/util_pmbus.c (63 lines of code) (raw):

#include <stdint.h> #include "sensor.h" #include "hal_i2c.h" const float slinear11_exponents[32] = { 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, 4096.0, 8192.0, 16384.0, 32768.0, 0.0000152587890625, 0.000030517578125, 0.00006103515625, 0.0001220703125, 0.000244140625, 0.00048828125, 0.0009765625, 0.001953125, 0.00390625, 0.0078125, 0.015625, 0.03125, 0.0625, 0.125, 0.25, 0.5 }; float slinear11_to_float(uint16_t read_value) { uint8_t exponent; int16_t mantissa; float lsb; float ret; exponent = read_value >> 11; mantissa = read_value & 0x07FF; /* Sign extend Mantissa to 16 bits */ if (mantissa > 0x03FF) mantissa |= 0xF800; lsb = slinear11_exponents[exponent]; ret = mantissa * lsb; return ret; } bool get_exponent_from_vout_mode(uint8_t sensor_num, float *exponent) { uint8_t retry = 5; I2C_MSG msg; msg.bus = sensor_config[SensorNum_SensorCfg_map[sensor_num]].port; msg.slave_addr = sensor_config[SensorNum_SensorCfg_map[sensor_num]].slave_addr; msg.tx_len = 1; msg.rx_len = 1; msg.data[0] = PMBUS_VOUT_MODE; if (i2c_master_read(&msg, retry)) return false; *exponent = slinear11_exponents[msg.data[0] & 0x1f]; return true; }