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