Skip to content

Commit

Permalink
finish initial config values for first boot
Browse files Browse the repository at this point in the history
  • Loading branch information
macphyter committed Jan 29, 2024
1 parent d9c39fd commit dc95504
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 67 deletions.
183 changes: 153 additions & 30 deletions main/TPS546.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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
Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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, "--------------------------------");
Expand All @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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---------------------");
Expand Down
Loading

0 comments on commit dc95504

Please sign in to comment.