diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index d73f28d3..467b35d9 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -498,15 +498,15 @@ static uint8_t _send_init(uint64_t frequency, uint16_t asic_count) for (uint8_t i = 0; i < chip_counter; i++) { unsigned char set_a8_register[6] = {i * address_interval, 0xA8, 0x00, 0x07, 0x01, 0xF0}; - _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_a8_register, 6, true); + _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_a8_register, 6, false); unsigned char set_18_register[6] = {i * address_interval, 0x18, 0xF0, 0x00, 0xC1, 0x00}; - _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_18_register, 6, true); + _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_18_register, 6, false); unsigned char set_3c_register_first[6] = {i * address_interval, 0x3C, 0x80, 0x00, 0x85, 0x40}; - _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_first, 6, true); + _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_first, 6, false); unsigned char set_3c_register_second[6] = {i * address_interval, 0x3C, 0x80, 0x00, 0x80, 0x20}; - _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_second, 6, true); + _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_second, 6, false); unsigned char set_3c_register_third[6] = {i * address_interval, 0x3C, 0x80, 0x00, 0x82, 0xAA}; - _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_third, 6, true); + _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_third, 6, false); } do_frequency_ramp_up(); diff --git a/components/bm1397/bm1368.c b/components/bm1397/bm1368.c index b2553b61..d03c3469 100644 --- a/components/bm1397/bm1368.c +++ b/components/bm1397/bm1368.c @@ -344,19 +344,19 @@ static uint8_t _send_init(uint64_t frequency, uint16_t asic_count) for (uint8_t i = 0; i < chip_counter; i++) { //Reg_A8 unsigned char set_a8_register[6] = {i * address_interval, 0xA8, 0x00, 0x07, 0x01, 0xF0}; - _send_BM1368((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_a8_register, 6, true); + _send_BM1368((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_a8_register, 6, false); //Misc Control unsigned char set_18_register[6] = {i * address_interval, 0x18, 0xF0, 0x00, 0xC1, 0x00}; - _send_BM1368((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_18_register, 6, true); + _send_BM1368((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_18_register, 6, false); //Core Register Control unsigned char set_3c_register_first[6] = {i * address_interval, 0x3C, 0x80, 0x00, 0x8B, 0x00}; - _send_BM1368((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_first, 6, true); + _send_BM1368((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_first, 6, false); //Core Register Control unsigned char set_3c_register_second[6] = {i * address_interval, 0x3C, 0x80, 0x00, 0x80, 0x18}; - _send_BM1368((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_second, 6, true); + _send_BM1368((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_second, 6, false); //Core Register Control unsigned char set_3c_register_third[6] = {i * address_interval, 0x3C, 0x80, 0x00, 0x82, 0xAA}; - _send_BM1368((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_third, 6, true); + _send_BM1368((TYPE_CMD | GROUP_SINGLE | CMD_WRITE), set_3c_register_third, 6, false); } do_frequency_ramp_up(); diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 84bef2d4..dcf0026e 100755 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -11,6 +11,8 @@ SRCS "nvs_config.c" "oled.c" "system.c" + "TMP1075.c" + "TPS546.c" "vcore.c" "work_queue.c" "./http_server/http_server.c" diff --git a/main/TMP1075.c b/main/TMP1075.c new file mode 100644 index 00000000..63c4b1f6 --- /dev/null +++ b/main/TMP1075.c @@ -0,0 +1,34 @@ +#include +#include "esp_log.h" +#include "i2c_master.h" + +#include "TMP1075.h" + +static const char *TAG = "TMP1075.c"; + +bool TMP1075_installed(int); +uint8_t TMP1075_read_temperature(int); + +bool TMP1075_installed(int device_index) +{ + uint8_t data[2]; + esp_err_t result = ESP_OK; + + // read the configuration register + //ESP_LOGI(TAG, "Reading configuration register"); + ESP_ERROR_CHECK(i2c_master_register_read(TMP1075_I2CADDR_DEFAULT + device_index, TMP1075_CONFIG_REG, data, 2)); + //ESP_LOGI(TAG, "Configuration[%d] = %02X %02X", device_index, data[0], data[1]); + + return (result == ESP_OK?true:false); +} + +uint8_t TMP1075_read_temperature(int device_index) +{ + uint8_t data[2]; + + ESP_ERROR_CHECK(i2c_master_register_read(TMP1075_I2CADDR_DEFAULT + device_index, TMP1075_TEMP_REG, data, 2)); + //ESP_LOGI(TAG, "Raw Temperature = %02X %02X", data[0], data[1]); + //ESP_LOGI(TAG, "Temperature[%d] = %d", device_index, data[0]); + return data[0]; +} + diff --git a/main/TMP1075.h b/main/TMP1075.h new file mode 100644 index 00000000..ff11da74 --- /dev/null +++ b/main/TMP1075.h @@ -0,0 +1,14 @@ +#ifndef TMP1075_H_ +#define TMP1075_H_ + +#define TMP1075_I2CADDR_DEFAULT 0x4A ///< TMP1075 i2c address +#define TMP1075_TEMP_REG 0x00 ///< Temperature register +#define TMP1075_CONFIG_REG 0x01 ///< Configuration register +#define TMP1075_LOW_LIMIT 0x02 ///< Low limit register +#define TMP1075_HIGH_LIMIT 0x03 ///< High limit register +#define TMP1075_DEVICE_ID 0x0F ///< Device ID register + +bool TMP1075_installed(int); +uint8_t TMP1075_read_temperature(int); + +#endif /* TMP1075_H_ */ diff --git a/main/TPS546.c b/main/TPS546.c new file mode 100644 index 00000000..b1995af8 --- /dev/null +++ b/main/TPS546.c @@ -0,0 +1,740 @@ +#include "driver/i2c.h" +#include "esp_log.h" +#include +#include +#include +#include + +#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); +} + diff --git a/main/TPS546.h b/main/TPS546.h new file mode 100644 index 00000000..91e13033 --- /dev/null +++ b/main/TPS546.h @@ -0,0 +1,85 @@ +#ifndef TPS546_H_ +#define TPS546_H_ + +#define TPS546_I2CADDR 0x24 //< TPS546 i2c address +#define TPS546_MANUFACTURER_ID 0xFE //< Manufacturer ID +#define TPS546_REVISION 0xFF //< Chip revision + +/*-------------------------*/ +/* 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 */ + + +#define TPS546_INIT_ON_OFF_CONFIG 0x18 /* use ON_OFF command to control power */ +#define OPERATION_OFF 0x00 +#define OPERATION_ON 0x80 + +#define TPS546_INIT_FREQUENCY 650 /* KHz */ + +/* vin voltage */ +#define TPS546_INIT_VIN_ON 4.8 /* V */ +#define TPS546_INIT_VIN_OFF 4.5 /* V */ +#define TPS546_INIT_VIN_UV_WARN_LIMIT 5.8 /* V */ +#define TPS546_INIT_VIN_OV_FAULT_LIMIT 6.0 /* V */ +#define TPS546_INIT_VIN_OV_FAULT_RESPONSE 0xB7 /* retry 6 times */ + + /* vout voltage */ +#define TPS546_INIT_SCALE_LOOP 0.25 /* Voltage Scale factor */ +#define TPS546_INIT_VOUT_MAX 3 /* 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 1.2 /* 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 1 /* v */ + + /* iout current */ +#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 */ + + /* temperature */ +// It is better to set the temperature warn limit for TPS546 more higher than Ultra +#define TPS546_INIT_OT_WARN_LIMIT 105 /* degrees C */ +#define TPS546_INIT_OT_FAULT_LIMIT 145 /* degrees C */ +#define TPS546_INIT_OT_FAULT_RESPONSE 0xFF /* wait for cooling, and retry */ + + /* timing */ +#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 + +#define INIT_STACK_CONFIG 0x0000 +#define INIT_SYNC_CONFIG 0x0010 +#define INIT_PIN_DETECT_OVERRIDE 0x0000 + +/*-------------------------*/ + +/* 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); +float TPS546_get_vin(void); +float TPS546_get_iout(void); +float TPS546_get_vout(void); +void TPS546_set_vout(float volts); +void TPS546_show_voltage_settings(void); + +#endif /* TPS546_H_ */ diff --git a/main/http_server/axe-os/src/app/components/home/home.component.html b/main/http_server/axe-os/src/app/components/home/home.component.html index b53a3beb..af8206b8 100644 --- a/main/http_server/axe-os/src/app/components/home/home.component.html +++ b/main/http_server/axe-os/src/app/components/home/home.component.html @@ -131,6 +131,15 @@ High Temperature
+ + Voltage Regulator Temperature + +   + Danger: + High Temperature +
+
Fan diff --git a/main/http_server/axe-os/src/app/services/system.service.ts b/main/http_server/axe-os/src/app/services/system.service.ts index 05be0d07..b97997d9 100644 --- a/main/http_server/axe-os/src/app/services/system.service.ts +++ b/main/http_server/axe-os/src/app/services/system.service.ts @@ -26,6 +26,7 @@ export class SystemService { current: 2237.5, fanSpeed: 82, temp: 60, + vrTemp: 45, hashRate: 475, bestDiff: "0", bestSessionDiff: "0", diff --git a/main/http_server/axe-os/src/models/ISystemInfo.ts b/main/http_server/axe-os/src/models/ISystemInfo.ts index 2aeb765f..0abe760f 100644 --- a/main/http_server/axe-os/src/models/ISystemInfo.ts +++ b/main/http_server/axe-os/src/models/ISystemInfo.ts @@ -9,6 +9,7 @@ export interface ISystemInfo { current: number, fanSpeed: number, temp: number, + vrTemp: number, hashRate: number, bestDiff: string, bestSessionDiff: string, diff --git a/main/http_server/http_server.c b/main/http_server/http_server.c index 53cffd3a..560c7485 100644 --- a/main/http_server/http_server.c +++ b/main/http_server/http_server.c @@ -362,6 +362,7 @@ static esp_err_t GET_system_info(httpd_req_t * req) cJSON_AddNumberToObject(root, "current", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.current); cJSON_AddNumberToObject(root, "fanSpeedRpm", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.fan_speed); cJSON_AddNumberToObject(root, "temp", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.chip_temp_avg); + cJSON_AddNumberToObject(root, "vrTemp", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.vr_temp); cJSON_AddNumberToObject(root, "hashRate", GLOBAL_STATE->SYSTEM_MODULE.current_hashrate); cJSON_AddStringToObject(root, "bestDiff", GLOBAL_STATE->SYSTEM_MODULE.best_diff_string); cJSON_AddStringToObject(root, "bestSessionDiff", GLOBAL_STATE->SYSTEM_MODULE.best_session_diff_string); @@ -404,7 +405,7 @@ static esp_err_t GET_system_info(httpd_req_t * req) cJSON_AddNumberToObject(root, "invertfanpolarity", nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1)); cJSON_AddNumberToObject(root, "autofanspeed", nvs_config_get_u16(NVS_CONFIG_AUTO_FAN_SPEED, 1)); - cJSON_AddNumberToObject(root, "fanspeed", nvs_config_get_u16(NVS_CONFIG_FAN_SPEED, 100)); + cJSON_AddNumberToObject(root, "fanspeed", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.fan_percentage); free(ssid); free(hostname); diff --git a/main/pmbus_commands.h b/main/pmbus_commands.h new file mode 100644 index 00000000..8bf074c5 --- /dev/null +++ b/main/pmbus_commands.h @@ -0,0 +1,83 @@ + +/* Standard Core PMBus commands */ +#define PMBUS_OPERATION 0x01 +#define PMBUS_ON_OFF_CONFIG 0x02 +#define PMBUS_CLEAR_FAULTS 0x03 +#define PMBUS_PHASE 0x04 +#define PMBUS_WRITE_PROTECT 0x10 +#define PMBUS_STORE_USER_ALL 0x15 +#define PMBUS_RESTORE_USER_ALL 0x16 +#define PMBUS_CAPABILITY 0x19 +#define PMBUS_SMBALERT_MASK 0x1B +#define PMBUS_VOUT_MODE 0x20 +#define PMBUS_VOUT_COMMAND 0x21 +#define PMBUS_VOUT_TRIM 0x22 +#define PMBUS_VOUT_MAX 0x24 +#define PMBUS_VOUT_MARGIN_HIGH 0x25 +#define PMBUS_VOUT_MARGIN_LOW 0x26 +#define PMBUS_VOUT_TRANSITION_RATE 0x27 +#define PMBUS_VOUT_SCALE_LOOP 0x29 +#define PMBUS_VOUT_MIN 0x2B +#define PMBUS_FREQUENCY_SWITCH 0x33 +#define PMBUS_VIN_ON 0x35 +#define PMBUS_VIN_OFF 0x36 +#define PMBUS_INTERLEAVE 0x37 +#define PMBUS_IOUT_CAL_GAIN 0x38 +#define PMBUS_IOUT_CAL_OFFSET 0x39 +#define PMBUS_VOUT_OV_FAULT_LIMIT 0x40 +#define PMBUS_VOUT_OV_FAULT_RESPONSE 0x41 +#define PMBUS_VOUT_OV_WARN_LIMIT 0x42 +#define PMBUS_VOUT_UV_WARN_LIMIT 0x43 +#define PMBUS_VOUT_UV_FAULT_LIMIT 0x44 +#define PMBUS_VOUT_UV_FAULT_RESPONSE 0x45 +#define PMBUS_IOUT_OC_FAULT_LIMIT 0x46 +#define PMBUS_IOUT_OC_FAULT_RESPONSE 0x47 +#define PMBUS_IOUT_OC_WARN_LIMIT 0x4A +#define PMBUS_OT_FAULT_LIMIT 0x4F +#define PMBUS_OT_FAULT_RESPONSE 0x50 +#define PMBUS_OT_WARN_LIMIT 0x51 +#define PMBUS_VIN_OV_FAULT_LIMIT 0x55 +#define PMBUS_VIN_OV_FAULT_RESPONSE 0x56 +#define PMBUS_VIN_UV_WARN_LIMIT 0x58 +#define PMBUS_TON_DELAY 0x60 +#define PMBUS_TON_RISE 0x61 +#define PMBUS_TON_MAX_FAULT_LIMIT 0x62 +#define PMBUS_TON_MAX_FAULT_RESPONSE 0x63 +#define PMBUS_TOFF_DELAY 0x64 +#define PMBUS_TOFF_FALL 0x65 +#define PMBUS_STATUS_BYTE 0x78 +#define PMBUS_STATUS_WORD 0x79 +#define PMBUS_STATUS_VOUT 0x7A +#define PMBUS_STATUS_IOUT 0x7B +#define PMBUS_STATUS_INPUT 0x7C +#define PMBUS_STATUS_TEMPERATURE 0x7D +#define PMBUS_STATUS_CML 0x7E +#define PMBUS_STATUS_OTHER 0x7F +#define PMBUS_STATUS_MFR_SPECIFIC 0x80 +#define PMBUS_READ_VIN 0x88 +#define PMBUS_READ_VOUT 0x8B +#define PMBUS_READ_IOUT 0x8C +#define PMBUS_READ_TEMPERATURE_1 0x8D +#define PMBUS_REVISION 0x98 +#define PMBUS_MFR_ID 0x99 +#define PMBUS_MFR_MODEL 0x9A +#define PMBUS_MFR_REVISION 0x9B +#define PMBUS_MFR_SERIAL 0x9E +#define PMBUS_IC_DEVICE_ID 0xAD +#define PMBUS_IC_DEVICE_REV 0xAE +#define PMBUS_COMPENSATION_CONFIG 0xB1 +#define PMBUS_POWER_STAGE_CONFIG 0xB5 + +/* Manufacturer Specific PMBUS commands used by the TPS546D24A */ +#define PMBUS_TELEMETRY_CFG 0xD0 +#define PMBUS_READ_ALL 0xDA +#define PMBUS_STATUS_ALL 0xDB +#define PMBUS_SYNC_CONFIG 0xE4 +#define PMBUS_STACK_CONFIG 0xEC +#define PMBUS_MISC_OPTIONS 0xED +#define PMBUS_PIN_DETECT_OVERRIDE 0xEE +#define PMBUS_SLAVE_ADDRESS 0xEF +#define PMBUS_NVM_CHECKSUM 0xF0 +#define PMBUS_SIMULATE_FAULTS 0xF1 +#define PMBUS_FUSION_ID0 0xFC +#define PMBUS_FUSION_ID1 0xFD diff --git a/main/system.c b/main/system.c index 8daf6d86..149a0630 100644 --- a/main/system.c +++ b/main/system.c @@ -5,6 +5,7 @@ #include "i2c_master.h" #include "EMC2101.h" #include "INA260.h" +#include "TMP1075.h" #include "adc.h" #include "connect.h" #include "led_controller.h" diff --git a/main/tasks/power_management_task.c b/main/tasks/power_management_task.c index 42b38055..5233003b 100644 --- a/main/tasks/power_management_task.c +++ b/main/tasks/power_management_task.c @@ -9,6 +9,9 @@ #include "mining.h" #include "nvs_config.h" #include "serial.h" +#include "TMP1075.h" +#include "TPS546.h" +#include "vcore.h" #include #define POLL_RATE 2000 @@ -20,6 +23,9 @@ #define VOLTAGE_MIN_THROTTLE 3500 #define VOLTAGE_RANGE (VOLTAGE_START_THROTTLE - VOLTAGE_MIN_THROTTLE) +#define TPS546_THROTTLE_TEMP 105.0 +#define TPS546_MAX_TEMP 145.0 + static const char * TAG = "power_management"; static float _fbound(float value, float lower_bound, float upper_bound) @@ -34,11 +40,11 @@ static float _fbound(float value, float lower_bound, float upper_bound) // Set the fan speed between 20% min and 100% max based on chip temperature as input. // The fan speed increases from 20% to 100% proportionally to the temperature increase from 50 and THROTTLE_TEMP -static void automatic_fan_speed(float chip_temp, GlobalState * GLOBAL_STATE) +static double automatic_fan_speed(float chip_temp, GlobalState * GLOBAL_STATE) { double result = 0.0; - double min_temp = 50.0; - double min_fan_speed = 20.0; + double min_temp = 45.0; + double min_fan_speed = 35.0; if (chip_temp < min_temp) { result = min_fan_speed; @@ -58,6 +64,7 @@ static void automatic_fan_speed(float chip_temp, GlobalState * GLOBAL_STATE) break; default: } + return result; } void POWER_MANAGEMENT_task(void * pvParameters) @@ -81,26 +88,33 @@ void POWER_MANAGEMENT_task(void * pvParameters) case DEVICE_MAX: case DEVICE_ULTRA: case DEVICE_SUPRA: - // Configure GPIO12 as input(barrel jack) 1 is plugged in - gpio_config_t barrel_jack_conf = { - .pin_bit_mask = (1ULL << GPIO_NUM_12), - .mode = GPIO_MODE_INPUT, - }; - gpio_config(&barrel_jack_conf); - int barrel_jack_plugged_in = gpio_get_level(GPIO_NUM_12); + if (GLOBAL_STATE->board_version != 402) { + // Configure GPIO12 as input(barrel jack) 1 is plugged in + gpio_config_t barrel_jack_conf = { + .pin_bit_mask = (1ULL << GPIO_NUM_12), + .mode = GPIO_MODE_INPUT, + }; + gpio_config(&barrel_jack_conf); + int barrel_jack_plugged_in = gpio_get_level(GPIO_NUM_12); - gpio_set_direction(GPIO_NUM_10, GPIO_MODE_OUTPUT); - if (barrel_jack_plugged_in == 1 || !power_management->HAS_PLUG_SENSE) { - // turn ASIC on - gpio_set_level(GPIO_NUM_10, 0); - } else { - // turn ASIC off - gpio_set_level(GPIO_NUM_10, 1); - } + gpio_set_direction(GPIO_NUM_10, GPIO_MODE_OUTPUT); + if (barrel_jack_plugged_in == 1 || !power_management->HAS_PLUG_SENSE) { + // turn ASIC on + gpio_set_level(GPIO_NUM_10, 0); + } else { + // turn ASIC off + gpio_set_level(GPIO_NUM_10, 1); + } + } break; default: } + if (GLOBAL_STATE->board_version == 402) { + // has already been done in system.c, why do it again here ? + VCORE_set_voltage(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0, GLOBAL_STATE); + } + vTaskDelay(3000 / portTICK_PERIOD_MS); while (1) { @@ -109,11 +123,16 @@ void POWER_MANAGEMENT_task(void * pvParameters) case DEVICE_MAX: case DEVICE_ULTRA: case DEVICE_SUPRA: - if (INA260_installed() == true) { + if (GLOBAL_STATE->board_version == 402) { + power_management->voltage = TPS546_get_vin() * 1000; + power_management->current = TPS546_get_iout() * 1000; + // calculate regulator power (in milliwatts) + power_management->power = (TPS546_get_vout() * power_management->current) / 1000; + } else if (INA260_installed() == true) { power_management->voltage = INA260_read_voltage(); - power_management->power = INA260_read_power() / 1000; power_management->current = INA260_read_current(); - } + power_management->power = INA260_read_power() / 1000; + } power_management->fan_speed = EMC2101_get_fan_speed(); break; default: @@ -192,22 +211,29 @@ void POWER_MANAGEMENT_task(void * pvParameters) case DEVICE_ULTRA: case DEVICE_SUPRA: power_management->chip_temp_avg = EMC2101_get_internal_temp() + 5; + if (GLOBAL_STATE->board_version == 402) { + power_management->vr_temp = (float)TPS546_get_temperature(); + } else { + power_management->vr_temp = 0.0; + } - if (power_management->chip_temp_avg > THROTTLE_TEMP && + if ((power_management->vr_temp > TPS546_THROTTLE_TEMP || power_management->chip_temp_avg > THROTTLE_TEMP) && (power_management->frequency_value > 50 || power_management->voltage > 1000)) { ESP_LOGE(TAG, "OVERHEAT"); EMC2101_set_fan_speed(1); - if (power_management->HAS_POWER_EN) { + if (GLOBAL_STATE->board_version == 402) { + // Turn off core voltage + VCORE_set_voltage(0.0, GLOBAL_STATE); + } else if (power_management->HAS_POWER_EN) { gpio_set_level(GPIO_NUM_10, 1); - } else { - 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); } - } + 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); + } // ESP_LOGI(TAG, "target %f, Freq %f, Volt %f, Power %f", target_frequency, power_management->frequency_value, // power_management->voltage, power_management->power); break; @@ -217,13 +243,14 @@ void POWER_MANAGEMENT_task(void * pvParameters) } if (auto_fan_speed == 1) { - automatic_fan_speed(power_management->chip_temp_avg, GLOBAL_STATE); + power_management->fan_percentage = (float)automatic_fan_speed(power_management->chip_temp_avg, GLOBAL_STATE); } else { switch (GLOBAL_STATE->device_model) { case DEVICE_MAX: case DEVICE_ULTRA: case DEVICE_SUPRA: EMC2101_set_fan_speed((float) nvs_config_get_u16(NVS_CONFIG_FAN_SPEED, 100) / 100); + power_management->fan_percentage = (float)nvs_config_get_u16(NVS_CONFIG_FAN_SPEED, 100); break; default: } diff --git a/main/tasks/power_management_task.h b/main/tasks/power_management_task.h index 18ae4a98..b5a829a5 100644 --- a/main/tasks/power_management_task.h +++ b/main/tasks/power_management_task.h @@ -4,8 +4,10 @@ typedef struct { uint16_t fan_speed; + float fan_percentage; float chip_temp[6]; float chip_temp_avg; + float vr_temp; float voltage; float frequency_multiplier; float frequency_value; diff --git a/main/tasks/stratum_task.c b/main/tasks/stratum_task.c index 95445a68..08363cda 100644 --- a/main/tasks/stratum_task.c +++ b/main/tasks/stratum_task.c @@ -3,10 +3,12 @@ #include "bm1397.h" #include "connect.h" #include "system.h" +#include "global_state.h" #include "lwip/dns.h" #include "nvs_config.h" #include "stratum_task.h" #include "work_queue.h" +#include "esp_wifi.h" #include #include @@ -16,6 +18,8 @@ #define STRATUM_PW CONFIG_STRATUM_PW #define STRATUM_DIFFICULTY CONFIG_STRATUM_DIFFICULTY +#define BASE_DELAY_MS 5000 +#define MAX_RETRY_ATTEMPTS 5 static const char * TAG = "stratum_task"; static ip_addr_t ip_Addr; static bool bDNSFound = false; @@ -27,14 +31,28 @@ static SystemTaskModule SYSTEM_TASK_MODULE = {.stratum_difficulty = 8192}; void dns_found_cb(const char * name, const ip_addr_t * ipaddr, void * callback_arg) { - bDNSFound = true; - if (ipaddr != NULL) { - ip_Addr = *ipaddr; + if ((ipaddr != NULL)){ + ip4_addr_t ip4addr = ipaddr->u_addr.ip4; // Obtener la estructura ip4_addr_t + if (ip4_addr1(&ip4addr) != 0 && ip4_addr2(&ip4addr) != 0 && + ip4_addr3(&ip4addr) != 0 && ip4_addr4(&ip4addr) != 0) { + ESP_LOGI(TAG, "IP found : %d.%d.%d.%d",ip4_addr1(&ip4addr),ip4_addr2(&ip4addr),ip4_addr3(&ip4addr),ip4_addr4(&ip4addr)); + ip_Addr = *ipaddr; + } } else { bDNSInvalid = true; } + bDNSFound = true; } +bool is_wifi_connected() { + wifi_ap_record_t ap_info; + if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) { + return true; + } else { + return false; + } +} + void stratum_task(void * pvParameters) { GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; @@ -43,6 +61,8 @@ void stratum_task(void * pvParameters) char host_ip[20]; int addr_family = 0; int ip_protocol = 0; + int retry_attempts = 0; + int delay_ms = BASE_DELAY_MS; char *stratum_url = GLOBAL_STATE->SYSTEM_MODULE.pool_url; @@ -76,118 +96,136 @@ void stratum_task(void * pvParameters) ip4_addr3(&ip_Addr.u_addr.ip4), ip4_addr4(&ip_Addr.u_addr.ip4)); ESP_LOGI(TAG, "Connecting to: stratum+tcp://%s:%d (%s)", stratum_url, port, host_ip); - - struct sockaddr_in dest_addr; - dest_addr.sin_addr.s_addr = inet_addr(host_ip); - dest_addr.sin_family = AF_INET; - dest_addr.sin_port = htons(port); - addr_family = AF_INET; - ip_protocol = IPPROTO_IP; - - GLOBAL_STATE->sock = socket(addr_family, SOCK_STREAM, ip_protocol); - if (GLOBAL_STATE->sock < 0) { - ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); - ESP_LOGI(TAG, "Restarting System because of ERROR: Unable to create socket"); - vTaskDelay(1000 / portTICK_PERIOD_MS); - esp_restart(); - break; - } - ESP_LOGI(TAG, "Socket created, connecting to %s:%d", host_ip, port); - - int err = connect(GLOBAL_STATE->sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in6)); - if (err != 0) - { - ESP_LOGE(TAG, "Socket unable to connect to %s:%d (errno %d)", stratum_url, port, errno); - // close the socket - shutdown(GLOBAL_STATE->sock, SHUT_RDWR); - close(GLOBAL_STATE->sock); - // instead of restarting, retry this every 5 seconds - vTaskDelay(5000 / portTICK_PERIOD_MS); - continue; - } - - ///// Start Stratum Action - // mining.subscribe - ID: 1 - STRATUM_V1_subscribe(GLOBAL_STATE->sock, GLOBAL_STATE->asic_model_str); - - // mining.configure - ID: 2 - STRATUM_V1_configure_version_rolling(GLOBAL_STATE->sock, &GLOBAL_STATE->version_mask); - - //mining.suggest_difficulty - ID: 3 - STRATUM_V1_suggest_difficulty(GLOBAL_STATE->sock, STRATUM_DIFFICULTY); - - char * username = nvs_config_get_string(NVS_CONFIG_STRATUM_USER, STRATUM_USER); - char * password = nvs_config_get_string(NVS_CONFIG_STRATUM_PASS, STRATUM_PW); - - //mining.authorize - ID: 4 - STRATUM_V1_authenticate(GLOBAL_STATE->sock, username, password); - free(password); - free(username); - while (1) { - char * line = STRATUM_V1_receive_jsonrpc_line(GLOBAL_STATE->sock); - ESP_LOGI(TAG, "rx: %s", line); // debug incoming stratum messages - STRATUM_V1_parse(&stratum_api_v1_message, line); - free(line); + if (!is_wifi_connected()) { + ESP_LOGI(TAG, "WiFi disconnected, attempting to reconnect..."); + esp_wifi_connect(); + vTaskDelay(10000 / portTICK_PERIOD_MS); + //delay_ms *= 2; // Increase delay exponentially + continue; + } - if (stratum_api_v1_message.method == MINING_NOTIFY) { - SYSTEM_notify_new_ntime(GLOBAL_STATE, stratum_api_v1_message.mining_notification->ntime); - if (stratum_api_v1_message.should_abandon_work && - (GLOBAL_STATE->stratum_queue.count > 0 || GLOBAL_STATE->ASIC_jobs_queue.count > 0)) { - ESP_LOGI(TAG, "abandoning work"); + struct sockaddr_in dest_addr; + dest_addr.sin_addr.s_addr = inet_addr(host_ip); + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = htons(port); + addr_family = AF_INET; + ip_protocol = IPPROTO_IP; - GLOBAL_STATE->abandon_work = 1; - queue_clear(&GLOBAL_STATE->stratum_queue); + GLOBAL_STATE->sock = socket(addr_family, SOCK_STREAM, ip_protocol); + if (GLOBAL_STATE->sock < 0) { + ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); + if (++retry_attempts > MAX_RETRY_ATTEMPTS) { + ESP_LOGE(TAG, "Max retry attempts reached, restarting..."); + esp_restart(); + } + vTaskDelay(5000 / portTICK_PERIOD_MS); + continue; + } + ESP_LOGI(TAG, "Socket created, connecting to %s:%d", host_ip, port); + retry_attempts = 0; + int err = connect(GLOBAL_STATE->sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in6)); + if (err != 0) + { + ESP_LOGE(TAG, "Socket unable to connect to %s:%d (errno %d)", stratum_url, port, errno); + // close the socket + shutdown(GLOBAL_STATE->sock, SHUT_RDWR); + close(GLOBAL_STATE->sock); + // instead of restarting, retry this every 5 seconds + vTaskDelay(5000 / portTICK_PERIOD_MS); + continue; + } - pthread_mutex_lock(&GLOBAL_STATE->valid_jobs_lock); - ASIC_jobs_queue_clear(&GLOBAL_STATE->ASIC_jobs_queue); - for (int i = 0; i < 128; i = i + 4) { - GLOBAL_STATE->valid_jobs[i] = 0; + ///// Start Stratum Action + // mining.subscribe - ID: 1 + STRATUM_V1_subscribe(GLOBAL_STATE->sock, GLOBAL_STATE->asic_model_str); + + // mining.configure - ID: 2 + STRATUM_V1_configure_version_rolling(GLOBAL_STATE->sock, &GLOBAL_STATE->version_mask); + + //mining.suggest_difficulty - ID: 3 + STRATUM_V1_suggest_difficulty(GLOBAL_STATE->sock, STRATUM_DIFFICULTY); + + char * username = nvs_config_get_string(NVS_CONFIG_STRATUM_USER, STRATUM_USER); + char * password = nvs_config_get_string(NVS_CONFIG_STRATUM_PASS, STRATUM_PW); + + //mining.authorize - ID: 4 + STRATUM_V1_authenticate(GLOBAL_STATE->sock, username, password); + free(password); + free(username); + + while (1) { + char * line = STRATUM_V1_receive_jsonrpc_line(GLOBAL_STATE->sock); + if (!line) { + ESP_LOGE(TAG, "Failed to receive JSON-RPC line, reconnecting..."); + shutdown(GLOBAL_STATE->sock, SHUT_RDWR); + close(GLOBAL_STATE->sock); + vTaskDelay(1000 / portTICK_PERIOD_MS); // Delay before attempting to reconnect + break; + } + ESP_LOGI(TAG, "rx: %s", line); // debug incoming stratum messages + STRATUM_V1_parse(&stratum_api_v1_message, line); + free(line); + + if (stratum_api_v1_message.method == MINING_NOTIFY) { + SYSTEM_notify_new_ntime(&GLOBAL_STATE->SYSTEM_MODULE, stratum_api_v1_message.mining_notification->ntime); + if (stratum_api_v1_message.should_abandon_work && + (GLOBAL_STATE->stratum_queue.count > 0 || GLOBAL_STATE->ASIC_jobs_queue.count > 0)) { + ESP_LOGI(TAG, "abandoning work"); + + GLOBAL_STATE->abandon_work = 1; + queue_clear(&GLOBAL_STATE->stratum_queue); + + pthread_mutex_lock(&GLOBAL_STATE->valid_jobs_lock); + ASIC_jobs_queue_clear(&GLOBAL_STATE->ASIC_jobs_queue); + for (int i = 0; i < 128; i = i + 4) { + GLOBAL_STATE->valid_jobs[i] = 0; + } + pthread_mutex_unlock(&GLOBAL_STATE->valid_jobs_lock); + } + if (GLOBAL_STATE->stratum_queue.count == QUEUE_SIZE) { + mining_notify * next_notify_json_str = (mining_notify *) queue_dequeue(&GLOBAL_STATE->stratum_queue); + STRATUM_V1_free_mining_notify(next_notify_json_str); } - pthread_mutex_unlock(&GLOBAL_STATE->valid_jobs_lock); - } - if (GLOBAL_STATE->stratum_queue.count == QUEUE_SIZE) { - mining_notify * next_notify_json_str = (mining_notify *) queue_dequeue(&GLOBAL_STATE->stratum_queue); - STRATUM_V1_free_mining_notify(next_notify_json_str); - } - stratum_api_v1_message.mining_notification->difficulty = SYSTEM_TASK_MODULE.stratum_difficulty; - queue_enqueue(&GLOBAL_STATE->stratum_queue, stratum_api_v1_message.mining_notification); - } else if (stratum_api_v1_message.method == MINING_SET_DIFFICULTY) { - if (stratum_api_v1_message.new_difficulty != SYSTEM_TASK_MODULE.stratum_difficulty) { - SYSTEM_TASK_MODULE.stratum_difficulty = stratum_api_v1_message.new_difficulty; - ESP_LOGI(TAG, "Set stratum difficulty: %ld", SYSTEM_TASK_MODULE.stratum_difficulty); - } - } else if (stratum_api_v1_message.method == MINING_SET_VERSION_MASK || - stratum_api_v1_message.method == .0) { - // 1fffe000 - ESP_LOGI(TAG, "Set version mask: %08lx", stratum_api_v1_message.version_mask); - GLOBAL_STATE->version_mask = stratum_api_v1_message.version_mask; - } else if (stratum_api_v1_message.method == STRATUM_RESULT_SUBSCRIBE) { - GLOBAL_STATE->extranonce_str = stratum_api_v1_message.extranonce_str; - GLOBAL_STATE->extranonce_2_len = stratum_api_v1_message.extranonce_2_len; - } else if (stratum_api_v1_message.method == STRATUM_RESULT) { - if (stratum_api_v1_message.response_success) { - ESP_LOGI(TAG, "message result accepted"); - SYSTEM_notify_accepted_share(GLOBAL_STATE); - } else { - ESP_LOGE(TAG, "message result rejected"); - SYSTEM_notify_rejected_share(GLOBAL_STATE); - } - } else if (stratum_api_v1_message.method == STRATUM_RESULT_SETUP) { - if (stratum_api_v1_message.response_success) { - ESP_LOGI(TAG, "setup message accepted"); - } else { - ESP_LOGE(TAG, "setup message rejected"); + stratum_api_v1_message.mining_notification->difficulty = SYSTEM_TASK_MODULE.stratum_difficulty; + queue_enqueue(&GLOBAL_STATE->stratum_queue, stratum_api_v1_message.mining_notification); + } else if (stratum_api_v1_message.method == MINING_SET_DIFFICULTY) { + if (stratum_api_v1_message.new_difficulty != SYSTEM_TASK_MODULE.stratum_difficulty) { + SYSTEM_TASK_MODULE.stratum_difficulty = stratum_api_v1_message.new_difficulty; + ESP_LOGI(TAG, "Set stratum difficulty: %ld", SYSTEM_TASK_MODULE.stratum_difficulty); + } + } else if (stratum_api_v1_message.method == MINING_SET_VERSION_MASK || + stratum_api_v1_message.method == .0) { + // 1fffe000 + ESP_LOGI(TAG, "Set version mask: %08lx", stratum_api_v1_message.version_mask); + GLOBAL_STATE->version_mask = stratum_api_v1_message.version_mask; + } else if (stratum_api_v1_message.method == STRATUM_RESULT_SUBSCRIBE) { + GLOBAL_STATE->extranonce_str = stratum_api_v1_message.extranonce_str; + GLOBAL_STATE->extranonce_2_len = stratum_api_v1_message.extranonce_2_len; + } else if (stratum_api_v1_message.method == STRATUM_RESULT) { + if (stratum_api_v1_message.response_success) { + ESP_LOGI(TAG, "message result accepted"); + SYSTEM_notify_accepted_share(&GLOBAL_STATE->SYSTEM_MODULE); + } else { + ESP_LOGE(TAG, "message result rejected"); + SYSTEM_notify_rejected_share(&GLOBAL_STATE->SYSTEM_MODULE); + } + } else if (stratum_api_v1_message.method == STRATUM_RESULT_SETUP) { + if (stratum_api_v1_message.response_success) { + ESP_LOGI(TAG, "setup message accepted"); + } else { + ESP_LOGE(TAG, "setup message rejected"); + } } } - } - if (GLOBAL_STATE->sock != -1) { - ESP_LOGE(TAG, "Shutting down socket and restarting..."); - shutdown(GLOBAL_STATE->sock, 0); - close(GLOBAL_STATE->sock); + if (GLOBAL_STATE->sock != -1) { + ESP_LOGE(TAG, "Shutting down socket and restarting..."); + shutdown(GLOBAL_STATE->sock, 0); + close(GLOBAL_STATE->sock); + } } } vTaskDelete(NULL); -} +} \ No newline at end of file diff --git a/main/vcore.c b/main/vcore.c index c2ff5a73..7c48354c 100644 --- a/main/vcore.c +++ b/main/vcore.c @@ -5,6 +5,7 @@ #include "vcore.h" #include "adc.h" #include "DS4432U.h" +#include "TPS546.h" #define TPS40305_VFB 0.6 @@ -21,6 +22,9 @@ static const char *TAG = "vcore.c"; void VCORE_init(GlobalState * global_state) { + if (global_state->board_version == 402) { + TPS546_init(); + } ADC_init(); } @@ -54,15 +58,18 @@ static uint8_t ds4432_tps40305_bitaxe_voltage_to_reg(float vout) bool VCORE_set_voltage(float core_voltage, GlobalState * global_state) { - uint8_t reg_setting; - switch (global_state->device_model) { case DEVICE_MAX: case DEVICE_ULTRA: case DEVICE_SUPRA: - reg_setting = ds4432_tps40305_bitaxe_voltage_to_reg(core_voltage * global_state->voltage_domain); - ESP_LOGI(TAG, "Set ASIC voltage = %.3fV [0x%02X]", core_voltage, reg_setting); - DS4432U_set_current_code(0, reg_setting); /// eek! + if (global_state->board_version == 402) { + ESP_LOGI(TAG, "Set ASIC voltage = %.3fV", core_voltage); + TPS546_set_vout(core_voltage * (float)global_state->voltage_domain); + } else { + uint8_t reg_setting = ds4432_tps40305_bitaxe_voltage_to_reg(core_voltage * (float)global_state->voltage_domain); + ESP_LOGI(TAG, "Set ASIC voltage = %.3fV [0x%02X]", core_voltage, reg_setting); + DS4432U_set_current_code(0, reg_setting); /// eek! + } break; // case DEVICE_HEX: default: