#include "husb238.h"
#include <inttypes.h>
#include "portmacro.h"
#include "esp_log.h"

static uint8_t husb_registers[10];

void init_i2c()
{
    int i2c_master_port = 0;
    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = 12, // select GPIO specific to your project
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_io_num = 14, // select GPIO specific to your project
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = 400000, // select frequency specific to your project
        // .clk_flags = 0,          /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
    };
    ESP_ERROR_CHECK(i2c_param_config(i2c_master_port, &conf));
    ESP_ERROR_CHECK(i2c_driver_install(i2c_master_port, I2C_MODE_MASTER, 0, 0, 0));
}

void husb238_init(int i2c_master_port)
{
    unsigned char addressToRead = 0;
    i2c_master_write_read_device(i2c_master_port, HUSB238_I2CADDR_DEFAULT, &addressToRead, 1, husb_registers, 10, 100);

    for(int i = 0; i<10;i++)
    {
        ESP_LOGE(HUSB238TAG,"address %d-0x%02x",i,husb_registers[i]);
    }
}

void husb238_requestVoltage(int i2c_master_port,HUSB238_PDSelection voltage)
{
    uint8_t bytesToWrite[2] = {HUSB238_SRC_PDO,(voltage<<4)&0xf0};
    i2c_master_write_to_device(i2c_master_port,HUSB238_I2CADDR_DEFAULT,bytesToWrite,2,100/portTICK_PERIOD_MS);

    bytesToWrite[0] = HUSB238_GO_COMMAND;
    bytesToWrite[1] = 0x01;
    i2c_master_write_to_device(i2c_master_port,HUSB238_I2CADDR_DEFAULT,bytesToWrite,2,100/portTICK_PERIOD_MS);

    husb238_init(i2c_master_port);
}

float husb238_getMaxCurrent(int i2c_master_port,HUSB238_PDSelection voltage)
{
    husb238_init(i2c_master_port);

    uint8_t currentOption;

    switch (voltage)
    {
        case PD_SRC_5V:
        currentOption = husb_registers[2];
        break;
        case PD_SRC_9V:
        currentOption = husb_registers[3];
        break;
        case PD_SRC_12V:
        currentOption = husb_registers[4];
        break;
        case PD_SRC_15V:
        currentOption = husb_registers[5];
        break;
        case PD_SRC_18V:
        currentOption = husb_registers[6];
        break;
        case PD_SRC_20V:
        currentOption = husb_registers[7];
        break;
    
    default:
    return -1.0;
        break;
    }

    if(!(currentOption &0x80))
    return -1.0;


    switch (currentOption)
    {
    case CURRENT_0_5_A:
        return 0.5;
        break;
        case CURRENT_0_7_A:
        return 0.7;
        break;
        case CURRENT_1_0_A:
        return 1.0;
        break;
        case CURRENT_1_25_A:
        return 1.25;
        break;
        case CURRENT_1_5_A:
        return 1.5;
        break;
        case CURRENT_1_75_A:
        return 1.75;
        break;
        case CURRENT_2_0_A:
        return 2.0;
        break;
        case CURRENT_2_25_A:
        return 2.25;
        break;
        case CURRENT_2_50_A:
        return 2.5;
        break;
        case CURRENT_2_75_A:
        return 2.75;
        break;
        case CURRENT_3_0_A:
        return 3.0;
        break;
        case CURRENT_3_25_A:
        return 3.25;
        break;
        case CURRENT_3_5_A:
        return 3.5;
        break;
        case CURRENT_4_0_A:
        return 4.0;
        break;
        case CURRENT_4_5_A:
        return 4.5;
        break;
        case CURRENT_5_0_A:
        return 5.0;
        break;
    
    default:
        break;
    }
    return -1.0;
}