decode VOUT_COMMAND and TEMPERATURE

This commit is contained in:
macphyter 2024-01-21 13:15:21 -07:00 committed by Georges Palauqui
parent 0c2745f17f
commit 628d3ac3de
No known key found for this signature in database
GPG Key ID: 1E45F544CE4D04A5
8 changed files with 196 additions and 15 deletions

View File

@ -3,6 +3,8 @@ SRCS
"adc.c"
"DS4432U.c"
"EMC2101.c"
"EMC2302.c"
"TPS546.c"
"fonts.c"
"i2c_master.c"
"INA260.c"

View File

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

153
main/TPS546.c Normal file
View File

@ -0,0 +1,153 @@
#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_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";
/**
* @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;
}
// 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
main/TPS546.h Normal file
View File

@ -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_ */

View File

@ -23,6 +23,7 @@ typedef enum
DEVICE_MAX = 0,
DEVICE_ULTRA,
DEVICE_SUPRA,
DEVICE_HEX,
} DeviceModel;
typedef enum
@ -103,4 +104,4 @@ typedef struct
} GlobalState;
#endif /* GLOBAL_STATE_H_ */
#endif /* GLOBAL_STATE_H_ */

View File

@ -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

View File

@ -4,6 +4,7 @@
#include "i2c_master.h"
#include "EMC2101.h"
#include "EMC2302.h"
#include "INA260.h"
#include "adc.h"
#include "connect.h"
@ -90,8 +91,15 @@ static void _init_system(GlobalState * GLOBAL_STATE)
switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
case DEVICE_ULTRA:
case DEVICE_SUPRA:
case DEVICE_ULTRA:
EMC2101_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1));
EMC2101_set_fan_speed(1);
break;
case DEVICE_HEX:
// 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:
}

View File

@ -5,6 +5,7 @@
#include "vcore.h"
#include "adc.h"
#include "DS4432U.h"
#include "TPS546.h"
#define TPS40305_VFB 0.6
@ -20,7 +21,10 @@
static const char *TAG = "vcore.c";
void VCORE_init(GlobalState * global_state) {
void VCORE_init(GlobalState global_state) {
if (global_state.device_model == DEVICE_HEX) {
TPS546_init();
}
ADC_init();
}