Skip to content

Commit

Permalink
decode VOUT_COMMAND and TEMPERATURE
Browse files Browse the repository at this point in the history
  • Loading branch information
macphyter committed Jan 21, 2024
1 parent e5b7f80 commit ecac56f
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 18 deletions.
2 changes: 2 additions & 0 deletions main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ SRCS
"adc.c"
"DS4432U.c"
"EMC2101.c"
"EMC2302.c"
"TPS546.c"
"fonts.c"
"INA260.c"
"led_controller.c"
Expand Down
22 changes: 11 additions & 11 deletions main/EMC2302.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,17 @@
*/
typedef enum
{
EMC2101_RATE_1_16_HZ, ///< 1_16_HZ
EMC2101_RATE_1_8_HZ, ///< 1_8_HZ
EMC2101_RATE_1_4_HZ, ///< 1_4_HZ
EMC2101_RATE_1_2_HZ, ///< 1_2_HZ
EMC2101_RATE_1_HZ, ///< 1_HZ
EMC2101_RATE_2_HZ, ///< 2_HZ
EMC2101_RATE_4_HZ, ///< 4_HZ
EMC2101_RATE_8_HZ, ///< 8_HZ
EMC2101_RATE_16_HZ, ///< 16_HZ
EMC2101_RATE_32_HZ, ///< 32_HZ
} emc2101_rate_t;
EMC2302_RATE_1_16_HZ, ///< 1_16_HZ
EMC2302_RATE_1_8_HZ, ///< 1_8_HZ
EMC2302_RATE_1_4_HZ, ///< 1_4_HZ
EMC2302_RATE_1_2_HZ, ///< 1_2_HZ
EMC2302_RATE_1_HZ, ///< 1_HZ
EMC2302_RATE_2_HZ, ///< 2_HZ
EMC2302_RATE_4_HZ, ///< 4_HZ
EMC2302_RATE_8_HZ, ///< 8_HZ
EMC2302_RATE_16_HZ, ///< 16_HZ
EMC2302_RATE_32_HZ, ///< 32_HZ
} emc2302_rate_t;

void EMC2302_init(bool);
void EMC2302_set_fan_speed(uint8_t, float);
Expand Down
184 changes: 184 additions & 0 deletions main/TPS546.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#include "driver/i2c.h"
#include "esp_log.h"
#include <stdio.h>
#include <stdint.h>
#include <math.h>

#include "pmbus_commands.h"
#include "TPS546.h"

#define I2C_MASTER_SCL_IO 48 /*!< GPIO number used for I2C master clock */
#define I2C_MASTER_SDA_IO 47 /*!< GPIO number used for I2C master data */
#define I2C_MASTER_NUM \
0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_TIMEOUT_MS 1000

#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";


/**
* @brief SMBus read byte
*/
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);
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, SMBUS_DEFAULT_TIMEOUT));
i2c_cmd_link_delete(cmd);

return err;
}

/**
* @brief SMBus read word
*/
esp_err_t smb_read_word(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(cmd, &data[0], 1, ACK_VALUE);
i2c_master_read_byte(cmd, &data[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);

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);

return 0;
}


