mirror of
https://github.com/skot/ESP-Miner.git
synced 2025-03-29 11:11:45 +01:00
refactor: split vcore out from ds4432 driver, to make it an abstraction of whatever hardware is regulating vcore (making room for TPS546)
This commit is contained in:
parent
c9865a5e0a
commit
2d15d447e0
@ -11,6 +11,7 @@ SRCS
|
||||
"nvs_config.c"
|
||||
"oled.c"
|
||||
"system.c"
|
||||
"vcore.c"
|
||||
"work_queue.c"
|
||||
"./tasks/stratum_task.c"
|
||||
"./tasks/create_jobs_task.c"
|
||||
|
@ -2,87 +2,47 @@
|
||||
#include <math.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "i2c_master.h"
|
||||
|
||||
#include "DS4432U.h"
|
||||
|
||||
// DS4432U+ -- Adjustable current DAC for use with the TPS40305 voltage regulator
|
||||
// address: 0x90
|
||||
// DS4432U+ -- Adjustable current DAC
|
||||
#define DS4432U_SENSOR_ADDR 0x48 // Slave address of the DS4432U+
|
||||
#define DS4432U_OUT0_REG 0xF8 // register for current output 0
|
||||
#define DS4432U_OUT1_REG 0xF9 // register for current output 1
|
||||
|
||||
// DS4432U Transfer function constants
|
||||
#define VFB 0.6
|
||||
#define IFS 0.000098921 // (Vrfs / Rfs) x (127/16) -> Vrfs = 0.997, Rfs = 80000
|
||||
#define RA 4750.0 // R14
|
||||
#define RB 3320.0 // R15
|
||||
#define NOMINAL 1.451 // this is with the current DAC set to 0. Should be pretty close to (VFB*(RA+RB))/RB
|
||||
#define MAXV 2.39
|
||||
#define MINV 0.046
|
||||
|
||||
static const char *TAG = "DS4432U.c";
|
||||
static const char *TAG = "DS4432U";
|
||||
|
||||
/**
|
||||
* @brief voltage_to_reg takes a voltage and returns a register setting for the DS4432U to get that voltage on the TPS40305
|
||||
* careful with this one!!
|
||||
* @brief Set the current DAC code for a specific DS4432U output.
|
||||
*
|
||||
* @param output The output channel (0 or 1).
|
||||
* @param code The current code value to set.
|
||||
* @return esp_err_t ESP_OK on success, or an error code on failure.
|
||||
*/
|
||||
static uint8_t voltage_to_reg(float vout)
|
||||
{
|
||||
float change;
|
||||
uint8_t reg;
|
||||
esp_err_t DS4432U_set_current_code(uint8_t output, uint8_t code) {
|
||||
uint8_t reg = (output == 0) ? DS4432U_OUT0_REG : DS4432U_OUT1_REG;
|
||||
return i2c_master_register_write_byte(DS4432U_SENSOR_ADDR, reg, code);
|
||||
}
|
||||
|
||||
// make sure the requested voltage is in within range of MINV and MAXV
|
||||
if (vout > MAXV || vout < MINV)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// this is the transfer function. comes from the DS4432U+ datasheet
|
||||
change = fabs((((VFB / RB) - ((vout - VFB) / RA)) / IFS) * 127);
|
||||
reg = (uint8_t)ceil(change);
|
||||
|
||||
// Set the MSB high if the requested voltage is BELOW nominal
|
||||
if (vout < NOMINAL)
|
||||
{
|
||||
reg |= 0x80;
|
||||
}
|
||||
|
||||
return reg;
|
||||
/**
|
||||
* @brief Get the current DAC code value for a specific DS4432U output.
|
||||
*
|
||||
* @param output The output channel (0 or 1).
|
||||
* @param code Pointer to store the current code value.
|
||||
* @return esp_err_t ESP_OK on success, or an error code on failure.
|
||||
*/
|
||||
esp_err_t DS4432U_get_current_code(uint8_t output, uint8_t *code) {
|
||||
uint8_t reg = (output == 0) ? DS4432U_OUT0_REG : DS4432U_OUT1_REG;
|
||||
return i2c_master_register_read(DS4432U_SENSOR_ADDR, reg, code, 1);
|
||||
}
|
||||
|
||||
bool DS4432U_test(void)
|
||||
{
|
||||
uint8_t data[3];
|
||||
uint8_t data;
|
||||
|
||||
/* Read the DS4432U+ WHO_AM_I register, on power up the register should have the value 0x00 */
|
||||
esp_err_t register_result = register_read(DS4432U_SENSOR_ADDR, DS4432U_OUT0_REG, data, 1);
|
||||
ESP_LOGI(TAG, "DS4432U+ OUT1 = 0x%02X", data[0]);
|
||||
esp_err_t register_result = i2c_master_register_read(DS4432U_SENSOR_ADDR, DS4432U_OUT0_REG, &data, 1);
|
||||
ESP_LOGI(TAG, "DS4432U+ OUT0 = 0x%02X", data);
|
||||
return register_result == ESP_OK;
|
||||
}
|
||||
|
||||
void DS4432U_read(void)
|
||||
{
|
||||
uint8_t data[3];
|
||||
|
||||
/* Read the DS4432U+ WHO_AM_I register, on power up the register should have the value 0x00 */
|
||||
ESP_ERROR_CHECK(register_read(DS4432U_SENSOR_ADDR, DS4432U_OUT0_REG, data, 1));
|
||||
ESP_LOGI(TAG, "DS4432U+ OUT1 = 0x%02X", data[0]);
|
||||
}
|
||||
|
||||
static void DS4432U_set(uint8_t val)
|
||||
{
|
||||
ESP_LOGI(TAG, "Writing 0x%02X", val);
|
||||
ESP_ERROR_CHECK(register_write_byte(DS4432U_SENSOR_ADDR, DS4432U_OUT0_REG, val));
|
||||
}
|
||||
|
||||
bool DS4432U_set_vcore(float core_voltage)
|
||||
{
|
||||
uint8_t reg_setting;
|
||||
|
||||
reg_setting = voltage_to_reg(core_voltage);
|
||||
|
||||
ESP_LOGI(TAG, "Set ASIC voltage = %.3fV [0x%02X]", core_voltage, reg_setting);
|
||||
|
||||
DS4432U_set(reg_setting); /// eek!
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
#ifndef DS4432U_H_
|
||||
#define DS4432U_H_
|
||||
|
||||
#include "i2c_master.h"
|
||||
#include <stdbool.h>
|
||||
#include "esp_check.h"
|
||||
|
||||
void DS4432U_read(void);
|
||||
bool DS4432U_test(void);
|
||||
bool DS4432U_set_vcore(float);
|
||||
esp_err_t DS4432U_set_current_code(uint8_t output, uint8_t code);
|
||||
esp_err_t DS4432U_get_current_code(uint8_t output, uint8_t *code);
|
||||
|
||||
#endif /* DS4432U_H_ */
|
||||
|
@ -10,10 +10,10 @@ void EMC2101_init(bool invertPolarity)
|
||||
{
|
||||
|
||||
// set the TACH input
|
||||
ESP_ERROR_CHECK(register_write_byte(EMC2101_I2CADDR_DEFAULT, EMC2101_REG_CONFIG, 0x04));
|
||||
ESP_ERROR_CHECK(i2c_master_register_write_byte(EMC2101_I2CADDR_DEFAULT, EMC2101_REG_CONFIG, 0x04));
|
||||
|
||||
if (invertPolarity) {
|
||||
ESP_ERROR_CHECK(register_write_byte(EMC2101_I2CADDR_DEFAULT, EMC2101_FAN_CONFIG, 0b00100011));
|
||||
ESP_ERROR_CHECK(i2c_master_register_write_byte(EMC2101_I2CADDR_DEFAULT, EMC2101_FAN_CONFIG, 0b00100011));
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ void EMC2101_set_fan_speed(float percent)
|
||||
uint8_t speed;
|
||||
|
||||
speed = (uint8_t) (63.0 * percent);
|
||||
ESP_ERROR_CHECK(register_write_byte(EMC2101_I2CADDR_DEFAULT, EMC2101_REG_FAN_SETTING, speed));
|
||||
ESP_ERROR_CHECK(i2c_master_register_write_byte(EMC2101_I2CADDR_DEFAULT, EMC2101_REG_FAN_SETTING, speed));
|
||||
}
|
||||
|
||||
// RPM = 5400000/reading
|
||||
@ -33,8 +33,8 @@ uint16_t EMC2101_get_fan_speed(void)
|
||||
uint16_t reading;
|
||||
uint16_t RPM;
|
||||
|
||||
ESP_ERROR_CHECK(register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_TACH_LSB, &tach_lsb, 1));
|
||||
ESP_ERROR_CHECK(register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_TACH_MSB, &tach_msb, 1));
|
||||
ESP_ERROR_CHECK(i2c_master_register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_TACH_LSB, &tach_lsb, 1));
|
||||
ESP_ERROR_CHECK(i2c_master_register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_TACH_MSB, &tach_msb, 1));
|
||||
|
||||
// ESP_LOGI(TAG, "Raw Fan Speed = %02X %02X", tach_msb, tach_lsb);
|
||||
|
||||
@ -53,8 +53,8 @@ float EMC2101_get_external_temp(void)
|
||||
uint8_t temp_msb, temp_lsb;
|
||||
uint16_t reading;
|
||||
|
||||
ESP_ERROR_CHECK(register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_EXTERNAL_TEMP_MSB, &temp_msb, 1));
|
||||
ESP_ERROR_CHECK(register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_EXTERNAL_TEMP_LSB, &temp_lsb, 1));
|
||||
ESP_ERROR_CHECK(i2c_master_register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_EXTERNAL_TEMP_MSB, &temp_msb, 1));
|
||||
ESP_ERROR_CHECK(i2c_master_register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_EXTERNAL_TEMP_LSB, &temp_lsb, 1));
|
||||
|
||||
reading = temp_lsb | (temp_msb << 8);
|
||||
reading >>= 5;
|
||||
@ -65,6 +65,6 @@ float EMC2101_get_external_temp(void)
|
||||
uint8_t EMC2101_get_internal_temp(void)
|
||||
{
|
||||
uint8_t temp;
|
||||
ESP_ERROR_CHECK(register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_INTERNAL_TEMP, &temp, 1));
|
||||
ESP_ERROR_CHECK(i2c_master_register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_INTERNAL_TEMP, &temp, 1));
|
||||
return temp;
|
||||
}
|
||||
|
@ -8,14 +8,14 @@
|
||||
bool INA260_installed(void)
|
||||
{
|
||||
uint8_t data[2];
|
||||
return register_read(INA260_I2CADDR_DEFAULT, INA260_REG_BUSVOLTAGE, data, 2) == ESP_OK;
|
||||
return i2c_master_register_read(INA260_I2CADDR_DEFAULT, INA260_REG_BUSVOLTAGE, data, 2) == ESP_OK;
|
||||
}
|
||||
|
||||
float INA260_read_current(void)
|
||||
{
|
||||
uint8_t data[2];
|
||||
|
||||
ESP_ERROR_CHECK(register_read(INA260_I2CADDR_DEFAULT, INA260_REG_CURRENT, data, 2));
|
||||
ESP_ERROR_CHECK(i2c_master_register_read(INA260_I2CADDR_DEFAULT, INA260_REG_CURRENT, data, 2));
|
||||
// ESP_LOGI(TAG, "Raw Current = %02X %02X", data[1], data[0]);
|
||||
|
||||
return (uint16_t)(data[1] | (data[0] << 8)) * 1.25;
|
||||
@ -25,7 +25,7 @@ float INA260_read_voltage(void)
|
||||
{
|
||||
uint8_t data[2];
|
||||
|
||||
ESP_ERROR_CHECK(register_read(INA260_I2CADDR_DEFAULT, INA260_REG_BUSVOLTAGE, data, 2));
|
||||
ESP_ERROR_CHECK(i2c_master_register_read(INA260_I2CADDR_DEFAULT, INA260_REG_BUSVOLTAGE, data, 2));
|
||||
// ESP_LOGI(TAG, "Raw Voltage = %02X %02X", data[1], data[0]);
|
||||
|
||||
return (uint16_t)(data[1] | (data[0] << 8)) * 1.25;
|
||||
@ -35,7 +35,7 @@ float INA260_read_power(void)
|
||||
{
|
||||
uint8_t data[2];
|
||||
|
||||
ESP_ERROR_CHECK(register_read(INA260_I2CADDR_DEFAULT, INA260_REG_POWER, data, 2));
|
||||
ESP_ERROR_CHECK(i2c_master_register_read(INA260_I2CADDR_DEFAULT, INA260_REG_POWER, data, 2));
|
||||
// ESP_LOGI(TAG, "Raw Power = %02X %02X", data[1], data[0]);
|
||||
|
||||
return (data[1] | (data[0] << 8)) * 10;
|
||||
|
@ -38,7 +38,7 @@ esp_err_t i2c_master_delete(void)
|
||||
/**
|
||||
* @brief Read a sequence of I2C bytes
|
||||
*/
|
||||
esp_err_t register_read(uint8_t device_address, uint8_t reg_addr, uint8_t * data, size_t len)
|
||||
esp_err_t i2c_master_register_read(uint8_t device_address, uint8_t reg_addr, uint8_t * data, size_t len)
|
||||
{
|
||||
return i2c_master_write_read_device(I2C_MASTER_NUM, device_address, ®_addr, 1, data, len,
|
||||
I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
|
||||
@ -47,7 +47,7 @@ esp_err_t register_read(uint8_t device_address, uint8_t reg_addr, uint8_t * data
|
||||
/**
|
||||
* @brief Write a byte to a I2C register
|
||||
*/
|
||||
esp_err_t register_write_byte(uint8_t device_address, uint8_t reg_addr, uint8_t data)
|
||||
esp_err_t i2c_master_register_write_byte(uint8_t device_address, uint8_t reg_addr, uint8_t data)
|
||||
{
|
||||
int ret;
|
||||
uint8_t write_buf[2] = {reg_addr, data};
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
esp_err_t i2c_master_init(void);
|
||||
esp_err_t i2c_master_delete(void);
|
||||
esp_err_t register_read(uint8_t device_address, uint8_t reg_addr, uint8_t * data, size_t len);
|
||||
esp_err_t register_write_byte(uint8_t device_address, uint8_t reg_addr, uint8_t data);
|
||||
esp_err_t i2c_master_register_read(uint8_t device_address, uint8_t reg_addr, uint8_t * data, size_t len);
|
||||
esp_err_t i2c_master_register_write_byte(uint8_t device_address, uint8_t reg_addr, uint8_t data);
|
||||
|
||||
#endif /* I2C_MASTER_H_ */
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "nvs_config.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "oled.h"
|
||||
#include "vcore.h"
|
||||
#include "utils.h"
|
||||
|
||||
static const char * TAG = "self_test";
|
||||
@ -67,7 +68,7 @@ void self_test(void * pvParameters)
|
||||
ESP_LOGI(TAG, "I2C initialized successfully");
|
||||
|
||||
ADC_init();
|
||||
DS4432U_set_vcore(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0);
|
||||
VCORE_set_voltage(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0, *GLOBAL_STATE);
|
||||
|
||||
EMC2101_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1));
|
||||
EMC2101_set_fan_speed(1);
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "i2c_master.h"
|
||||
#include "DS4432U.h"
|
||||
#include "EMC2101.h"
|
||||
#include "INA260.h"
|
||||
#include "adc.h"
|
||||
@ -12,6 +11,7 @@
|
||||
#include "led_controller.h"
|
||||
#include "nvs_config.h"
|
||||
#include "oled.h"
|
||||
#include "vcore.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_app_desc.h"
|
||||
@ -84,8 +84,7 @@ 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);
|
||||
VCORE_set_voltage(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0, *global_state);
|
||||
|
||||
EMC2101_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1));
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include "DS4432U.h"
|
||||
#include "EMC2101.h"
|
||||
#include "INA260.h"
|
||||
#include "bm1397.h"
|
||||
|
62
main/vcore.c
Normal file
62
main/vcore.c
Normal file
@ -0,0 +1,62 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "vcore.h"
|
||||
#include "DS4432U.h"
|
||||
|
||||
// DS4432U Transfer function constants for Bitaxe board
|
||||
#define BITAXE_VFB 0.6
|
||||
#define BITAXE_IFS 0.000098921 // (Vrfs / Rfs) x (127/16) -> Vrfs = 0.997, Rfs = 80000
|
||||
#define BITAXE_RA 4750.0 // R14
|
||||
#define BITAXE_RB 3320.0 // R15
|
||||
#define BITAXE_VNOM 1.451 // this is with the current DAC set to 0. Should be pretty close to (VFB*(RA+RB))/RB
|
||||
#define BITAXE_VMAX 2.39
|
||||
#define BITAXE_VMIN 0.046
|
||||
|
||||
static const char *TAG = "vcore.c";
|
||||
|
||||
/**
|
||||
* @brief ds4432_tps40305_bitaxe_voltage_to_reg takes a voltage and returns a register setting for the DS4432U to get that voltage on the TPS40305
|
||||
* careful with this one!!
|
||||
*/
|
||||
static uint8_t ds4432_tps40305_bitaxe_voltage_to_reg(float vout)
|
||||
{
|
||||
float change;
|
||||
uint8_t reg;
|
||||
|
||||
// make sure the requested voltage is in within range of BITAXE_VMIN and BITAXE_VMAX
|
||||
if (vout > BITAXE_VMAX || vout < BITAXE_VMIN)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// this is the transfer function. comes from the DS4432U+ datasheet
|
||||
change = fabs((((BITAXE_VFB / BITAXE_RB) - ((vout - BITAXE_VFB) / BITAXE_RA)) / BITAXE_IFS) * 127);
|
||||
reg = (uint8_t)ceil(change);
|
||||
|
||||
// Set the MSB high if the requested voltage is BELOW nominal
|
||||
if (vout < BITAXE_VNOM)
|
||||
{
|
||||
reg |= 0x80;
|
||||
}
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
bool VCORE_set_voltage(float core_voltage, GlobalState global_state)
|
||||
{
|
||||
uint8_t reg_setting;
|
||||
|
||||
if ((global_state.device_model == DEVICE_MAX) ||
|
||||
(global_state.device_model == DEVICE_ULTRA) ||
|
||||
(global_state.device_model == DEVICE_SUPRA)) {
|
||||
reg_setting = ds4432_tps40305_bitaxe_voltage_to_reg(core_voltage);
|
||||
ESP_LOGI(TAG, "Set ASIC voltage = %.3fV [0x%02X]", core_voltage, reg_setting);
|
||||
DS4432U_set_current_code(0, reg_setting); /// eek!
|
||||
}
|
||||
// can make other fancy 'else if' based on other device_model or specific version that have different HW to set VCore value
|
||||
// for example DEVICE_HEX will have a different way to set VCore using TPS546...
|
||||
|
||||
return true;
|
||||
}
|
8
main/vcore.h
Normal file
8
main/vcore.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef VCORE_H_
|
||||
#define VCORE_H_
|
||||
|
||||
#include "global_state.h"
|
||||
|
||||
bool VCORE_set_voltage(float core_voltage, GlobalState global_state);
|
||||
|
||||
#endif /* VCORE_H_ */
|
Loading…
x
Reference in New Issue
Block a user