mirror of
https://github.com/skot/ESP-Miner.git
synced 2025-03-18 13:52:07 +01:00
* port TCH Supra 402 branch * refactor TMP1075 (unused?) driver using i2c_master module * pulled in @Bitmaker-hub stratum_task.c DNS changes from PR #185 * removing serial debug --------- Co-authored-by: Skot <skot@bitnet.cx>
741 lines
23 KiB
C
741 lines
23 KiB
C
#include "driver/i2c.h"
|
|
#include "esp_log.h"
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
|
|
#include "pmbus_commands.h"
|
|
#include "TPS546.h"
|
|
|
|
#define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
|
|
|
|
#define WRITE_BIT I2C_MASTER_WRITE
|
|
#define READ_BIT I2C_MASTER_READ
|
|
#define ACK_CHECK true
|
|
#define NO_ACK_CHECK false
|
|
#define ACK_VALUE 0x0
|
|
#define NACK_VALUE 0x1
|
|
#define MAX_BLOCK_LEN 32
|
|
|
|
#define SMBUS_DEFAULT_TIMEOUT (1000 / portTICK_PERIOD_MS)
|
|
|
|
static const char *TAG = "TPS546.c";
|
|
|
|
static uint8_t DEVICE_ID1[] = {0x54, 0x49, 0x54, 0x6B, 0x24, 0x41};
|
|
static uint8_t DEVICE_ID2[] = {0x54, 0x49, 0x54, 0x6D, 0x24, 0x41};
|
|
static uint8_t MFR_ID[] = {'B', 'A', 'X'};
|
|
static uint8_t MFR_MODEL[] = {'H', 'E', 'X'};
|
|
static uint8_t MFR_REVISION[] = {0x00, 0x00, 0x01};
|
|
|
|
static uint8_t COMPENSATION_CONFIG[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
|
|
|
/**
|
|
* @brief SMBus read byte
|
|
*/
|
|
static esp_err_t smb_read_byte(uint8_t command, uint8_t *data)
|
|
{
|
|
esp_err_t err = ESP_FAIL;
|
|
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, TPS546_I2CADDR << 1 | WRITE_BIT, ACK_CHECK);
|
|
i2c_master_write_byte(cmd, command, ACK_CHECK);
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, TPS546_I2CADDR << 1 | READ_BIT, ACK_CHECK);
|
|
i2c_master_read_byte(cmd, data, NACK_VALUE);
|
|
i2c_master_stop(cmd);
|
|
i2c_set_timeout(I2C_MASTER_NUM, 20);
|
|
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
|
|
i2c_cmd_link_delete(cmd);
|
|
|
|
// return get an actual error status
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* @brief SMBus write byte
|
|
*/
|
|
static esp_err_t smb_write_byte(uint8_t command, uint8_t data)
|
|
{
|
|
esp_err_t err = ESP_FAIL;
|
|
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, TPS546_I2CADDR << 1 | WRITE_BIT, ACK_CHECK);
|
|
i2c_master_write_byte(cmd, command, ACK_CHECK);
|
|
i2c_master_write_byte(cmd, data, ACK_CHECK);
|
|
i2c_master_stop(cmd);
|
|
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
|
|
i2c_cmd_link_delete(cmd);
|
|
|
|
// TODO return an actual error status
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* @brief SMBus read word
|
|
*/
|
|
static esp_err_t smb_read_word(uint8_t command, uint16_t *result)
|
|
{
|
|
uint8_t data[2];
|
|
esp_err_t err = ESP_FAIL;
|
|
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, TPS546_I2CADDR << 1 | WRITE_BIT, ACK_CHECK);
|
|
i2c_master_write_byte(cmd, command, ACK_CHECK);
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, TPS546_I2CADDR << 1 | READ_BIT, ACK_CHECK);
|
|
i2c_master_read(cmd, &data[0], 1, ACK_VALUE);
|
|
i2c_master_read_byte(cmd, &data[1], NACK_VALUE);
|
|
i2c_master_stop(cmd);
|
|
i2c_set_timeout(I2C_MASTER_NUM, 20);
|
|
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
|
|
i2c_cmd_link_delete(cmd);
|
|
|
|
*result = (data[1] << 8) + data[0];
|
|
// TODO return an actual error status
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* @brief SMBus write word
|
|
*/
|
|
static esp_err_t smb_write_word(uint8_t command, uint16_t data)
|
|
{
|
|
esp_err_t err = ESP_FAIL;
|
|
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, TPS546_I2CADDR << 1 | WRITE_BIT, ACK_CHECK);
|
|
i2c_master_write_byte(cmd, command, ACK_CHECK);
|
|
i2c_master_write_byte(cmd, (uint8_t)(data & 0x00FF), ACK_CHECK);
|
|
i2c_master_write_byte(cmd, (uint8_t)((data & 0xFF00) >> 8), NACK_VALUE);
|
|
i2c_master_stop(cmd);
|
|
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
|
|
i2c_cmd_link_delete(cmd);
|
|
|
|
// TODO return an actual error status
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* @brief SMBus read block
|
|
*/
|
|
static esp_err_t smb_read_block(uint8_t command, uint8_t *data, uint8_t len)
|
|
{
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, TPS546_I2CADDR << 1 | WRITE_BIT, ACK_CHECK);
|
|
i2c_master_write_byte(cmd, command, ACK_CHECK);
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, TPS546_I2CADDR << 1 | READ_BIT, ACK_CHECK);
|
|
uint8_t slave_len = 0;
|
|
i2c_master_read_byte(cmd, &slave_len, ACK_VALUE);
|
|
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
|
|
i2c_cmd_link_delete(cmd);
|
|
|
|
cmd = i2c_cmd_link_create();
|
|
for (size_t i = 0; i < slave_len - 1; ++i)
|
|
{
|
|
i2c_master_read_byte(cmd, &data[i], ACK_VALUE);
|
|
}
|
|
i2c_master_read_byte(cmd, &data[slave_len - 1], NACK_VALUE);
|
|
i2c_master_stop(cmd);
|
|
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
|
|
i2c_cmd_link_delete(cmd);
|
|
|
|
// TODO return an actual error status
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief SMBus write block
|
|
*/
|
|
static esp_err_t smb_write_block(uint8_t command, uint8_t *data, uint8_t len)
|
|
{
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, TPS546_I2CADDR << 1 | WRITE_BIT, ACK_CHECK);
|
|
i2c_master_write_byte(cmd, command, ACK_CHECK);
|
|
i2c_master_write_byte(cmd, len, ACK_CHECK);
|
|
for (size_t i = 0; i < len; ++i)
|
|
{
|
|
i2c_master_write_byte(cmd, data[i], ACK_CHECK);
|
|
}
|
|
i2c_master_stop(cmd);
|
|
i2c_set_timeout(I2C_MASTER_NUM, 20);
|
|
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
|
|
i2c_cmd_link_delete(cmd);
|
|
|
|
// TODO return an actual error status
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Convert an SLINEAR11 value into an int
|
|
*/
|
|
static int slinear11_2_int(uint16_t value)
|
|
{
|
|
int exponent, mantissa;
|
|
float result;
|
|
|
|
// First 5 bits is exponent in twos-complement
|
|
// check the first bit of the exponent to see if its negative
|
|
if (value & 0x8000) {
|
|
// exponent is negative
|
|
exponent = -1 * (((~value >> 11) & 0x001F) + 1);
|
|
} else {
|
|
exponent = (value >> 11);
|
|
}
|
|
// last 11 bits is the mantissa in twos-complement
|
|
// check the first bit of the mantissa to see if its negative
|
|
if (value & 0x400) {
|
|
// mantissa is negative
|
|
mantissa = -1 * ((~value & 0x03FF) + 1);
|
|
} else {
|
|
mantissa = (value & 0x03FF);
|
|
}
|
|
|
|
// calculate result (mantissa * 2^exponent)
|
|
result = mantissa * powf(2.0, exponent);
|
|
return (int)result;
|
|
}
|
|
|
|
/**
|
|
* @brief Convert an SLINEAR11 value into an int
|
|
*/
|
|
static float slinear11_2_float(uint16_t value)
|
|
{
|
|
int exponent, mantissa;
|
|
float result;
|
|
|
|
// First 5 bits is exponent in twos-complement
|
|
// check the first bit of the exponent to see if its negative
|
|
if (value & 0x8000) {
|
|
// exponent is negative
|
|
exponent = -1 * (((~value >> 11) & 0x001F) + 1);
|
|
} else {
|
|
exponent = (value >> 11);
|
|
}
|
|
// last 11 bits is the mantissa in twos-complement
|
|
// check the first bit of the mantissa to see if its negative
|
|
if (value & 0x400) {
|
|
// mantissa is negative
|
|
mantissa = -1 * ((~value & 0x03FF) + 1);
|
|
} else {
|
|
mantissa = (value & 0x03FF);
|
|
}
|
|
|
|
// calculate result (mantissa * 2^exponent)
|
|
result = mantissa * powf(2.0, exponent);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @brief Convert an int value into an SLINEAR11
|
|
*/
|
|
static uint16_t int_2_slinear11(int value)
|
|
{
|
|
int mantissa;
|
|
int exponent = 0;
|
|
uint16_t result = 0;
|
|
int i;
|
|
|
|
// First see if the exponent is positive or negative
|
|
if (value >= 0) {
|
|
// exponent is positive
|
|
for (i=0; i<=15; i++) {
|
|
mantissa = value / powf(2.0, i);
|
|
if (mantissa < 1024) {
|
|
exponent = i;
|
|
break;
|
|
}
|
|
}
|
|
if (i == 16) {
|
|
ESP_LOGI(TAG, "Could not find a solution");
|
|
return 0;
|
|
}
|
|
} else {
|
|
// value is negative
|
|
ESP_LOGI(TAG, "No negative numbers at this time");
|
|
return 0;
|
|
}
|
|
|
|
result = ((exponent << 11) & 0xF800) + mantissa;
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @brief Convert a float value into an SLINEAR11
|
|
*/
|
|
static uint16_t float_2_slinear11(float value)
|
|
{
|
|
int mantissa;
|
|
int exponent = 0;
|
|
uint16_t result = 0;
|
|
int i;
|
|
|
|
// First see if the exponent is positive or negative
|
|
if (value > 0) {
|
|
// exponent is negative
|
|
for (i=0; i<=15; i++) {
|
|
mantissa = value * powf(2.0, i);
|
|
if (mantissa >= 1024) {
|
|
exponent = i-1;
|
|
mantissa = value * powf(2.0, exponent);
|
|
break;
|
|
}
|
|
}
|
|
if (i == 16) {
|
|
ESP_LOGI(TAG, "Could not find a solution");
|
|
return 0;
|
|
}
|
|
} else {
|
|
// value is negative
|
|
ESP_LOGI(TAG, "No negative numbers at this time");
|
|
return 0;
|
|
}
|
|
|
|
result = (( (~exponent + 1) << 11) & 0xF800) + mantissa;
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @brief Convert a ULINEAR16 value into a float
|
|
* the exponent comes from the VOUT_MODE bits[4..0]
|
|
* stored in twos-complement
|
|
* The mantissa occupies the full 16-bits of the value
|
|
*/
|
|
static float ulinear16_2_float(uint16_t value)
|
|
{
|
|
uint8_t voutmode;
|
|
int exponent;
|
|
float result;
|
|
|
|
smb_read_byte(PMBUS_VOUT_MODE, &voutmode);
|
|
|
|
if (voutmode & 0x10) {
|
|
// exponent is negative
|
|
exponent = -1 * ((~voutmode & 0x1F) + 1);
|
|
} else {
|
|
exponent = (voutmode & 0x1F);
|
|
}
|
|
result = (value * powf(2.0, exponent));
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @brief Convert a float value into a ULINEAR16
|
|
* the exponent comes from the VOUT_MODE bits[4..0]
|
|
* stored in twos-complement
|
|
* The mantissa occupies the full 16-bits of the result
|
|
**/
|
|
static uint16_t float_2_ulinear16(float value)
|
|
{
|
|
uint8_t voutmode;
|
|
float exponent;
|
|
uint16_t result;
|
|
|
|
smb_read_byte(PMBUS_VOUT_MODE, &voutmode);
|
|
if (voutmode & 0x10) {
|
|
// exponent is negative
|
|
exponent = -1 * ((~voutmode & 0x1F) + 1);
|
|
} else {
|
|
exponent = (voutmode & 0x1F);
|
|
}
|
|
|
|
result = (value / powf(2.0, exponent));
|
|
|
|
return result;
|
|
}
|
|
|
|
/*--- Public TPS546 functions ---*/
|
|
|
|
// Set up the TPS546 regulator and turn it on
|
|
int TPS546_init(void)
|
|
{
|
|
uint8_t data[6];
|
|
uint8_t u8_value;
|
|
uint16_t u16_value;
|
|
float vin;
|
|
float iout;
|
|
float vout;
|
|
uint8_t read_mfr_revision[4];
|
|
int temp;
|
|
uint8_t comp_config[5];
|
|
|
|
ESP_LOGI(TAG, "Initializing the core voltage regulator");
|
|
|
|
/* Establish communication with regulator */
|
|
smb_read_block(PMBUS_IC_DEVICE_ID, data, 6);
|
|
ESP_LOGI(TAG, "Device ID: %02x %02x %02x %02x %02x %02x", data[0], data[1],
|
|
data[2], data[3], data[4], data[5]);
|
|
/* There's two different known device IDs observed so far */
|
|
if ( (memcmp(data, DEVICE_ID1, 6) != 0) && (memcmp(data, DEVICE_ID2, 6) != 0) )
|
|
{
|
|
ESP_LOGI(TAG, "ERROR- cannot find TPS546 regulator");
|
|
return -1;
|
|
}
|
|
|
|
/* Make sure power is turned off until commanded */
|
|
u8_value = ON_OFF_CONFIG_CMD | ON_OFF_CONFIG_PU | ON_OFF_CONFIG_CP |
|
|
ON_OFF_CONFIG_POLARITY | ON_OFF_CONFIG_DELAY;
|
|
ESP_LOGI(TAG, "Power config-ON_OFF_CONFIG: %02x", u8_value);
|
|
smb_write_byte(PMBUS_ON_OFF_CONFIG, u8_value);
|
|
|
|
/* Read version number and see if it matches */
|
|
TPS546_read_mfr_info(read_mfr_revision);
|
|
if (memcmp(read_mfr_revision, MFR_REVISION, 3) != 0) {
|
|
uint8_t voutmode;
|
|
// If it doesn't match, then write all the registers and set new version number
|
|
ESP_LOGI(TAG, "--------------------------------");
|
|
ESP_LOGI(TAG, "Config version mismatch, writing new config values");
|
|
smb_read_byte(PMBUS_VOUT_MODE, &voutmode);
|
|
ESP_LOGI(TAG, "VOUT_MODE: %02x", voutmode);
|
|
TPS546_write_entire_config();
|
|
}
|
|
|
|
/* Show temperature */
|
|
ESP_LOGI(TAG, "--------------------------------");
|
|
ESP_LOGI(TAG, "Temp: %d", TPS546_get_temperature());
|
|
|
|
/* Show switching frequency */
|
|
TPS546_get_frequency();
|
|
TPS546_set_frequency(650);
|
|
|
|
/* Show voltage settings */
|
|
TPS546_show_voltage_settings();
|
|
|
|
ESP_LOGI(TAG, "-----------VOLTAGE/CURRENT---------------------");
|
|
/* Get voltage input (SLINEAR11) */
|
|
TPS546_get_vin();
|
|
/* Get output current (SLINEAR11) */
|
|
TPS546_get_iout();
|
|
/* Get voltage output (ULINEAR16) */
|
|
TPS546_get_vout();
|
|
|
|
ESP_LOGI(TAG, "-----------TIMING---------------------");
|
|
smb_read_word(PMBUS_TON_DELAY, &u16_value);
|
|
temp = slinear11_2_int(u16_value);
|
|
ESP_LOGI(TAG, "TON_DELAY: %d", temp);
|
|
smb_read_word(PMBUS_TON_RISE, &u16_value);
|
|
temp = slinear11_2_int(u16_value);
|
|
ESP_LOGI(TAG, "TON_RISE: %d", temp);
|
|
smb_read_word(PMBUS_TON_MAX_FAULT_LIMIT, &u16_value);
|
|
temp = slinear11_2_int(u16_value);
|
|
ESP_LOGI(TAG, "TON_MAX_FAULT_LIMIT: %d", temp);
|
|
smb_read_byte(PMBUS_TON_MAX_FAULT_RESPONSE, &u8_value);
|
|
ESP_LOGI(TAG, "TON_MAX_FAULT_RESPONSE: %02x", u8_value);
|
|
smb_read_word(PMBUS_TOFF_DELAY, &u16_value);
|
|
temp = slinear11_2_int(u16_value);
|
|
ESP_LOGI(TAG, "TOFF_DELAY: %d", temp);
|
|
smb_read_word(PMBUS_TOFF_FALL, &u16_value);
|
|
temp = slinear11_2_int(u16_value);
|
|
ESP_LOGI(TAG, "TOFF_FALL: %d", temp);
|
|
ESP_LOGI(TAG, "--------------------------------------");
|
|
|
|
// Read the compensation config registers
|
|
smb_read_block(PMBUS_COMPENSATION_CONFIG, comp_config, 5);
|
|
ESP_LOGI(TAG, "COMPENSATION CONFIG");
|
|
ESP_LOGI(TAG, "%02x %02x %02x %02x %02x", comp_config[0], comp_config[1],
|
|
comp_config[2], comp_config[3], comp_config[4]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Read the manufacturer model and revision */
|
|
void TPS546_read_mfr_info(uint8_t *read_mfr_revision)
|
|
{
|
|
uint8_t read_mfr_id[4];
|
|
uint8_t read_mfr_model[4];
|
|
|
|
ESP_LOGI(TAG, "Reading MFR info");
|
|
smb_read_block(PMBUS_MFR_ID, read_mfr_id, 3);
|
|
read_mfr_id[3] = 0x00;
|
|
smb_read_block(PMBUS_MFR_MODEL, read_mfr_model, 3);
|
|
read_mfr_model[3] = 0x00;
|
|
smb_read_block(PMBUS_MFR_REVISION, read_mfr_revision, 3);
|
|
|
|
ESP_LOGI(TAG, "MFR_ID: %s", read_mfr_id);
|
|
ESP_LOGI(TAG, "MFR_MODEL: %s", read_mfr_model);
|
|
ESP_LOGI(TAG, "MFR_REVISION: %d%d%d ", read_mfr_revision[0],
|
|
read_mfr_revision[1], read_mfr_revision[2]);
|
|
}
|
|
|
|
/* Write the manufacturer ID and revision to NVM */
|
|
void TPS546_set_mfr_info(void)
|
|
{
|
|
ESP_LOGI(TAG, "Setting MFR info");
|
|
smb_write_block(PMBUS_MFR_ID, MFR_ID, 3);
|
|
smb_write_block(PMBUS_MFR_MODEL, MFR_MODEL, 3);
|
|
smb_write_block(PMBUS_MFR_REVISION, MFR_REVISION, 3);
|
|
}
|
|
|
|
/* Set all the relevant config registers for normal operation */
|
|
void TPS546_write_entire_config(void)
|
|
{
|
|
ESP_LOGI(TAG, "---Writing new config values to TPS546---");
|
|
/* set up the ON_OFF_CONFIG */
|
|
ESP_LOGI(TAG, "Setting ON_OFF_CONFIG");
|
|
smb_write_byte(PMBUS_ON_OFF_CONFIG, TPS546_INIT_ON_OFF_CONFIG);
|
|
|
|
/* Switch frequency */
|
|
ESP_LOGI(TAG, "Setting FREQUENCY");
|
|
smb_write_word(PMBUS_FREQUENCY_SWITCH, int_2_slinear11(TPS546_INIT_FREQUENCY));
|
|
|
|
/* vin voltage */
|
|
ESP_LOGI(TAG, "Setting VIN");
|
|
smb_write_word(PMBUS_VIN_ON, float_2_slinear11(TPS546_INIT_VIN_ON));
|
|
smb_write_word(PMBUS_VIN_OFF, float_2_slinear11(TPS546_INIT_VIN_OFF));
|
|
smb_write_word(PMBUS_VIN_UV_WARN_LIMIT, float_2_slinear11(TPS546_INIT_VIN_UV_WARN_LIMIT));
|
|
smb_write_word(PMBUS_VIN_OV_FAULT_LIMIT, float_2_slinear11(TPS546_INIT_VIN_OV_FAULT_LIMIT));
|
|
smb_write_byte(PMBUS_VIN_OV_FAULT_RESPONSE, TPS546_INIT_VIN_OV_FAULT_RESPONSE);
|
|
|
|
/* vout voltage */
|
|
ESP_LOGI(TAG, "Setting VOUT SCALE");
|
|
smb_write_word(PMBUS_VOUT_SCALE_LOOP, float_2_slinear11(TPS546_INIT_SCALE_LOOP));
|
|
ESP_LOGI(TAG, "VOUT_COMMAND");
|
|
smb_write_word(PMBUS_VOUT_COMMAND, float_2_ulinear16(TPS546_INIT_VOUT_COMMAND));
|
|
ESP_LOGI(TAG, "VOUT_MAX");
|
|
smb_write_word(PMBUS_VOUT_MAX, float_2_ulinear16(TPS546_INIT_VOUT_MAX));
|
|
ESP_LOGI(TAG, "VOUT_OV_FAULT_LIMIT");
|
|
smb_write_word(PMBUS_VOUT_OV_FAULT_LIMIT, float_2_ulinear16(TPS546_INIT_VOUT_OV_FAULT_LIMIT));
|
|
ESP_LOGI(TAG, "VOUT_OV_WARN_LIMIT");
|
|
smb_write_word(PMBUS_VOUT_OV_WARN_LIMIT, float_2_ulinear16(TPS546_INIT_VOUT_OV_WARN_LIMIT));
|
|
ESP_LOGI(TAG, "VOUT_MARGIN_HIGH");
|
|
smb_write_word(PMBUS_VOUT_MARGIN_HIGH, float_2_ulinear16(TPS546_INIT_VOUT_MARGIN_HIGH));
|
|
ESP_LOGI(TAG, "VOUT_MARGIN_LOW");
|
|
smb_write_word(PMBUS_VOUT_MARGIN_LOW, float_2_ulinear16(TPS546_INIT_VOUT_MARGIN_LOW));
|
|
ESP_LOGI(TAG, "VOUT_UV_WARN_LIMIT");
|
|
smb_write_word(PMBUS_VOUT_UV_WARN_LIMIT, float_2_ulinear16(TPS546_INIT_VOUT_UV_WARN_LIMIT));
|
|
ESP_LOGI(TAG, "VOUT_UV_FAULT_LIMIT");
|
|
smb_write_word(PMBUS_VOUT_UV_FAULT_LIMIT, float_2_ulinear16(TPS546_INIT_VOUT_UV_FAULT_LIMIT));
|
|
ESP_LOGI(TAG, "VOUT_MIN");
|
|
smb_write_word(PMBUS_VOUT_MIN, float_2_ulinear16(TPS546_INIT_VOUT_MIN));
|
|
|
|
/* iout current */
|
|
ESP_LOGI(TAG, "Setting IOUT");
|
|
smb_write_word(PMBUS_IOUT_OC_WARN_LIMIT, float_2_slinear11(TPS546_INIT_IOUT_OC_WARN_LIMIT));
|
|
smb_write_word(PMBUS_IOUT_OC_FAULT_LIMIT, float_2_slinear11(TPS546_INIT_IOUT_OC_FAULT_LIMIT));
|
|
smb_write_byte(PMBUS_IOUT_OC_FAULT_RESPONSE, TPS546_INIT_IOUT_OC_FAULT_RESPONSE);
|
|
|
|
/* temperature */
|
|
ESP_LOGI(TAG, "Setting TEMPERATURE");
|
|
ESP_LOGI(TAG, "OT_WARN_LIMIT");
|
|
smb_write_word(PMBUS_OT_WARN_LIMIT, int_2_slinear11(TPS546_INIT_OT_WARN_LIMIT));
|
|
ESP_LOGI(TAG, "OT_FAULT_LIMIT");
|
|
smb_write_word(PMBUS_OT_FAULT_LIMIT, int_2_slinear11(TPS546_INIT_OT_FAULT_LIMIT));
|
|
ESP_LOGI(TAG, "OT_FAULT_RESPONSE");
|
|
smb_write_byte(PMBUS_OT_FAULT_RESPONSE, TPS546_INIT_OT_FAULT_RESPONSE);
|
|
|
|
/* timing */
|
|
ESP_LOGI(TAG, "Setting TIMING");
|
|
ESP_LOGI(TAG, "TON_DELAY");
|
|
smb_write_word(PMBUS_TON_DELAY, int_2_slinear11(TPS546_INIT_TON_DELAY));
|
|
ESP_LOGI(TAG, "TON_RISE");
|
|
smb_write_word(PMBUS_TON_RISE, int_2_slinear11(TPS546_INIT_TON_RISE));
|
|
ESP_LOGI(TAG, "TON_MAX_FAULT_LIMIT");
|
|
smb_write_word(PMBUS_TON_MAX_FAULT_LIMIT, int_2_slinear11(TPS546_INIT_TON_MAX_FAULT_LIMIT));
|
|
smb_write_byte(PMBUS_TON_MAX_FAULT_RESPONSE, TPS546_INIT_TON_MAX_FAULT_RESPONSE);
|
|
smb_write_word(PMBUS_TOFF_DELAY, int_2_slinear11(TPS546_INIT_TOFF_DELAY));
|
|
smb_write_word(PMBUS_TOFF_FALL, int_2_slinear11(TPS546_INIT_TOFF_FALL));
|
|
|
|
/* Compensation config */
|
|
//ESP_LOGI(TAG, "COMPENSATION");
|
|
//smb_write_block(PMBUS_COMPENSATION_CONFIG, COMPENSATION_CONFIG, 5);
|
|
|
|
/* configure the bootup behavior regarding pin detect values vs NVM values */
|
|
ESP_LOGI(TAG, "Setting PIN_DETECT_OVERRIDE");
|
|
smb_write_word(PMBUS_PIN_DETECT_OVERRIDE, INIT_PIN_DETECT_OVERRIDE);
|
|
|
|
/* TODO write new MFR_REVISION number to reflect these parameters */
|
|
ESP_LOGI(TAG, "Writing MFR ID");
|
|
smb_write_block(PMBUS_MFR_ID, MFR_ID, 3);
|
|
ESP_LOGI(TAG, "Writing MFR MODEL");
|
|
smb_write_block(PMBUS_MFR_ID, MFR_MODEL, 3);
|
|
ESP_LOGI(TAG, "Writing MFR REVISION");
|
|
smb_write_block(PMBUS_MFR_ID, MFR_REVISION, 3);
|
|
|
|
/* store configuration in NVM */
|
|
ESP_LOGI(TAG, "---Saving new config---");
|
|
smb_write_byte(PMBUS_STORE_USER_ALL, 0x98);
|
|
|
|
}
|
|
|
|
int TPS546_get_frequency(void)
|
|
{
|
|
uint16_t value;
|
|
int freq;
|
|
|
|
smb_read_word(PMBUS_FREQUENCY_SWITCH, &value);
|
|
freq = slinear11_2_int(value);
|
|
|
|
return (int)freq;
|
|
}
|
|
|
|
void TPS546_set_frequency(int newfreq)
|
|
{
|
|
uint16_t value;
|
|
int freq;
|
|
|
|
ESP_LOGI(TAG, "Writing new frequency: %d", newfreq);
|
|
value = int_2_slinear11(newfreq);
|
|
//ESP_LOGI(TAG, "New value: 0x%04x", value);
|
|
smb_write_word(PMBUS_FREQUENCY_SWITCH, value);
|
|
|
|
//ESP_LOGI(TAG, "Checking conversion...");
|
|
//freq = slinear11_2_int(value);
|
|
//ESP_LOGI(TAG, "Converted value: %d", freq);
|
|
}
|
|
|
|
int TPS546_get_temperature(void)
|
|
{
|
|
uint16_t value;
|
|
int temp;
|
|
|
|
smb_read_word(PMBUS_READ_TEMPERATURE_1, &value);
|
|
temp = slinear11_2_int(value);
|
|
return temp;
|
|
}
|
|
|
|
float TPS546_get_vin(void)
|
|
{
|
|
uint16_t u16_value;
|
|
float vin;
|
|
|
|
/* Get voltage input (ULINEAR16) */
|
|
smb_read_word(PMBUS_READ_VIN, &u16_value);
|
|
vin = slinear11_2_float(u16_value);
|
|
#ifdef _DEBUG_LOG_
|
|
ESP_LOGI(TAG, "Got Vin: %2.3f V", vin);
|
|
#endif
|
|
return vin;
|
|
}
|
|
|
|
float TPS546_get_iout(void)
|
|
{
|
|
uint16_t u16_value;
|
|
float iout;
|
|
|
|
/* Get current output (SLINEAR11) */
|
|
smb_read_word(PMBUS_READ_IOUT, &u16_value);
|
|
iout = slinear11_2_float(u16_value);
|
|
|
|
#ifdef _DEBUG_LOG_
|
|
ESP_LOGI(TAG, "Got Iout: %2.3f A", iout);
|
|
#endif
|
|
|
|
return iout;
|
|
}
|
|
|
|
float TPS546_get_vout(void)
|
|
{
|
|
uint16_t u16_value;
|
|
float vout;
|
|
|
|
/* Get voltage output (ULINEAR16) */
|
|
smb_read_word(PMBUS_READ_VOUT, &u16_value);
|
|
vout = ulinear16_2_float(u16_value);
|
|
#ifdef _DEBUG_LOG_
|
|
ESP_LOGI(TAG, "Got Vout: %2.3f V", vout);
|
|
#endif
|
|
return vout;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the core voltage
|
|
* this function controls the regulator ontput state
|
|
* send it the desired output in millivolts
|
|
* A value between TPS546_INIT_VOUT_MIN and TPS546_INIT_VOUT_MAX
|
|
* send a 0 to turn off the output
|
|
**/
|
|
void TPS546_set_vout(float volts)
|
|
{
|
|
uint16_t value;
|
|
|
|
if (volts == 0) {
|
|
/* turn off output */
|
|
smb_write_byte(PMBUS_OPERATION, OPERATION_OFF);
|
|
} else {
|
|
/* make sure we're in range */
|
|
if ((volts < TPS546_INIT_VOUT_MIN) || (volts > TPS546_INIT_VOUT_MAX)) {
|
|
ESP_LOGI(TAG, "ERR- Voltage requested (%f V) is out of range", volts);
|
|
} else {
|
|
/* set the output voltage */
|
|
value = float_2_ulinear16(volts);
|
|
smb_write_word(PMBUS_VOUT_COMMAND, value);
|
|
ESP_LOGI(TAG, "Vout changed to %1.2f V", volts);
|
|
|
|
/* turn on output */
|
|
smb_write_byte(PMBUS_OPERATION, OPERATION_ON);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TPS546_show_voltage_settings(void)
|
|
{
|
|
uint16_t u16_value;
|
|
float f_value;
|
|
|
|
ESP_LOGI(TAG, "-----------VOLTAGE---------------------");
|
|
/* VIN_ON SLINEAR11 */
|
|
smb_read_word(PMBUS_VIN_ON, &u16_value);
|
|
f_value = slinear11_2_float(u16_value);
|
|
ESP_LOGI(TAG, "VIN ON set to: %f", f_value);
|
|
|
|
/* VIN_OFF SLINEAR11 */
|
|
smb_read_word(PMBUS_VIN_OFF, &u16_value);
|
|
f_value = slinear11_2_float(u16_value);
|
|
ESP_LOGI(TAG, "VIN OFF set to: %f", f_value);
|
|
|
|
/* VOUT_MAX */
|
|
smb_read_word(PMBUS_VOUT_MAX, &u16_value);
|
|
f_value = ulinear16_2_float(u16_value);
|
|
ESP_LOGI(TAG, "Vout Max set to: %f V", f_value);
|
|
|
|
/* VOUT_OV_FAULT_LIMIT */
|
|
smb_read_word(PMBUS_VOUT_OV_FAULT_LIMIT, &u16_value);
|
|
f_value = ulinear16_2_float(u16_value);
|
|
ESP_LOGI(TAG, "Vout OV Fault Limit: %f V", f_value);
|
|
|
|
/* VOUT_OV_WARN_LIMIT */
|
|
smb_read_word(PMBUS_VOUT_OV_WARN_LIMIT, &u16_value);
|
|
f_value = ulinear16_2_float(u16_value);
|
|
ESP_LOGI(TAG, "Vout OV Warn Limit: %f V", f_value);
|
|
|
|
/* VOUT_MARGIN_HIGH */
|
|
smb_read_word(PMBUS_VOUT_MARGIN_HIGH, &u16_value);
|
|
f_value = ulinear16_2_float(u16_value);
|
|
ESP_LOGI(TAG, "Vout Margin HIGH: %f V", f_value);
|
|
|
|
/* --- VOUT_COMMAND --- */
|
|
smb_read_word(PMBUS_VOUT_COMMAND, &u16_value);
|
|
f_value = ulinear16_2_float(u16_value);
|
|
ESP_LOGI(TAG, "Vout set to: %f V", f_value);
|
|
|
|
/* VOUT_MARGIN_LOW */
|
|
smb_read_word(PMBUS_VOUT_MARGIN_LOW, &u16_value);
|
|
f_value = ulinear16_2_float(u16_value);
|
|
ESP_LOGI(TAG, "Vout Margin LOW: %f V", f_value);
|
|
|
|
/* VOUT_UV_WARN_LIMIT */
|
|
smb_read_word(PMBUS_VOUT_UV_WARN_LIMIT, &u16_value);
|
|
f_value = ulinear16_2_float(u16_value);
|
|
ESP_LOGI(TAG, "Vout UV Warn Limit: %f V", f_value);
|
|
|
|
/* VOUT_UV_FAULT_LIMIT */
|
|
smb_read_word(PMBUS_VOUT_UV_FAULT_LIMIT, &u16_value);
|
|
f_value = ulinear16_2_float(u16_value);
|
|
ESP_LOGI(TAG, "Vout UV Fault Limit: %f V", f_value);
|
|
|
|
/* VOUT_MIN */
|
|
smb_read_word(PMBUS_VOUT_MIN, &u16_value);
|
|
f_value = ulinear16_2_float(u16_value);
|
|
ESP_LOGI(TAG, "Vout Min set to: %f V", f_value);
|
|
}
|
|
|