/*
 * adc7291.c
 */

#include "adc7291.h"
#include "main.h"

extern I2C_HandleTypeDef hi2c1;

ad7291_dev_t hgpio_ps1_adc_U9 = {0};
ad7291_dev_t hgpio_ps2_adc_U10 = {0};
ad7291_dev_t hgpio_oring_circuit_adc_U12 = {0};

/**
 * @brief ad7291 i2c write function
 */
uint8_t ad7291_i2c_write(void* intf_hdl, uint16_t slv_addr, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
    I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef*)intf_hdl;
    int8_t sts = AD7291_ERR;
    uint8_t tx_arr[3] = {0};
    tx_arr[0]= reg_addr;
    tx_arr[1]= data[0];
    if (len>1)
        tx_arr[2]= data[1];
    len++;
    if(HAL_I2C_Master_Transmit(hi2c, (uint16_t)(slv_addr), tx_arr, 1, 500) == HAL_OK)
    {
        sts =AD7291_SCS;

    }
    else
    {
        sts =AD7291_ERR;
    }
    return sts;
}

/**
 * @brief ad7291 i2c read function
 */
uint8_t ad7291_i2c_read(void* intf_hdl, uint16_t slv_addr, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
    I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef*)intf_hdl;
    int8_t sts = AD7291_ERR;
    if(HAL_I2C_Master_Transmit(hi2c, (uint16_t)(slv_addr), &reg_addr, 1, 500) == HAL_OK)
    {
        if(HAL_I2C_Master_Receive(hi2c, (uint16_t)(slv_addr), data, len, 500) == HAL_OK)
        {
            sts =AD7291_SCS;
        }
        else
        {
            sts =AD7291_ERR;
        }
    }
    else
    {
        sts =AD7291_ERR;
    }
    return sts;
}

/*!
 *  @brief init power board adc7291
 */
void pwr_brd_adc7291_init(uint8_t ahw_id)
{
    switch(ahw_id)
    {
    case ADC_AD7291_PS_1:
    {
        hgpio_ps1_adc_U9.io_intf_hdle = &hi2c1;
        hgpio_ps1_adc_U9.slave_address = 0x56;
        hgpio_ps1_adc_U9.write = ad7291_i2c_write;
        hgpio_ps1_adc_U9.read = ad7291_i2c_read;
    }
    break;

    case ADC_AD7291_PS_2:
    {
        hgpio_ps2_adc_U10.io_intf_hdle = &hi2c1;
        hgpio_ps2_adc_U10.slave_address = 0x5C;
        hgpio_ps2_adc_U10.write = ad7291_i2c_write;
        hgpio_ps2_adc_U10.read = ad7291_i2c_read;
    }
    break;

    case ADC_AD7291_ORING_CIRCUIT:
    {
        hgpio_oring_circuit_adc_U12.io_intf_hdle = &hi2c1;
        hgpio_oring_circuit_adc_U12.slave_address = 0x5E;
        hgpio_oring_circuit_adc_U12.write = ad7291_i2c_write;
        hgpio_oring_circuit_adc_U12.read = ad7291_i2c_read;
    }
    break;

    default:
        break;

    }
}

/**
 * @brief ad7291 null poniter check function
 */
int8_t null_ptr_check(ad7291_dev_t* ad7291_hdl)
{
    int8_t sts = AD7291_ERR;
    if ((ad7291_hdl == NULL) || (ad7291_hdl->read == NULL) || (ad7291_hdl->write == NULL))
    {
        sts=AD7291_NULL_PTR;
    }
    else
    {
        sts=AD7291_SCS;
    }
    return sts;
}

/**
 * @brief ad7291_init function
 */
e_ad7291_ret_sts ad7291_init(ad7291_dev_t* ad7291_hdl)
{
    e_ad7291_ret_sts sts = AD7291_ERR;
    int16_t temp=1;
    temp=temp;
    sts = null_ptr_check(ad7291_hdl);
    if(sts==AD7291_SCS)
    {
        sts=AD7291_SetRegisterValue(ad7291_hdl, AD7291_REG_COMMAND, AD7291_COMMAND_DELAY |0xFF00);
        if(sts==AD7291_SCS)
        {
            sts=AD7291_SCS;
        }
    }
    else
    {
        sts=AD7291_COM_ERR;
    }
    return (sts);
}

/**
 * @brief ad7291 get voltage conversion result function
 */
