CLSH1001-Firmware/include/sw7203/sw7203.c

296 lines
11 KiB
C
Raw Normal View History

2024-03-07 05:21:06 +08:00
#include <sw7203.h>
2024-03-08 01:45:59 +08:00
#include "driver/i2c_master.h"
2024-03-07 05:21:06 +08:00
#include "esp_log.h"
2024-03-19 02:44:58 +08:00
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
2024-03-07 05:21:06 +08:00
2024-03-08 01:45:59 +08:00
uint8_t sw7203_I2C_address_find(i2c_master_bus_handle_t I2C_bus_handle)
2024-03-07 05:21:06 +08:00
{
2024-03-08 01:45:59 +08:00
esp_err_t errcode;
errcode = i2c_master_probe(I2C_bus_handle, sw7203_I2c_0x3C, -1);
if (errcode == ESP_OK)
{
return 0x3C;
}
errcode = i2c_master_probe(I2C_bus_handle, sw7203_I2c_0x1C, -1);
if (errcode == ESP_OK)
{
return 0x1C;
}
errcode = i2c_master_probe(I2C_bus_handle, sw7203_I2c_0x18, -1);
if (errcode == ESP_OK)
{
return 0x18;
}
errcode = i2c_master_probe(I2C_bus_handle, sw7203_I2c_0x38, -1);
if (errcode == ESP_OK)
{
return 0x38;
}
return -1;
2024-03-07 05:21:06 +08:00
}
2024-03-19 02:44:58 +08:00
void sw7203_register_change_bitmask(uint8_t *reg_addr, uint8_t *data, uint8_t *bitmask)
2024-03-07 05:21:06 +08:00
{
2024-03-08 01:45:59 +08:00
uint8_t original_reg;
2024-03-19 02:44:58 +08:00
if (__sw7203_driver_config__.I2CBusBusyEnable == 1)
{
while (*SW7203_Mutex != 0)
{
vTaskDelay(50 / portTICK_PERIOD_MS);
}
*SW7203_Mutex = 1;
ESP_ERROR_CHECK(i2c_master_transmit_receive(SW7203_I2C_handle, reg_addr, 1, &original_reg, 1, -1));
*SW7203_Mutex = 0;
}
else
ESP_ERROR_CHECK(i2c_master_transmit_receive(SW7203_I2C_handle, reg_addr, 1, &original_reg, 1, -1));
uint8_t diff = (original_reg ^ (*data)) & (*bitmask);
2024-03-08 01:45:59 +08:00
if (diff)
{
2024-03-19 02:44:58 +08:00
uint16_t write_data = (*reg_addr) << 8 | (diff ^ original_reg);
if (__sw7203_driver_config__.I2CBusBusyEnable == 1)
{
while (SW7203_Mutex != 0)
{
vTaskDelay(50 / portTICK_PERIOD_MS);
}
SW7203_Mutex = 1;
ESP_ERROR_CHECK(i2c_master_transmit(SW7203_I2C_handle, &write_data, 2, -1));
*SW7203_Mutex = 0;
}
else
ESP_ERROR_CHECK(i2c_master_transmit(SW7203_I2C_handle, &write_data, 2, -1));
2024-03-08 01:45:59 +08:00
}
2024-03-07 05:21:06 +08:00
}
2024-03-19 02:44:58 +08:00
esp_err_t sw7203_reg_read(uint8_t reg_addr, uint8_t *data)
{
esp_err_t errcode;
if (__sw7203_driver_config__.I2CBusBusyEnable == 1)
{
while (SW7203_Mutex != 0)
{
vTaskDelay(50 / portTICK_PERIOD_MS);
}
SW7203_Mutex = 1;
errcode = i2c_master_transmit(SW7203_I2C_handle, data, 2, -1);
*SW7203_Mutex = 0;
}
else
errcode = i2c_master_transmit(SW7203_I2C_handle, data, 2, -1);
return errcode;
}
2024-03-07 05:21:06 +08:00
2024-03-19 02:44:58 +08:00
esp_err_t sw7203_driver_install(sw7203_config_t *sw7203_config, i2c_master_bus_handle_t I2C_bus_handle, uint8_t I2C_address)
2024-03-07 05:21:06 +08:00
{
2024-03-08 01:45:59 +08:00
if (I2C_address == -1)
{
return ESP_ERR_NOT_ALLOWED;
}
2024-03-07 05:21:06 +08:00
esp_err_t errcode;
2024-03-08 01:45:59 +08:00
i2c_device_config_t sw7203_i2c_dev_config = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = I2C_address,
.scl_speed_hz = 100000};
ESP_ERROR_CHECK(errcode = i2c_master_bus_add_device(I2C_bus_handle, &sw7203_i2c_dev_config, &SW7203_I2C_handle));
2024-03-19 02:44:58 +08:00
if (sw7203_config->SW7203_control_mode.I2CBusBusyEnable == 0)
{
SW7203_Mutex = sw7203_config->Mutex;
__sw7203_driver_config__.I2CBusBusyEnable = 1;
}
else
__sw7203_driver_config__.I2CBusBusyEnable = 0;
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[0][0], &sw7203_config->connectDetect.hex, &SW7203RegAddress_bitmask[0][1]); // {0x18, 0b00010011}, 0
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[1][0], &sw7203_config->i2cAddress, &SW7203RegAddress_bitmask[1][1]); // {0x1A, 0b00000011}, 1
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[2][0], &sw7203_config->funcConfig1.hex, &SW7203RegAddress_bitmask[2][1]); // {0x20, 0b11100111}, 2
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[3][0], &sw7203_config->funcConfig2.hex, &SW7203RegAddress_bitmask[3][1]); // {0x21, 0b11111111}, 3
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[4][0], &sw7203_config->funcConfig3.hex, &SW7203RegAddress_bitmask[4][1]); // {0x22, 0b11110000}, 4
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[5][0], &sw7203_config->funcConfig4.hex, &SW7203RegAddress_bitmask[5][1]); // {0x30, 0b11001111}, 5
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[6][0], &sw7203_config->funcConfig5.hex, &SW7203RegAddress_bitmask[6][1]); // {0x31, 0b00001111}, 6
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[7][0], &sw7203_config->funcConfig6.hex, &SW7203RegAddress_bitmask[7][1]); // {0x32, 0b11011111}, 7
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[8][0], &sw7203_config->funcConfig7.hex, &SW7203RegAddress_bitmask[8][1]); // {0x33, 0b11111111}, 8
uint8_t data_up, data_lb;
int tmp;
if (sw7203_config->chargeVoltage_mV < 3000)
{
data_up = 0;
data_lb = 0;
}
else if (sw7203_config->chargeVoltage_mV > 19200)
{
data_up = 0b11001010;
data_lb = 0b00000100;
}
else
{
tmp = ((sw7203_config->chargeVoltage_mV - 3000) / 10);
data_up = (uint8_t)(tmp >> 3) & 0xff;
data_lb = (tmp) & 0b0000000000000111;
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[9][0], &data_up, &SW7203RegAddress_bitmask[9][1]); // {0x34, 0b11111111}, 9
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[10][0], &data_lb, &SW7203RegAddress_bitmask[10][1]); // {0x35, 0b00000111}, 10
if (sw7203_config->trickleVoltage_mV < 2500)
{
data_up = 0;
}
else if (sw7203_config->trickleVoltage_mV > 13200)
{
data_up = 107;
}
else
{
data_up = ((sw7203_config->trickleVoltage_mV - 2500) / 100);
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[11][0], &data_up, &SW7203RegAddress_bitmask[11][1]); // {0x36, 0b01111111}, 11
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[12][0], &sw7203_config->trickleConfig.hex, &SW7203RegAddress_bitmask[12][1]); // {0x37, 0b00001111}, 12
if (sw7203_config->chargeVBUSVoltageLimit_mV < 4000)
{
data_up = 0;
}
else if (sw7203_config->chargeVBUSVoltageLimit_mV > 20000)
{
data_up = 160;
}
else
{
data_up = ((sw7203_config->chargeVBUSVoltageLimit_mV - 4000) / 100);
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[13][0], &data_up, &SW7203RegAddress_bitmask[13][1]); // {0x38, 0b11111111}, 13
if (sw7203_config->chargeVBUSCurrentLimit_mA < 500)
{
data_up = 0;
}
else if (sw7203_config->chargeVBUSCurrentLimit_mA > 6850)
{
data_up = 127;
}
else
{
data_up = ((sw7203_config->chargeVBUSCurrentLimit_mA - 500) / 50);
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[14][0], &data_up, &SW7203RegAddress_bitmask[14][1]); // {0x39, 0b01111111}, 14
if (sw7203_config->chargeVBATCurrentLimit_mA < 100)
{
data_up = 0;
}
else if (sw7203_config->chargeVBATCurrentLimit_mA > 12000)
{
data_up = 119;
}
else
{
data_up = ((sw7203_config->chargeVBATCurrentLimit_mA - 100) / 100);
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[15][0], &data_up, &SW7203RegAddress_bitmask[15][1]); // {0x3A, 0b01111111}, 15
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[16][0], &sw7203_config->NVDCConfig1.hex, &SW7203RegAddress_bitmask[16][1]); // {0x40, 0b01000011}, 16
if (sw7203_config->chargeLDOCurrentLimit_mA < 100)
{
data_up = 0;
}
else if (sw7203_config->chargeLDOCurrentLimit_mA > 2000)
{
data_up = 19;
}
else
{
data_up = ((sw7203_config->chargeLDOCurrentLimit_mA - 100) / 100);
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[17][0], &data_up, &SW7203RegAddress_bitmask[17][1]); // {0x41, 0b00011111}, 17
if (sw7203_config->VSYSMinVoltage_mV < 3000)
{
data_up = 0;
}
else if (sw7203_config->VSYSMinVoltage_mV > 16600)
{
data_up = 68;
}
else
{
data_up = ((sw7203_config->VSYSMinVoltage_mV - 3000) / 200);
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[18][0], &data_up, &SW7203RegAddress_bitmask[18][1]); // {0x42, 0b01111111}, 18
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[19][0], &sw7203_config->NTCConfig.hex, &SW7203RegAddress_bitmask[19][1]); // {0x43, 0b11111111}, 19
2024-03-08 01:45:59 +08:00
return ESP_OK;
}
2024-03-19 02:44:58 +08:00
void sw7203SwitchOutput(sw7203_Vout_config_t *config)
{
uint8_t data_up, data_lb;
int tmp;
if (config->VBUSVoltage_mV < 3000)
{
data_up = 0;
data_lb = 0;
}
else if (config->VBUSVoltage_mV > 22000)
{
data_up = 0b11101101;
data_lb = 0b00000100;
}
else
{
tmp = ((config->VBUSVoltage_mV - 3000) / 10);
data_up = (uint8_t)(tmp >> 3) & 0xff;
data_lb = (tmp) & 0b0000000000000111;
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[20][0], &data_up, &SW7203RegAddress_bitmask[20][1]); // {0x23, 0b11111111} 20
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[21][0], &data_lb, &SW7203RegAddress_bitmask[21][1]); // {0x24, 0b00000111} 21
if (config->VBUSCurrentLimit_mA < 500)
{
data_up = 0;
}
else if (config->VBUSCurrentLimit_mA > 6850)
{
data_up = 127;
}
else
{
data_up = (uint8_t)((config->VBUSCurrentLimit_mA - 500) / 50);
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[22][0], &data_up, &SW7203RegAddress_bitmask[22][1]); // {0x25, 0b01111111} 22
if (config->VBATCurrentLimit_mA < 100)
{
data_up = 0;
}
else if (config->VBATCurrentLimit_mA > 12000)
{
data_up = 119;
}
else
{
data_up = (uint8_t)((config->VBUSCurrentLimit_mA - 100) / 100);
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[23][0], &data_up, &SW7203RegAddress_bitmask[23][1]); // {0x26, 0b01111111} 23
if (config->VBATVoltageLimit_mV < 2700)
{
data_up = 0;
}
else if (config->VBATVoltageLimit_mV > 13200)
{
data_up = 105;
}
else
{
data_up = (uint8_t)((config->VBATVoltageLimit_mV - 2700) / 100);
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[24][0], &data_up, &SW7203RegAddress_bitmask[24][1]); // {0x27, 0b01111111} 24
if (config->VBATVoltageLimitHysteresis_mV < 400)
{
data_up = 0;
}
else if (config->VBATVoltageLimitHysteresis_mV > 2000)
{
data_up = 16;
}
else
{
data_up = (uint8_t)((config->VBATVoltageLimitHysteresis_mV - 400) / 100);
}
sw7203_register_change_bitmask(&SW7203RegAddress_bitmask[25][0], &data_up, &SW7203RegAddress_bitmask[25][1]); // {0x28, 0b00011111} 25
}
esp_err_t sw7203_driver_uninstall(i2c_master_bus_handle_t I2C_bus_handle)
{
return i2c_master_bus_rm_device(SW7203_I2C_handle);
}