finish initial config values for first boot

This commit is contained in:
macphyter 2024-01-28 20:41:01 -07:00
parent d9c39fdfb4
commit dc95504d16
2 changed files with 199 additions and 67 deletions

View File

@ -3,13 +3,14 @@
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <string.h>
#include "pmbus_commands.h"
#include "TPS546.h"
#define I2C_MASTER_SCL_IO 48 /*!< GPIO number used for I2C master clock */
#define I2C_MASTER_SDA_IO 47 /*!< GPIO number used for I2C master data */
#define I2C_MASTER_NUM \
#define I2C_MASTER_NUM \
0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
@ -28,6 +29,10 @@
static const char *TAG = "TPS546.c";
static uint8_t DEVICE_ID[] = {0x54, 0x49, 0x54, 0x6B, 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};
/**
* @brief SMBus read byte
@ -47,7 +52,7 @@ static esp_err_t smb_read_byte(uint8_t command, uint8_t *data)
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
i2c_cmd_link_delete(cmd);
// TODO get an actual error status
// return get an actual error status
return err;
}
@ -67,7 +72,7 @@ static esp_err_t smb_write_byte(uint8_t command, uint8_t data)
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
i2c_cmd_link_delete(cmd);
// TODO get an actual error status
// TODO return an actual error status
return err;
}
@ -92,7 +97,7 @@ static esp_err_t smb_read_word(uint8_t command, uint16_t *result)
i2c_cmd_link_delete(cmd);
*result = (data[1] << 8) + data[0];
// TODO get an actual error status
// TODO return an actual error status
return err;
}
@ -113,14 +118,14 @@ static esp_err_t smb_write_word(uint8_t command, uint16_t data)
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
i2c_cmd_link_delete(cmd);
// TODO get an actual error status
// 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)
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);
@ -143,10 +148,31 @@ static esp_err_t smb_read_block(uint8_t command, uint8_t * data, uint8_t len)
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
i2c_cmd_link_delete(cmd);
// TODO get an actual error status
// 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);
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
@ -192,9 +218,6 @@ static uint16_t int_2_slinear11(int value)
ESP_LOGI(TAG, "mantissa: %f, exponent: %d", mantissa, exponent);
result = (mantissa * 1024);
// ESP_LOGI(TAG, "result: %04x", result);
// TPS546.c: Writing new frequency: 550
// TPS546.c: result: 0.537109, exponent: 10
// First 5 bits is exponent in twos-complement
// check the first bit of the exponent to see if its negative
@ -213,8 +236,6 @@ static uint16_t int_2_slinear11(int value)
// mantissa = (value & 0x07FF);
// }
// TPS546.c: Read Freq: 1234
// TPS546.c: result: 2256.000000
// calculate result (mantissa * 2^exponent)
// result = mantissa * powf(2.0, exponent);
@ -273,24 +294,41 @@ static uint16_t int_2_ulinear16(int value)
/*--- Public TPS546 functions ---*/
// Set up the TPS546 regulator and turn it on
void TPS546_init(void)
int TPS546_init(void)
{
uint8_t data[6];
uint8_t u8_value;
uint16_t u16_value;
int i_value;
int millivolts;
int vmax;
float f_value;
int iout;
uint8_t mfr_revision[3];
int temp;
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]);
if (memcmp(data, DEVICE_ID, 6) != 0)
{
ESP_LOGI(TAG, "ERROR- cannot find TPS546 regulator");
return -1;
}
smb_read_byte(PMBUS_REVISION, &u8_value);
ESP_LOGI(TAG, "PMBus revision: %02x", u8_value);
/* Make sure power is turned off until commanded */
ESP_LOGI(TAG, "Setting power config");
u8_value = ON_OFF_CONFIG_CMD | ON_OFF_CONFIG_PU | ON_OFF_CONFIG_CP |
ON_OFF_CONFIG_POLARITY | ON_OFF_CONFIG_DELAY;
smb_write_byte(PMBUS_ON_OFF_CONFIG, u8_value);
/* Read version number and see if it matches */
TPS546_read_mfr_info(mfr_revision);
if (memcmp(mfr_revision, MFR_REVISION, 3) != 0) {
// If it doesn't match, then set the version and write all the registers
ESP_LOGI(TAG, "Config version mismatch, writing new config values");
//TPS546_write_entire_config();
// TODO write new config version here
}
/* Show temperature */
ESP_LOGI(TAG, "--------------------------------");
@ -303,16 +341,6 @@ void TPS546_init(void)
/* Show voltage settings */
TPS546_show_voltage_settings();
/* Test changing value */
// u16_value = int_2_ulinear16(1300);
// smb_write_word(PMBUS_VOUT_MAX, u16_value);
// ESP_LOGI(TAG, "Vout Max changed to 1300");
// smb_read_word(PMBUS_VOUT_MAX, &u16_value);
// ESP_LOGI(TAG, "VOUT_MAX: %04x", u16_value);
// vmax = ulinear16_2_int(u16_value);
// ESP_LOGI(TAG, "Vout Max set to: %d mV", vmax);
ESP_LOGI(TAG, "-----------CURRENT---------------------");
/* Get output current (SLINEAR11) */
smb_read_word(PMBUS_READ_IOUT, &u16_value);
@ -326,6 +354,102 @@ void TPS546_init(void)
// millivolts = ulinear16_2_int(u16_value);
// ESP_LOGI(TAG, "Vout measured: %d mV", millivolts);
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, "--------------------------------------");
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)
{
/* Switch frequency */
smb_write_word(PMBUS_FREQUENCY_SWITCH, int_2_slinear11(TPS546_INIT_FREQUENCY));
/* vin voltage */
smb_write_word(PMBUS_VIN_ON, int_2_slinear11(TPS546_INIT_VIN_ON));
smb_write_word(PMBUS_VIN_OFF, int_2_slinear11(TPS546_INIT_VIN_OFF));
smb_write_word(PMBUS_VIN_UV_WARN_LIMIT, int_2_slinear11(TPS546_INIT_VIN_UV_WARN_LIMIT));
smb_write_word(PMBUS_VIN_OV_FAULT_LIMIT, int_2_slinear11(TPS546_INIT_VIN_OV_FAULT_LIMIT));
smb_write_byte(PMBUS_VIN_OV_FAULT_RESPONSE, TPS546_INIT_VIN_OV_FAULT_RESPONSE);
/* vout voltage */
smb_write_word(PMBUS_VOUT_SCALE_LOOP, TPS546_INIT_SCALE_LOOP); /* no conversion necessary */
smb_write_word(PMBUS_VOUT_MAX, int_2_slinear11(TPS546_INIT_VOUT_MAX));
smb_write_word(PMBUS_VOUT_OV_FAULT_LIMIT, int_2_slinear11(TPS546_INIT_VOUT_OV_FAULT_LIMIT));
smb_write_word(PMBUS_VOUT_OV_WARN_LIMIT, int_2_slinear11(TPS546_INIT_VOUT_OV_WARN_LIMIT));
//TODO enable this someplace smb_write_word(PMBUS_VOUT_COMMAND, int_2_slinear11(TPS546_INIT_VOUT_COMMAND));
smb_write_word(PMBUS_VOUT_UV_WARN_LIMIT, int_2_slinear11(TPS546_INIT_VOUT_UV_WARN_LIMIT));
smb_write_word(PMBUS_VOUT_UV_FAULT_LIMIT, int_2_slinear11(TPS546_INIT_VOUT_UV_FAULT_LIMIT));
smb_write_word(PMBUS_VOUT_MIN, int_2_slinear11(TPS546_INIT_VOUT_MIN));
/* iout current */
smb_write_word(PMBUS_IOUT_OC_WARN_LIMIT, int_2_slinear11(TPS546_INIT_IOUT_OC_WARN_LIMIT));
smb_write_word(PMBUS_IOUT_OC_FAULT_LIMIT, int_2_slinear11(TPS546_INIT_IOUT_OC_FAULT_LIMIT));
smb_write_byte(PMBUS_IOUT_OC_FAULT_RESPONSE, TPS546_INIT_IOUT_OC_FAULT_RESPONSE);
/* temperature */
smb_write_word(PMBUS_OT_WARN_LIMIT, int_2_slinear11(TPS546_INIT_OT_WARN_LIMIT));
smb_write_word(PMBUS_OT_FAULT_LIMIT, int_2_slinear11(TPS546_INIT_OT_FAULT_LIMIT));
smb_write_byte(PMBUS_OT_FAULT_RESPONSE, TPS546_INIT_OT_FAULT_RESPONSE);
/* timing */
smb_write_word(PMBUS_TON_DELAY, int_2_slinear11(TPS546_INIT_TON_DELAY));
smb_write_word(PMBUS_TON_RISE, int_2_slinear11(TPS546_INIT_TON_RISE));
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));
/* store configuration in NVM */
smb_write_byte(PMBUS_STORE_USER_ALL, 0xFF);
}
int TPS546_get_frequency(void)
@ -383,7 +507,6 @@ void TPS546_show_voltage_settings(void)
{
uint16_t u16_value;
int i_value;
float f_value;
int millivolts;
ESP_LOGI(TAG, "-----------VOLTAGE---------------------");

View File

@ -5,54 +5,63 @@
#define TPS546_MANUFACTURER_ID 0xFE //< Manufacturer ID
#define TPS546_REVISION 0xFF //< Chip revision
struct tps546_settings_t
{
int switch_frequency;
/*-------------------------*/
/* These are the inital values for the voltage regulator configuration */
/* when the config revision stored in the TPS546 doesn't match, these values are used */
/* vin voltage */
int vin_on; /* voltage level to start power conversion */
int vin_off; /* voltage level to stop power conversion */
int vin_uv_warn_limit;
int vin_ov_fault_limit;
int vin_ov_fault_response;
#define TPS546_INIT_FREQUENCY 650 /* KHz */
/* vin voltage */
#define TPS546_INIT_VIN_ON 11900 /* mV */
#define TPS546_INIT_VIN_OFF 11000 /* mV */
#define TPS546_INIT_VIN_UV_WARN_LIMIT 11000 /* mV */
#define TPS546_INIT_VIN_OV_FAULT_LIMIT 14000 /* mV */
#define TPS546_INIT_VIN_OV_FAULT_RESPONSE 0xB7 /* retry 6 times */
/* vout voltage */
int vout_transition_rate;
int vout_scale_loop;
int vout_trim;
int vout_max;
int vout_ov_fault_limit;
int vout_ov_warn_limit;
int vout_margin_high;
int vout_command;
int vout_margin_low;
int vout_uv_warn_limit;
int vout_uv_fault_limit;
int vout_min;
#define TPS546_INIT_SCALE_LOOP 0xC808 /* 0.125 */
#define TPS546_INIT_VOUT_MAX 4500 /* mV */
#define TPS546_INIT_VOUT_OV_FAULT_LIMIT 4500 /* mV */
#define TPS546_INIT_VOUT_OV_WARN_LIMIT 4400 /* mV */
#define TPS546_INIT_VOUT_COMMAND 3600 /* mV */
#define TPS546_INIT_VOUT_UV_WARN_LIMIT 3100 /* mV */
#define TPS546_INIT_VOUT_UV_FAULT_LIMIT 3000 /* mV */
#define TPS546_INIT_VOUT_MIN 3000 /* mv */
/* iout current */
int iout_oc_warn_limit;
int iout_oc_fault_limit;
int iout_oc_fault_response;
int iout_cal_gain;
int iout_cal_offset;
#define TPS546_INIT_IOUT_OC_WARN_LIMIT 25000 /* mA */
#define TPS546_INIT_IOUT_OC_FAULT_LIMIT 30000 /* mA */
#define TPS546_INIT_IOUT_OC_FAULT_RESPONSE 0xC0 /* shut down, no retries */
/* temperature */
int ot_warn_limit;
int ot_fault_limit;
int ot_fault_response;
#define TPS546_INIT_OT_WARN_LIMIT 70 /* degrees C */
#define TPS546_INIT_OT_FAULT_LIMIT 80 /* degrees C */
#define TPS546_INIT_OT_FAULT_RESPONSE 0xFF /* wait for cooling, and retry */
/* timing */
int ton_delay;
int ton_rise;
int ton_max_fault_limit;
int ton_max_fault_response;
int toff_delay;
int toff_fall;
#define TPS546_INIT_TON_DELAY 0
#define TPS546_INIT_TON_RISE 3
#define TPS546_INIT_TON_MAX_FAULT_LIMIT 0
#define TPS546_INIT_TON_MAX_FAULT_RESPONSE 0x3B
#define TPS546_INIT_TOFF_DELAY 0
#define TPS546_INIT_TOFF_FALL 0
};
/*-------------------------*/
void TPS546_init(void);
/* PMBUS_ON_OFF_CONFIG initialization values */
#define ON_OFF_CONFIG_PU 0x10 // turn on PU bit
#define ON_OFF_CONFIG_CMD 0x08 // turn on CMD bit
#define ON_OFF_CONFIG_CP 0x00 // turn off CP bit
#define ON_OFF_CONFIG_POLARITY 0x00 // turn off POLARITY bit
#define ON_OFF_CONFIG_DELAY 0x00 // turn off DELAY bit
/* public functions */
int TPS546_init(void);
void TPS546_read_mfr_info(uint8_t *);
void TPS546_set_mfr_info(void);
void TPS546_write_entire_config(void);
int TPS546_get_frequency(void);
void TPS546_set_frequency(int);
int TPS546_get_temperature(void);