/**
 * @file hv_pm51_driver_I2C.c
 * @brief HT7135 PM51 I2C Driver.
 * @details Sample I2C driver, only 7bit I2C slave addr supported
 * @author HiView SoC Software Team
 * @version 0.0.1
 * @date 20230301
 * @copyright Copyright(c),2023-3, Hiview Software. All rights reserved.
 * @par History: 
 * <table>
 * <tr><th>author                     <th>date           <th>description
 * <tr><td>HiView SoC Software Team   <td>20230301       <td>Create and first Version.
 * </table>
**/

#include "hv_pm51_Base.h"
#include "hv_pm51_Reg.h"
#include "hv_pm51_Setting.h"
#include "hv_pm51_driver_Reg.h"
#include "hv_pm51_driver_I2C.h"
#include "hv_pm51_driver_UART.h"
#include "hv_pm51_driver_Interrupt.h"
#include "hv_pm51_app_Sys.h"
#include "hv_pm51_app_PM.h"

#if MI2C_ENABLE

void Hv_PM51_I2C_Init(void)
{
	/* not config in pinshare */
    Hv_PM51_Reg_WriteMask(HS_Standby__SH08_TOP_STBY__reg_mi2c_scl_func_sel_ADDR,
                      HS_Standby__SH08_TOP_STBY__reg_mi2c_scl_func_sel_BITSTART,
                      HS_Standby__SH08_TOP_STBY__reg_mi2c_scl_func_sel_BITEND, 0);
    Hv_PM51_Reg_WriteMask(HS_Standby__SH08_TOP_STBY__reg_mi2c_scl_io_ctrl_ADDR,
                      HS_Standby__SH08_TOP_STBY__reg_mi2c_scl_io_ctrl_BITSTART,
                      HS_Standby__SH08_TOP_STBY__reg_mi2c_scl_io_ctrl_BITEND, 0xD9); /* [7]OD[6]IE[5]PD[4]PU[3]SMT[2]PIN2[1]PIN1[0]OE */ //0x53

    Hv_PM51_Reg_WriteMask(HS_Standby__SH08_TOP_STBY__reg_mi2c_sda_func_sel_ADDR,
                      HS_Standby__SH08_TOP_STBY__reg_mi2c_sda_func_sel_BITSTART,
                      HS_Standby__SH08_TOP_STBY__reg_mi2c_sda_func_sel_BITEND, 0);
    Hv_PM51_Reg_WriteMask(HS_Standby__SH08_TOP_STBY__reg_mi2c_sda_io_ctrl_ADDR,
                      HS_Standby__SH08_TOP_STBY__reg_mi2c_sda_io_ctrl_BITSTART,
                      HS_Standby__SH08_TOP_STBY__reg_mi2c_sda_io_ctrl_BITEND, 0xD9); //0x51

    Hv_PM51_Reg_WriteMask(HS_Standby__SH08_TOP_STBY__reg_mi2c_sda_in_in_sel_ADDR,
                      HS_Standby__SH08_TOP_STBY__reg_mi2c_sda_in_in_sel_BITSTART,
                      HS_Standby__SH08_TOP_STBY__reg_mi2c_sda_in_in_sel_BITEND, 0x0);

    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_clk_en_ADDR,
                      HS_Standby__standby_i2c_reg__reg_clk_en_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_clk_en_BITEND, 1);      /*  i2c_clk_en */
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_speed_ADDR,
                      HS_Standby__standby_i2c_reg__reg_speed_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_speed_BITEND, I2C_SPEED);   /*  i2c_clk_speed_div */
    return;
}

