new power management task for Hex

This commit is contained in:
macphyter 2024-02-10 12:52:06 -07:00 committed by Georges Palauqui
parent da18e05688
commit b4b02f8056
No known key found for this signature in database
GPG Key ID: 1E45F544CE4D04A5
5 changed files with 164 additions and 39 deletions

View File

@ -143,7 +143,6 @@ static esp_err_t smb_read_block(uint8_t command, uint8_t *data, uint8_t len)
}
i2c_master_read_byte(cmd, &data[slave_len - 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);
@ -201,7 +200,6 @@ static int slinear11_2_int(uint16_t value)
// calculate result (mantissa * 2^exponent)
result = mantissa * powf(2.0, exponent);
ESP_LOGI(TAG, "result: %f", result);
return (int)result;
}
@ -267,9 +265,6 @@ static uint16_t int_2_slinear11(int value)
result = ((exponent << 11) & 0xF800) + mantissa;
//ESP_LOGI(TAG, "mantissa: %d, exponent: %d", mantissa, exponent);
//ESP_LOGI(TAG, "result: %04x", result);
return result;
}
@ -306,9 +301,6 @@ static uint16_t float_2_slinear11(float value)
result = (( (~exponent + 1) << 11) & 0xF800) + mantissa;
//ESP_LOGI(TAG, "mantissa: %d, exponent: -%d", mantissa, exponent);
//ESP_LOGI(TAG, "result: %04x", result);
return result;
}
@ -332,8 +324,6 @@ static int ulinear16_2_float(uint16_t value)
exponent = (voutmode & 0x1F);
}
//ESP_LOGI(TAG, "value: %04x", value);
//ESP_LOGI(TAG, "mantissa: %d, exponent: %d", value, exponent);
result = (value * powf(2.0, exponent));
return result;
}
@ -359,7 +349,6 @@ static uint16_t float_2_ulinear16(float value)
}
result = (value / powf(2.0, exponent));
ESP_LOGI(TAG, "result: %04x, exponent: %f", result, exponent);
return result;
}
@ -423,21 +412,22 @@ int TPS546_init(void)
ESP_LOGI(TAG, "-----------VOLTAGE/CURRENT---------------------");
/* Get voltage input (SLINEAR11) */
smb_read_word(PMBUS_READ_VIN, &u16_value);
vin = slinear11_2_float(u16_value);
ESP_LOGI(TAG, "Vin measured: %2.3f V", vin);
//smb_read_word(PMBUS_READ_VIN, &u16_value);
//vin = slinear11_2_float(u16_value);
//ESP_LOGI(TAG, "Vin measured: %2.3f V", vin);
TPS546_get_vin();
/* Get output current (SLINEAR11) */
smb_read_word(PMBUS_READ_IOUT, &u16_value);
iout = slinear11_2_float(u16_value);
ESP_LOGI(TAG, "Iout measured: %2.3f A", iout);
//smb_read_word(PMBUS_READ_IOUT, &u16_value);
//iout = slinear11_2_float(u16_value);
//ESP_LOGI(TAG, "Iout measured: %2.3f A", iout);
TPS546_get_iout();
/* Get voltage output (ULINEAR16) */
// This gets a timeout, don't know why. clock stretching?
// Should take about 91 uS
smb_read_word(PMBUS_READ_VOUT, &u16_value);
vout = ulinear16_2_float(u16_value);
ESP_LOGI(TAG, "Vout measured: %2.3f V", vout);
//smb_read_word(PMBUS_READ_VOUT, &u16_value);
//vout = ulinear16_2_float(u16_value);
//ESP_LOGI(TAG, "Vout measured: %2.3f V", vout);
TPS546_get_vout();
ESP_LOGI(TAG, "-----------TIMING---------------------");
smb_read_word(PMBUS_TON_DELAY, &u16_value);
@ -523,12 +513,16 @@ void TPS546_write_entire_config(void)
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_MAX_OV_FAULT_LIMIT");
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));
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));
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");
@ -565,9 +559,6 @@ void TPS546_write_entire_config(void)
//ESP_LOGI(TAG, "COMPENSATION");
//smb_write_block(PMBUS_COMPENSATION_CONFIG, COMPENSATION_CONFIG, 5);
/* Slave address */
//smb_write_byte(PMBUS_SLAVE_ADDRESS, TPS546_I2CADDR);
/* 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);
@ -582,7 +573,7 @@ void TPS546_write_entire_config(void)
/* store configuration in NVM */
ESP_LOGI(TAG, "---Saving new config---");
//smb_write_byte(PMBUS_STORE_USER_ALL, 0xFF);
smb_write_byte(PMBUS_STORE_USER_ALL, 0x98);
}
@ -628,6 +619,41 @@ int TPS546_get_temperature(void)
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);
ESP_LOGI(TAG, "Got Vin: %2.3f V", vin);
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);
ESP_LOGI(TAG, "Got Iout: %2.3f V", iout);
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);
ESP_LOGI(TAG, "Got Vout: %2.3f V", vout);
return vout;
}
/**
* @brief Sets the core voltage

View File

@ -25,16 +25,18 @@
/* vout voltage */
#define TPS546_INIT_SCALE_LOOP 0xC808 /* 0.125 */
#define TPS546_INIT_VOUT_MAX 5.00 /* V */
#define TPS546_INIT_VOUT_OV_FAULT_LIMIT 1.20 /* V relative to VOUT_COMMAND */
#define TPS546_INIT_VOUT_OV_WARN_LIMIT 0.90 /* V relative to VOUT_COMMAND */
#define TPS546_INIT_VOUT_COMMAND 3.60 /* V absolute value */
#define TPS546_INIT_VOUT_UV_WARN_LIMIT 0.50 /* V relative to VOUT_COMMAND */
#define TPS546_INIT_VOUT_UV_FAULT_LIMIT 0.60 /* V relative to VOUT_COMMAND */
#define TPS546_INIT_VOUT_MIN 3.00 /* v */
#define TPS546_INIT_VOUT_MAX 4.50 /* V */
#define TPS546_INIT_VOUT_OV_FAULT_LIMIT 1.25 /* %/100 above VOUT_COMMAND */
#define TPS546_INIT_VOUT_OV_WARN_LIMIT 1.1 /* %/100 above VOUT_COMMAND */
#define TPS546_INIT_VOUT_MARGIN_HIGH 1.1 /* %/100 above VOUT */
#define TPS546_INIT_VOUT_COMMAND 3.60 /* V absolute value */
#define TPS546_INIT_VOUT_MARGIN_LOW 0.90 /* %/100 below VOUT */
#define TPS546_INIT_VOUT_UV_WARN_LIMIT 0.90 /* %/100 below VOUT_COMMAND */
#define TPS546_INIT_VOUT_UV_FAULT_LIMIT 0.75 /* %/100 below VOUT_COMMAND */
#define TPS546_INIT_VOUT_MIN 2.5 /* v */
/* iout current */
#define TPS546_INIT_IOUT_OC_WARN_LIMIT 25.00 /* A */
#define TPS546_INIT_IOUT_OC_WARN_LIMIT 25.00 /* A */
#define TPS546_INIT_IOUT_OC_FAULT_LIMIT 30.00 /* A */
#define TPS546_INIT_IOUT_OC_FAULT_RESPONSE 0xC0 /* shut down, no retries */
@ -73,6 +75,9 @@ void TPS546_write_entire_config(void);
int TPS546_get_frequency(void);
void TPS546_set_frequency(int);
int TPS546_get_temperature(void);
float TPS546_get_vin(void);
float TPS546_get_iout(void);
float TPS546_get_vout(void);
void TPS546_set_vout(int millivolts);
void TPS546_show_voltage_settings(void);