/**
* @brief Read a sequence of I2C bytes
*/
static esp_err_t register_read(uint8_t reg_addr, uint8_t * data, size_t len)
{
return i2c_master_write_read_device(I2C_MASTER_NUM, TPS546_I2CADDR, &reg_addr, 1, data, len,
I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}

/**
* @brief Write a byte to a I2C register
*/
static esp_err_t register_write_byte(uint8_t reg_addr, uint8_t data)
{
int ret;
uint8_t write_buf[2] = {reg_addr, data};

ret = i2c_master_write_to_device(I2C_MASTER_NUM, TPS546_I2CADDR, write_buf, sizeof(write_buf),
I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);

return ret;
}

// Set up the TPS546 regulator and turn it on
void TPS546_init(void)
{
uint8_t data[6];
uint8_t u8_value;
uint16_t u16_value;
float temp;
int mantissa, exponent;

ESP_LOGI(TAG, "Initializing the core voltage 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]);

smb_read_byte(PMBUS_REVISION, &u8_value);
ESP_LOGI(TAG, "PMBus revision: %02x", u8_value);

/* Get temperature (SLINEAR11) */
ESP_LOGI(TAG, "--------------------------------");
smb_read_word(PMBUS_READ_TEMPERATURE_1, data);
u16_value = (data[1] << 8) + data[0];
ESP_LOGI(TAG, "Temperature raw: %04x", u16_value);
if (u16_value & 0x400) {
// mantissa is negative
mantissa = -1 * ((~u16_value & 0x07FF) + 1);
} else {
mantissa = (u16_value & 0x07FF);
}
if (u16_value & 0x8000) {
// exponent is negative
exponent = -1 * (((~u16_value >> 11) & 0x001F) + 1);
} else {
exponent = (u16_value >> 11);
}
ESP_LOGI(TAG, "exp: %04x, mant: %04x", exponent, mantissa);
temp = mantissa * powf(2.0, exponent);
ESP_LOGI(TAG, "Temp: %2.1f", temp);

/* Get voltage setting (ULINEAR16) */
ESP_LOGI(TAG, "--------------------------------");
smb_read_byte(PMBUS_VOUT_MODE, &u8_value);
//ESP_LOGI(TAG, "VOUT mode: %02x", u8_value);
float mode_exponent = -1 * ((~u8_value & 0x1F) + 1);
//ESP_LOGI(TAG, "mode_exponent: %f", mode_exponent);

smb_read_word(PMBUS_VOUT_COMMAND, data);
u16_value = (data[1] << 8) + data[0];
//ESP_LOGI(TAG, "VOUT: %d", u16_value);
float scaler = powf(2.0, mode_exponent);
//ESP_LOGI(TAG, "scaler: %f", scaler);
int voltage = (u16_value * scaler) * 1000;
ESP_LOGI(TAG, "Vout: %d mV", voltage);

}


13 changes: 13 additions & 0 deletions main/TPS546.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#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


void TPS546_init(void);
//void TPS546_set_voltage(float);
//void TPS546_get_status(void);

#endif /* TPS546_H_ */
9 changes: 8 additions & 1 deletion main/global_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@

#define STRATUM_USER CONFIG_STRATUM_USER

/* Use platform ID to decide which drivers to use */
#define PLATFORM_BITAXE 0x01
#define PLATFORM_ULTRA 0x02
#define PLATFORM_HEX 0x03

typedef struct
{
void (*init_fn)(u_int64_t);
Expand All @@ -24,6 +29,8 @@ typedef struct

typedef struct
{
int platform_id;

char * asic_model;
AsicFunctions ASIC_functions;
double asic_job_frequency_ms;
Expand All @@ -50,4 +57,4 @@ typedef struct

} GlobalState;

#endif /* GLOBAL_STATE_H_ */
#endif /* GLOBAL_STATE_H_ */
6 changes: 6 additions & 0 deletions main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());

/* we need to populate the platform_id here, but it doesn't exist in NVS yet */
/* TODO read the platform ID from the NVS */
/* TODO bitaxetool will need to be modified to include it */
/* use hard-coded value for now */
GLOBAL_STATE.platform_id = PLATFORM_HEX;

ESP_LOGI(TAG, "NVS_CONFIG_ASIC_FREQ %f", (float) nvs_config_get_u16(NVS_CONFIG_ASIC_FREQ, CONFIG_ASIC_FREQUENCY));
GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value = nvs_config_get_u16(NVS_CONFIG_ASIC_FREQ, CONFIG_ASIC_FREQUENCY);

Expand Down
2 changes: 1 addition & 1 deletion main/pmbus_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
#define PMBUS_READ_VOUT 0x8B
#define PMBUS_READ_IOUT 0x8C
#define PMBUS_READ_TEMPERATURE_1 0x8D
#define PMBUS_PMBUS_REVISION 0x98
#define PMBUS_REVISION 0x98
#define PMBUS_MFR_ID 0x99
#define PMBUS_MFR_MODEL 0x9A
#define PMBUS_MFR_REVISION 0x9B
Expand Down
29 changes: 24 additions & 5 deletions main/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
#include "esp_log.h"

#include "DS4432U.h"
#include "TPS546.h"
#include "EMC2101.h"
#include "EMC2302.h"
#include "INA260.h"
#include "adc.h"
#include "connect.h"
Expand Down Expand Up @@ -75,11 +77,28 @@ static void _init_system(GlobalState * global_state, SystemModule * module)

ADC_init();

// DS4432U tests
DS4432U_set_vcore(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0);

EMC2101_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1));
EMC2101_set_fan_speed(1);
/* perform platform init based on the platform ID */
/* TODO add other platforms besides HEX */
switch (global_state->platform_id) {
case PLATFORM_BITAXE:
case PLATFORM_ULTRA:
// DS4432U tests
DS4432U_set_vcore(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0);

EMC2101_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1));
EMC2101_set_fan_speed(1);
break;
case PLATFORM_HEX:
// Initialize the core voltage regulator
TPS546_init();
// Fan Tests
EMC2302_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1));
EMC2302_set_fan_speed(0, (float) nvs_config_get_u16(NVS_CONFIG_FAN_SPEED, 100) / 100);
EMC2302_set_fan_speed(1, (float) nvs_config_get_u16(NVS_CONFIG_FAN_SPEED, 100) / 100);
break;
default:
ESP_LOGI(TAG, "ERROR- invalid platform ID");
}

vTaskDelay(500 / portTICK_PERIOD_MS);

Expand Down

0 comments on commit ecac56f

Please sign in to comment.