Skip to content

Commit

Permalink
Merge branch 'hex_v302' of https://github.com/skot/ESP-Miner into hex…
Browse files Browse the repository at this point in the history
…_v302
  • Loading branch information
benjamin-wilson committed Feb 26, 2024
2 parents fb20a75 + 82da18c commit 75ef84d
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 21 deletions.
71 changes: 57 additions & 14 deletions main/EMC2302.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,38 +41,81 @@ static esp_err_t register_write_byte(uint8_t reg_addr, uint8_t data)
// run this first. sets up the PWM polarity register
void EMC2302_init(bool invertPolarity)
{
uint8_t read_byte;
uint8_t fan_config1;

if (invertPolarity) {
ESP_ERROR_CHECK(register_write_byte(EMC2302_PWM_POLARITY, 0b00011111));
}
// Read the manufacturer ID
ESP_ERROR_CHECK(register_read(EMC2302_MANUFACTURER_ID, &read_byte, 1));
ESP_LOGI(TAG, "Manufacturer ID = %02x", read_byte);

// Read the product ID
ESP_ERROR_CHECK(register_read(EMC2302_PRODUCT_ID, &read_byte, 1));
ESP_LOGI(TAG, "Product ID = %02x", read_byte);

// Read the
ESP_ERROR_CHECK(register_read(EMC2302_SILICON_REVISION, &read_byte, 1));
ESP_LOGI(TAG, "Silicon Revision = %02x", read_byte);

fan_config1 = 0x98; // 10011000
ESP_ERROR_CHECK(register_write_byte(EMC2302_FAN1_CONFIG1, fan_config1));
ESP_ERROR_CHECK(register_write_byte(EMC2302_FAN2_CONFIG1, fan_config1));

//if (invertPolarity) {
// ESP_ERROR_CHECK(register_write_byte(EMC2302_PWM_POLARITY, 0b00011111));
//}
}

// Sets the fan speed to a given percent
void EMC2302_set_fan_speed(uint8_t devicenum, float percent)
{
uint8_t speed;
uint8_t FAN_SETTING_REG = EMC2302_FAN1_SETTING + (devicenum * 0x10);

speed = (uint8_t) (63.0 * percent);
ESP_ERROR_CHECK(register_write_byte(FAN_SETTING_REG, speed));
int max_rpm = 2400;
int req_rpm = max_rpm * (percent / 100);
uint16_t tach_counts;
uint8_t TACH_MSB_REG = EMC2302_TACH1_TARGET_MSB + (devicenum * 0x10);
uint8_t TACH_LSB_REG = EMC2302_TACH1_TARGET_LSB + (devicenum * 0x10);
uint8_t tach_counts_MSB;
uint8_t tach_counts_LSB;

int poles = 4; // motor poles
int edges = 9; // motor edges
int ftach = 32768; // tach clock frequency

//ESP_LOGI(TAG, "SET-Fan RPM requested (%d%%) %d", (int)percent, req_rpm);

tach_counts = (uint16_t) ((edges - 1)/poles * (1.0f/req_rpm) * ftach * 60);
tach_counts_MSB = tach_counts >> 5;
tach_counts_LSB = (tach_counts & 0x001F) << 3;

ESP_ERROR_CHECK( register_write_byte(TACH_MSB_REG, tach_counts_MSB ));
ESP_ERROR_CHECK( register_write_byte(TACH_LSB_REG, tach_counts_LSB ));
}

// Gets the fan speed
uint16_t EMC2302_get_fan_speed(uint8_t devicenum)
{
uint8_t tach_lsb, tach_msb;
uint16_t RPM;
uint16_t tach_counts = 1;
uint16_t rpm;
uint8_t TACH_LSB_REG = EMC2302_TACH1_LSB + (devicenum * 0x10);
uint8_t TACH_MSB_REG = EMC2302_TACH1_MSB + (devicenum * 0x10);

ESP_ERROR_CHECK(register_read(TACH_LSB_REG, &tach_lsb, 1));
int poles = 4; // motor poles
int edges = 9; // motor edges
int ftach = 32768; // tach clock frequency

ESP_ERROR_CHECK(register_read(TACH_MSB_REG, &tach_msb, 1));
ESP_ERROR_CHECK(register_read(TACH_LSB_REG, &tach_lsb, 1));
//ESP_LOGI(TAG, "GET-Tach counts reg: %02x %02x", tach_msb, tach_lsb);

ESP_LOGI(TAG, "Raw Fan Speed[%d] = %02X %02X", devicenum, tach_msb, tach_lsb);
RPM = (tach_msb << 5) + ((tach_lsb >> 3) & 0x1F);
ESP_LOGI(TAG, "Fan Speed[%d] = %d RPM", devicenum, RPM);
if ((tach_msb == 0xff) && (tach_msb == 0xF8)) {
rpm = 0;
} else {
tach_counts = (tach_msb << 5) + ((tach_lsb >> 3) & 0x1F);
rpm = (uint16_t) ((edges - 1)/poles * (1.0f/tach_counts) * ftach * 60);
}
ESP_LOGI(TAG, "GET-Fan Speed[%d] = %d RPM", devicenum, rpm);

return RPM;
return rpm;
}