View File

@ -160,7 +160,17 @@ void app_main(void)
xTaskCreate(USER_INPUT_task, "user input", 8192, (void *) &GLOBAL_STATE, 5, NULL);
if (strcmp(GLOBAL_STATE.board_version, "302") == 0) {
// this is a HEX board
ESP_LOGI(TAG, "Starting HEX power management");
xTaskCreate(POWER_MANAGEMENT_HEX_task, "power mangement", 8192, (void *) &GLOBAL_STATE, 10, NULL);
} else {
// this is NOT a HEX board
ESP_LOGI(TAG, "Starting BITAXE power management");
xTaskCreate(POWER_MANAGEMENT_task, "power mangement", 8192, (void *) &GLOBAL_STATE, 10, NULL);
}
ESP_LOGI(TAG, "Starting init functions");
if (GLOBAL_STATE.ASIC_functions.init_fn != NULL) {
wifi_softap_off();

View File

@ -1,5 +1,7 @@
#include "EMC2101.h"
#include "INA260.h"
#include "TPS546.h"
#include "TMP1075.h"
#include "bm1397.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
@ -16,6 +18,8 @@
#define THROTTLE_TEMP 75.0
#define THROTTLE_TEMP_RANGE (MAX_TEMP - THROTTLE_TEMP)
#define TPS546_THROTTLE_TEMP 105.0
#define VOLTAGE_START_THROTTLE 4900
#define VOLTAGE_MIN_THROTTLE 3500
#define VOLTAGE_RANGE (VOLTAGE_START_THROTTLE - VOLTAGE_MIN_THROTTLE)
@ -56,6 +60,9 @@ static void automatic_fan_speed(float chip_temp, GlobalState * GLOBAL_STATE)
case DEVICE_SUPRA:
EMC2101_set_fan_speed((float) result / 100);
break;
case DEVICE_HEX:
// TODO
break;
default:
}
}
@ -242,3 +249,80 @@ void POWER_MANAGEMENT_task(void * pvParameters)
}
}
void POWER_MANAGEMENT_HEX_task(void * pvParameters)
{
GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters;
PowerManagementModule * power_management = &GLOBAL_STATE->POWER_MANAGEMENT_MODULE;
power_management->frequency_multiplier = 1;
char * board_version = nvs_config_get_string(NVS_CONFIG_BOARD_VERSION, "unknown");
power_management->HAS_POWER_EN =
(strcmp(board_version, "202") == 1 || strcmp(board_version, "203") == 1 || strcmp(board_version, "204") == 1);
power_management->HAS_PLUG_SENSE = strcmp(board_version, "204") == 1;
free(board_version);
int last_frequency_increase = 0;
uint16_t frequency_target = nvs_config_get_u16(NVS_CONFIG_ASIC_FREQ, CONFIG_ASIC_FREQUENCY);
uint16_t auto_fan_speed = nvs_config_get_u16(NVS_CONFIG_AUTO_FAN_SPEED, 1);
// turn on ASIC core voltage (three domains in series)
TPS546_set_vout(3600);
vTaskDelay(3000 / portTICK_PERIOD_MS);
while (1) {
// use TPS546_get_vin() for input voltage
power_management->voltage = TPS546_get_vout();
power_management->current = TPS546_get_iout();
// calculate ASIC power consumed (in milliwatts)
power_management->power = (power_management->voltage * power_management->current) / 1000;
// TODO fix fan driver
//power_management->fan_speed = EMC2101_get_fan_speed();
// Two board temperature sensors
ESP_LOGI(TAG, "Board Temp: %d, %d", TMP1075_read_temperature(0), TMP1075_read_temperature(1));
// get regulator internal temperature
power_management->chip_temp = (float)TPS546_get_temperature();
ESP_LOGI(TAG, "TPS546 Temp: %f", power_management->chip_temp);
// TODO figure out best way to detect overheating on the Hex
if (power_management->chip_temp > TPS546_THROTTLE_TEMP &&
(power_management->frequency_value > 50 || power_management->voltage > 1000)) {
ESP_LOGE(TAG, "OVERHEAT");
// Turn off core voltage
TPS546_set_vout(0);
nvs_config_set_u16(NVS_CONFIG_ASIC_VOLTAGE, 990);
nvs_config_set_u16(NVS_CONFIG_ASIC_FREQ, 50);
nvs_config_set_u16(NVS_CONFIG_FAN_SPEED, 100);
nvs_config_set_u16(NVS_CONFIG_AUTO_FAN_SPEED, 0);
exit(EXIT_FAILURE);
}
// TODO fix fan driver
//if (auto_fan_speed == 1) {
// automatic_fan_speed(power_management->chip_temp);
//} else {
// EMC2101_set_fan_speed((float) nvs_config_get_u16(NVS_CONFIG_FAN_SPEED, 100) / 100);
//}
ESP_LOGI(TAG, "TPS546 VIN: %f, VOUT: %f, IOUT: %f", TPS546_get_vin(), TPS546_get_vout(), TPS546_get_iout());
ESP_LOGI(TAG, "Regulator power: %f mW", power_management->power);
//ESP_LOGI(TAG, "Frequency target %f, Freq %f", target_frequency, power_management->frequency_value);
ESP_LOGI(TAG, "Frequency %d", TPS546_get_frequency());
vTaskDelay(POLL_RATE / portTICK_PERIOD_MS);
}
}

View File

@ -16,5 +16,5 @@ typedef struct
} PowerManagementModule;
void POWER_MANAGEMENT_task(void * pvParameters);
#endif
void POWER_MANAGEMENT_HEX_task(void * pvParameters);
#endif