e_ad7291_ret_sts AD7291_GetVoltageConversionResults(ad7291_dev_t* ad7291_hdl,e_ad7291_chnl chnl,float* data)
{
    chnl = 0x20;
    unsigned short commandValue = 0;
    unsigned char mask = 0x80;
    mask=mask;
    unsigned char channelsNumber = 0;
    channelsNumber = channelsNumber;
    unsigned short voltageData[16] = {0, };
    unsigned char channel = 0;
    channel = channel;
    unsigned char channelAddress = 0;

    AD7291_GetRegisterValue(ad7291_hdl,AD7291_REG_COMMAND,
            (unsigned short*)&commandValue,
            1);

    commandValue = (commandValue & 0xFF00) >> 8;
    while(mask)
    {
        if(commandValue & mask)
        {
            channelsNumber++;
        }
        mask = mask >> 1;
    }

    if(channelsNumber)
    {
        AD7291_GetRegisterValue(ad7291_hdl,AD7291_REG_VOLTAGE,
                voltageData,
                channelsNumber);
    }
    for(channel = 0; channel < channelsNumber; channel++)
    {
        channelAddress = (voltageData[channel] & 0xF000) >> 12;
        data[channelAddress] = (float)((float)(voltageData[channel] & 0x0FFF) * 2.5) / 4096 ;

    }

    return AD7291_SCS;
}

/**
 * @brief ad7291 Set Register Value function
 */
e_ad7291_ret_sts AD7291_SetRegisterValue(ad7291_dev_t* ad7291_hdl , unsigned char registerAddress,unsigned short registerValue)
{

    e_ad7291_ret_sts sts = AD7291_ERR;
    unsigned char sendData[2]={0};
    // sendData[0] = registerAddress;
    sendData[0] = ((registerValue & 0xFF00) >> 8);
    sendData[1] = ((registerValue & 0x00FF));
    sts=ad7291_hdl->write(ad7291_hdl->io_intf_hdle,ad7291_hdl->slave_address,registerAddress,sendData,2);
    return(sts);
}

/**
 * @brief ad7291 get Register Value function
 */
void AD7291_GetRegisterValue(ad7291_dev_t* ad7291_hdl,unsigned char registerAddress,
        unsigned short* registerValue,
        unsigned char readsNumber)
{
    unsigned char receiveBuffer[16] = {0};
    unsigned char read = 0;
    uint8_t testBuffer=1;
    e_ad7291_ret_sts sts=AD7291_ERR;
    sts=null_ptr_check(ad7291_hdl);
    if(sts!=AD7291_SCS)
    {
        sts=AD7291_NULL_PTR;
    }
    else
    {
        sts=ad7291_hdl->write(ad7291_hdl->io_intf_hdle,ad7291_hdl->slave_address,registerAddress,&testBuffer,1);
        if(sts == AD7291_SCS)
        {
            sts = AD7291_SCS;
        }else
        {
            sts = AD7291_ERR;
        }
        sts=ad7291_hdl->read(ad7291_hdl->io_intf_hdle,ad7291_hdl->slave_address,registerAddress,receiveBuffer,15);
        if(sts == AD7291_SCS)
        {
            sts = AD7291_SCS;
        }else
        {
            sts = AD7291_ERR;
        }
    }

    for(read = 0; read < readsNumber; read++)
    {
        registerValue[read] = ((unsigned short)receiveBuffer[read * 2] << 8) +
                receiveBuffer[read * 2 + 1];
    }
}

/**
 * @brief ad7291 get voltage convertion function
 */
e_ad7291_ret_sts ad7291_get_voltage_convertion(ad7291_dev_t* ad7291_hdl,e_ad7291_chnl chnl,float *data)
{
    e_ad7291_ret_sts sts = AD7291_ERR;
    sts = AD7291_GetVoltageConversionResults(ad7291_hdl,chnl,data);
    return (sts);
}

/**
 * @brief ad7291 Self test function
 */
e_ad7291_ret_sts ad7291_self_test(ad7291_dev_t *ad7291_hdl)
{
    e_ad7291_ret_sts sts = 0;
    uint8_t write_data = 26;
    uint8_t read_data = 0;
    uint8_t AD7291_REG_ADDR = 0x00;

    sts=ad7291_hdl->write(ad7291_hdl->io_intf_hdle,ad7291_hdl->slave_address,AD7291_REG_ADDR,(uint8_t*)&write_data,1);
    {
        sts=ad7291_hdl->read(ad7291_hdl->io_intf_hdle,ad7291_hdl->slave_address,AD7291_REG_ADDR,(uint8_t*)&read_data,10);
        {
            if(write_data == read_data)
            {
                sts = AD7291_SCS;
            }
            else
            {
                sts = AD7291_ERR;
            }
        }
    }
    return sts;
}