UCHAR8 Hv_PM51_I2C_E2PReadByte(UCHAR8 ucSlvID, USHORT16 usAddr, iBOOL bSub2AddrEn)
{   
    xULONG32 ulTempData = 0;
    xUSHORT16 usTimeoutCount = 0;

    /* clk_en = 1,ucSlvID = (A2>>1) */
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_addr_ADDR,
                      HS_Standby__standby_i2c_reg__reg_addr_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_addr_BITEND, usAddr);
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_slv_id_ADDR,
                      HS_Standby__standby_i2c_reg__reg_slv_id_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_slv_id_BITEND, ucSlvID);

    if(bSub2AddrEn)
    {
        Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_addr_length_ADDR,
                          HS_Standby__standby_i2c_reg__reg_addr_length_BITSTART,
                          HS_Standby__standby_i2c_reg__reg_addr_length_BITEND, 1);
    }
    else
    {
        Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_addr_length_ADDR,
                          HS_Standby__standby_i2c_reg__reg_addr_length_BITSTART,
                          HS_Standby__standby_i2c_reg__reg_addr_length_BITEND, 0);
    }
    
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_rw_sel_ADDR,
                      HS_Standby__standby_i2c_reg__reg_rw_sel_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_rw_sel_BITEND,1);       /* i2c = read,rw=1 */
    /* Hv_PM51_Reg_WriteMask(REG_DATA_LENGTH,8,15,0);    i2c data lenth */
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_start_ADDR,
                      HS_Standby__standby_i2c_reg__reg_start_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_start_BITEND, 0);       /* i2c tranmit start */
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_start_ADDR,
                      HS_Standby__standby_i2c_reg__reg_start_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_start_BITEND, 1);       /* i2c tranmit start */
                      
    /* Hv_PM51_Sys_DelayMs(1);  wait for eeprom operation */
    while (((Hv_PM51_Reg_Read(HS_Standby__standby_i2c_reg__reg_done_out_ADDR) & BIT_17)) == 0x0 
            && (usTimeoutCount++<I2C_TIMEOUT_MAX));
    
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_done_out_ADDR,
                      HS_Standby__standby_i2c_reg__reg_done_out_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_done_out_BITEND, 0);

    if(usTimeoutCount >= I2C_TIMEOUT_MAX)
    {
        Hv_PM51_Uart_Print("I2C Read time out!\r\n");
    }

    ulTempData = Hv_PM51_Reg_Read(HS_Standby__standby_i2c_reg__reg_iic_rxdata_ADDR);
    
    return (ulTempData & 0xFF);
}

void Hv_PM51_I2C_E2PWriteByte(UCHAR8 ucSlvID,USHORT16 usAddr,iBOOL bSub2AddrEn, UCHAR8 ucTransData)
{    
    xULONG32 ulTempData = 0;
    xUSHORT16 usTimeoutCount = 0;

    /* todo add i2c polling check if ack is given */
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_addr_ADDR,
                      HS_Standby__standby_i2c_reg__reg_addr_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_addr_BITEND, usAddr);
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_slv_id_ADDR,
                      HS_Standby__standby_i2c_reg__reg_slv_id_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_slv_id_BITEND, ucSlvID);
    if(bSub2AddrEn)
    {
        Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_addr_length_ADDR,
                          HS_Standby__standby_i2c_reg__reg_addr_length_BITSTART,
                          HS_Standby__standby_i2c_reg__reg_addr_length_BITEND, 1);
    }
    else
    {
        Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_addr_length_ADDR,
                          HS_Standby__standby_i2c_reg__reg_addr_length_BITSTART,
                          HS_Standby__standby_i2c_reg__reg_addr_length_BITEND, 0);
    }
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_rw_sel_ADDR,
                      HS_Standby__standby_i2c_reg__reg_rw_sel_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_rw_sel_BITEND, 0);       /* i2c = write,rw=0 */
    /* Hv_PM51_Reg_WriteMask(REG_DATA_LENGTH,8,15,0);    //i2c data lenth */
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_start_ADDR,
                      HS_Standby__standby_i2c_reg__reg_start_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_start_BITEND, 0);       /* i2c tranmit start */
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_start_ADDR,
                      HS_Standby__standby_i2c_reg__reg_start_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_start_BITEND, 1);       /* i2c tranmit start */
                      
    ulTempData = ucTransData;
    ulTempData = ulTempData << 24;
    Hv_PM51_Reg_Write(HS_Standby__standby_i2c_reg__reg_iic_txdata_ADDR, ulTempData);         /* write tx fifo */
    Hv_PM51_Sys_DelayMs(1);                                        /*  wait for eeprom operation */
    
    while (((Hv_PM51_Reg_Read(HS_Standby__standby_i2c_reg__reg_done_out_ADDR) & BIT_17) == 0x0) 
            && (usTimeoutCount++ < I2C_TIMEOUT_MAX));
    
    Hv_PM51_Reg_WriteMask(HS_Standby__standby_i2c_reg__reg_done_out_ADDR,
                      HS_Standby__standby_i2c_reg__reg_done_out_BITSTART,
                      HS_Standby__standby_i2c_reg__reg_done_out_BITEND, 0);
    if(usTimeoutCount >= I2C_TIMEOUT_MAX)
    {
        Hv_PM51_Uart_Print("I2C write time out!\r\n");
    }
    
    return;
}

#endif