ESP-Miner/main/thermal/EMC2103.c
Skot 7dcb69ebdc
GammaTurbo support and HW abstraction (#698)
* initial changes for the gammaturbo bringup
* added preliminary TPS546 changes
* added preliminary EMC2103 support
* ASIC temp seems to be maybe working.
* magically now fan seems to have the right polarity
* added in ideality and beta constants (currently unused). Fixed EMC2103_get_fan_speed()
* abstract fan and ASIC temp into thermal functions
* abstracted voltage regulator specifics out of tasks and into power.c and vcore.c functions
* add TPS546 support for multiple models
* move TPS40305/DS4432U vout setter to DS4432U.c
* move all ASIC specific functions to asic.c
* bad device_model nvs handling
* remove old code
* add workaround for TPS546 VIN_UV_WARN_LIMIT silicon bug.
2025-02-11 22:46:56 -05:00

159 lines
4.9 KiB
C

#include <stdio.h>
#include "esp_log.h"
#include "i2c_bitaxe.h"
#include "EMC2103.h"
static const char * TAG = "EMC2103";
static i2c_master_dev_handle_t EMC2103_dev_handle;
/**
* @brief Initialize the EMC2103 sensor.
*
* @return esp_err_t ESP_OK on success, or an error code on failure.
*/
esp_err_t EMC2103_init(bool invertPolarity) {
if (i2c_bitaxe_add_device(EMC2103_I2CADDR_DEFAULT, &EMC2103_dev_handle, TAG) != ESP_OK) {
ESP_LOGE(TAG, "Failed to add device");
return ESP_FAIL;
}
ESP_LOGI(TAG, "EMC2103 init with polarity %d", invertPolarity);
// Configure the fan setting
ESP_ERROR_CHECK(i2c_bitaxe_register_write_byte(EMC2103_dev_handle, EMC2103_CONFIGURATION1, 0));
if (invertPolarity) {
ESP_ERROR_CHECK(i2c_bitaxe_register_write_byte(EMC2103_dev_handle, EMC2103_PWM_CONFIG, 0x01));
}
return ESP_OK;
}
void EMC2103_set_ideality_factor(uint8_t ideality){
//set Ideality Factor
ESP_ERROR_CHECK(i2c_bitaxe_register_write_byte(EMC2103_dev_handle, EMC2103_EXTERNAL_DIODE1_IDEALITY, ideality));
ESP_ERROR_CHECK(i2c_bitaxe_register_write_byte(EMC2103_dev_handle, EMC2103_EXTERNAL_DIODE2_IDEALITY, ideality));
}
void EMC2103_set_beta_compensation(uint8_t beta){
//set Beta Compensation
ESP_ERROR_CHECK(i2c_bitaxe_register_write_byte(EMC2103_dev_handle, EMC2103_EXTERNAL_DIODE1_BETA, beta));
ESP_ERROR_CHECK(i2c_bitaxe_register_write_byte(EMC2103_dev_handle, EMC2103_EXTERNAL_DIODE2_BETA, beta));
}
/**
* @brief Set the fan speed as a percentage.
*
* @param percent The desired fan speed as a percentage (0.0 to 1.0).
*/
void EMC2103_set_fan_speed(float percent)
{
uint8_t setting = (uint8_t) (255.0 * percent);
//ESP_LOGI(TAG, "Setting fan speed to %.2f%% (%d)", percent*100.0, setting);
ESP_ERROR_CHECK(i2c_bitaxe_register_write_byte(EMC2103_dev_handle, EMC2103_FAN_SETTING, setting));
}
/**
* @brief Get the current fan speed in RPM.
*
* @return uint16_t The fan speed in RPM.
*/
uint16_t EMC2103_get_fan_speed(void)
{
uint8_t tach_lsb, tach_msb;
uint16_t reading;
uint32_t RPM;
ESP_ERROR_CHECK(i2c_bitaxe_register_read(EMC2103_dev_handle, EMC2103_TACH_LSB, &tach_lsb, 1));
ESP_ERROR_CHECK(i2c_bitaxe_register_read(EMC2103_dev_handle, EMC2103_TACH_MSB, &tach_msb, 1));
// ESP_LOGI(TAG, "Raw Fan Speed = %02X %02X", tach_msb, tach_lsb);
reading = tach_lsb | (tach_msb << 8);
reading >>= 3;
//RPM = (3,932,160 * m)/reading
//m is the multipler, which is default 2
RPM = 7864320 / reading;
// ESP_LOGI(TAG, "Fan Speed = %d RPM", RPM);
if (RPM == 82) {
return 0;
}
return RPM;
}
/**
* @brief Get the external temperature in Celsius.
*
* @return float The external temperature in Celsius.
*/
float EMC2103_get_external_temp(void)
{
uint8_t temp_msb, temp_lsb;
uint16_t reading;
float temp1, temp2;
ESP_ERROR_CHECK(i2c_bitaxe_register_read(EMC2103_dev_handle, EMC2103_EXTERNAL_TEMP1_MSB, &temp_msb, 1));
ESP_ERROR_CHECK(i2c_bitaxe_register_read(EMC2103_dev_handle, EMC2103_EXTERNAL_TEMP1_LSB, &temp_lsb, 1));
//print the temps
//ESP_LOGI(TAG, "Temp1 MSB: %02X Temp1 LSB: %02X", temp_msb, temp_lsb);
// Combine MSB and LSB, and then right shift to get 11 bits
reading = (temp_msb << 8) | temp_lsb;
if (reading == EMC2103_TEMP_DIODE_FAULT) {
ESP_LOGE(TAG, "EMC2103 TEMP_DIODE1_FAULT: %04X", reading);
}
reading >>= 5; // Now, `reading` contains an 11-bit signed value
// Cast `reading` to a signed 16-bit integer
int16_t signed_reading = (int16_t)reading;
// If the 11th bit (sign bit in 11-bit data) is set, extend the sign
if (signed_reading & 0x0400) {
signed_reading |= 0xF800; // Set upper bits to extend the sign
}
// Convert the signed reading to temperature in Celsius
temp1 = (float)signed_reading / 8.0;
ESP_ERROR_CHECK(i2c_bitaxe_register_read(EMC2103_dev_handle, EMC2103_EXTERNAL_TEMP2_MSB, &temp_msb, 1));
ESP_ERROR_CHECK(i2c_bitaxe_register_read(EMC2103_dev_handle, EMC2103_EXTERNAL_TEMP2_LSB, &temp_lsb, 1));
//print the temps
//ESP_LOGI(TAG, "Temp2 MSB: %02X Temp2 LSB: %02X", temp_msb, temp_lsb);
// Combine MSB and LSB, and then right shift to get 11 bits
reading = (temp_msb << 8) | temp_lsb;
if (reading == EMC2103_TEMP_DIODE_FAULT) {
ESP_LOGE(TAG, "EMC2103 TEMP_DIODE2_FAULT: %04X", reading);
}
reading >>= 5; // Now, `reading` contains an 11-bit signed value
// Cast `reading` to a signed 16-bit integer
signed_reading = (int16_t)reading;
// If the 11th bit (sign bit in 11-bit data) is set, extend the sign
if (signed_reading & 0x0400) {
signed_reading |= 0xF800; // Set upper bits to extend the sign
}
// Convert the signed reading to temperature in Celsius
temp2 = (float)signed_reading / 8.0;
//debug the temps
//ESP_LOGI(TAG, "Temp1: %.2f Temp2: %.2f", temp1, temp2);
return temp1;
}