float EMC2302_get_external_temp(void)
Expand Down
15 changes: 11 additions & 4 deletions main/EMC2302.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
#define EMC2302_FAN1_DRV_FAIL_HIGH 0x3B ///< Fan 1 drive fail band high byte
#define EMC2302_TACH1_TARGET_LSB 0x3C ///< Tach 1 target low byte
#define EMC2302_TACH1_TARGET_MSB 0x3D ///< Tach 1 target high byte
#define EMC2302_TACH1_LSB 0x3E ///< Tach 1 reading low byte
#define EMC2302_TACH1_MSB 0x3F ///< Tach 1 reading high byte
#define EMC2302_TACH1_MSB 0x3E ///< Tach 1 reading low byte
#define EMC2302_TACH1_LSB 0x3F ///< Tach 1 reading high byte

#define EMC2302_FAN2_SETTING 0x40 ///< Fan 2 setting
#define EMC2302_PWM2_DIVIDE 0x41 ///< PWM 2 divider
Expand All @@ -47,8 +47,14 @@
#define EMC2302_FAN2_DRV_FAIL_HIGH 0x4B ///< Fan 2 drive fail band high byte
#define EMC2302_TACH2_TARGET_LSB 0x4C ///< Tach 2 target low byte
#define EMC2302_TACH2_TARGET_MSB 0x4D ///< Tach 2 target high byte
#define EMC2302_TACH2_LSB 0x4E ///< Tach 2 reading low byte
#define EMC2302_TACH2_MSB 0x4F ///< Tach 2 reading high byte
#define EMC2302_TACH2_MSB 0x4E ///< Tach 2 reading low byte
#define EMC2302_TACH2_LSB 0x4F ///< Tach 2 reading high byte

#define EMC2302_SOFTWARE_LOCK 0xEF
#define EMC2302_PRODUCT_FEATURES 0xFC
#define EMC2302_PRODUCT_ID 0xFD
#define EMC2302_MANUFACTURER_ID 0xFE
#define EMC2302_SILICON_REVISION 0xFF

#define EMC2302_FAN_RPM_NUMERATOR 5400000 ///< Conversion unit to convert LSBs to fan RPM
#define _TEMP_LSB 0.125 ///< single bit value for internal temperature readings
Expand Down Expand Up @@ -76,6 +82,7 @@ void EMC2302_init(bool);
void EMC2302_set_fan_speed(uint8_t, float);
uint16_t EMC2302_get_fan_speed(uint8_t);

/* EMC2302 doesn't have temperature sensors, so these are dummy functions */
float EMC2302_get_external_temp(void);
uint8_t EMC2302_get_internal_temp(void);

Expand Down
6 changes: 5 additions & 1 deletion main/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,13 @@ static void _init_system(GlobalState * global_state, SystemModule * module)
// Initialize the core voltage regulator
TPS546_init();
// Fan config - Hex has two fans
//EMC2302_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1));
EMC2302_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1));
EMC2302_get_fan_speed(0);
EMC2302_get_fan_speed(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);

// temperature sensors - Hex has two sensors
if (TMP1075_installed(0)) {
ESP_LOGI(TAG, "Temperature sensor 0: %d", TMP1075_read_temperature(0));
Expand Down
16 changes: 14 additions & 2 deletions main/tasks/power_management_task.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "DS4432U.h"
#include "EMC2101.h"
#include "EMC2302.h"
#include "INA260.h"
#include "TPS546.h"
#include "TMP1075.h"
Expand Down Expand Up @@ -271,8 +272,9 @@ void POWER_MANAGEMENT_HEX_task(void * pvParameters)
// calculate regulator power (in milliwatts)
power_management->power = (TPS546_get_vout() * power_management->current) / 1000;

// TODO fix fan driver
//power_management->fan_speed = EMC2101_get_fan_speed();
// get the fan RPM
power_management->fan_speed = EMC2302_get_fan_speed(0);
power_management->fan_speed = EMC2302_get_fan_speed(1);

// Two board temperature sensors
ESP_LOGI(TAG, "Board Temp: %d, %d", TMP1075_read_temperature(0), TMP1075_read_temperature(1));
Expand All @@ -281,6 +283,16 @@ void POWER_MANAGEMENT_HEX_task(void * pvParameters)
power_management->chip_temp = (float)TPS546_get_temperature();
ESP_LOGI(TAG, "TPS546 Temp: %2f", power_management->chip_temp);

EMC2302_set_fan_speed(1, 100);

// This causes the fan to cycle on/off quickly, need some hysteresis
// for active fan control
//if (power_management->chip_temp > 65) {
// EMC2302_set_fan_speed(1, 100);
//} else {
// EMC2302_set_fan_speed(1, 60);
//}

// TODO figure out best way to detect overheating on the Hex
if (power_management->chip_temp > TPS546_THROTTLE_TEMP &&
(power_management->frequency_value > 50 || power_management->voltage > 1000)) {
Expand Down

0 comments on commit 75ef84d

Please sign in to comment.