From 7b816bc6d4ae30092ecea743518703e779f3e16f Mon Sep 17 00:00:00 2001 From: Skot Croshere Date: Tue, 17 Jan 2023 00:07:21 -0500 Subject: [PATCH] added the DS4432U transfer function for setting the BM1397 core voltage. careful with this one!! --- main/DS4432U.c | 61 +++++++++++++++++++++++++++++++++++------- main/DS4432U.h | 2 ++ main/EMC2101.c | 8 ++++++ main/INA260.c | 8 ++++++ main/i2c_simple_main.c | 34 +++++------------------ 5 files changed, 75 insertions(+), 38 deletions(-) create mode 100644 main/EMC2101.c create mode 100644 main/INA260.c diff --git a/main/DS4432U.c b/main/DS4432U.c index b737423..6b81c9a 100644 --- a/main/DS4432U.c +++ b/main/DS4432U.c @@ -1,4 +1,5 @@ #include +#include #include "esp_log.h" #include "driver/i2c.h" @@ -17,8 +18,43 @@ #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"; +/** + * @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!! + */ +uint8_t voltage_to_reg(float vout) { + float change; + uint8_t reg; + + //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 i2c master initialization */ @@ -50,26 +86,31 @@ esp_err_t i2c_master_delete(void) { /** * @brief Read a sequence of I2C bytes */ -static esp_err_t register_read(uint8_t i2c_address, uint8_t reg_addr, uint8_t *data, size_t len) { - return i2c_master_write_read_device(I2C_MASTER_NUM, i2c_address, ®_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); +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, DS4432U_SENSOR_ADDR, ®_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); } /** * @brief Write a byte to a I2C register */ -// static esp_err_t register_write_byte(uint8_t i2c_address, uint8_t reg_addr, uint8_t data) { -// int ret; -// uint8_t write_buf[2] = {reg_addr, data}; +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, i2c_address, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); + ret = i2c_master_write_to_device(I2C_MASTER_NUM, DS4432U_SENSOR_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); -// return ret; -// } + return ret; +} 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_OUT1_REG, data, 1)); + ESP_ERROR_CHECK(register_read(DS4432U_OUT0_REG, data, 1)); ESP_LOGI(TAG, "DS4432U+ OUT1 = 0x%02X", data[0]); +} + +void DS4432U_set(uint8_t val) { + ESP_LOGI(TAG, "Writing 0x%02X", val); + ESP_ERROR_CHECK(register_write_byte(DS4432U_OUT0_REG, val)); } \ No newline at end of file diff --git a/main/DS4432U.h b/main/DS4432U.h index b51a2dc..d270c94 100644 --- a/main/DS4432U.h +++ b/main/DS4432U.h @@ -6,5 +6,7 @@ esp_err_t i2c_master_init(void); esp_err_t i2c_master_delete(void); void DS4432U_read(void); +void DS4432U_set(uint8_t); +uint8_t voltage_to_reg(float vout); #endif /* DS4432U_H_ */ \ No newline at end of file diff --git a/main/EMC2101.c b/main/EMC2101.c new file mode 100644 index 0000000..df99375 --- /dev/null +++ b/main/EMC2101.c @@ -0,0 +1,8 @@ +//EMC2101 -- Fan and temp sensor controller +//address: 0x4C +#define EMC2101_SENSOR_ADDR 0x4C //Slave address of the EMC2101 +#define EMC2101_PRODUCTID_REG 0xFD //should be 0x16 or 0x28 + + // /* Read the EMC2101 WHO_AM_I register, on power up the register should have the value 0x16 or 0x28 */ + // ESP_ERROR_CHECK(register_read(EMC2101_SENSOR_ADDR, EMC2101_PRODUCTID_REG, data, 1)); + // ESP_LOGI(TAG, "EMC2101 PRODUCT ID = 0x%02X", data[0]); \ No newline at end of file diff --git a/main/INA260.c b/main/INA260.c new file mode 100644 index 0000000..d682ecf --- /dev/null +++ b/main/INA260.c @@ -0,0 +1,8 @@ +//INA260 -- Power meter +//address: 0x40 +#define INA260_SENSOR_ADDR 0x40 //Slave address of the INA260 +#define INA260_MANFID_REG 0xFE //should be 0x5449 + + // /* Read the INA260 WHO_AM_I register, on power up the register should have the value 0x5449 */ + // ESP_ERROR_CHECK(register_read(INA260_SENSOR_ADDR, INA260_MANFID_REG, data, 2)); + // ESP_LOGI(TAG, "INA260 MANF ID = 0x%02X%02X", data[0], data[1]); \ No newline at end of file diff --git a/main/i2c_simple_main.c b/main/i2c_simple_main.c index c1c9b70..8624a9c 100755 --- a/main/i2c_simple_main.c +++ b/main/i2c_simple_main.c @@ -23,27 +23,10 @@ static const char *TAG = "i2c-test"; -//INA260 -- Power meter -//address: 0x40 -#define INA260_SENSOR_ADDR 0x40 //Slave address of the INA260 -#define INA260_MANFID_REG 0xFE //should be 0x5449 - -//EMC2101 -- Fan and temp sensor controller -//address: 0x4C -#define EMC2101_SENSOR_ADDR 0x4C //Slave address of the EMC2101 -#define EMC2101_PRODUCTID_REG 0xFD //should be 0x16 or 0x28 - - - - - void app_main(void) { //test the LEDs ESP_LOGI(TAG, "Init LEDs!"); - initLEDs(); - // gpio_set_level(LEDX_R, 1); - // gpio_set_level(LEDZ_R, 1); ledc_init(); led_set(); @@ -53,20 +36,15 @@ void app_main(void) { DS4432U_read(); - // /* Read the EMC2101 WHO_AM_I register, on power up the register should have the value 0x16 or 0x28 */ - // ESP_ERROR_CHECK(register_read(EMC2101_SENSOR_ADDR, EMC2101_PRODUCTID_REG, data, 1)); - // ESP_LOGI(TAG, "EMC2101 PRODUCT ID = 0x%02X", data[0]); + DS4432U_set(0x00); + float core_voltage = 1.0; + uint8_t reg_setting; - // /* Read the INA260 WHO_AM_I register, on power up the register should have the value 0x5449 */ - // ESP_ERROR_CHECK(register_read(INA260_SENSOR_ADDR, INA260_MANFID_REG, data, 2)); - // ESP_LOGI(TAG, "INA260 MANF ID = 0x%02X%02X", data[0], data[1]); + reg_setting = voltage_to_reg(core_voltage); - // /* 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_OUT1_REG, data, 1)); - // ESP_LOGI(TAG, "DS4432U+ OUT1 = 0x%02X", data[0]); + ESP_LOGI(TAG, "Test set %.3fV = 0x%02X", core_voltage, reg_setting); - // /* Demonstrate writing by reseting the MPU9250 */ - // ESP_ERROR_CHECK(mpu9250_register_write_byte(MPU9250_PWR_MGMT_1_REG_ADDR, 1 << MPU9250_RESET_BIT)); + DS4432U_set(reg_setting); ///eek! ESP_ERROR_CHECK(i2c_master_delete()); ESP_LOGI(TAG, "I2C unitialized successfully");