#include "../../hal.h"
#include "stdint.h"
#include "string.h"

#include "ts3a_i2c_applib.h"

#define PORT_NUM        1

uint8_t rcvBuf[PORT_NUM][128];
typedef struct
{
    uint8_t             port;           ///< iic port序号
    bool                busyFlg;

    uint8_t             *rx_buffer;     ///< 接收缓冲区
    uint16_t            buffer_size;    ///< 缓冲区大小
    I2C_ReadMode        read_mode;      ///< 读取模式：轮询或DMA
    volatile bool       dmaRxComplete;  ///< DMA传输完成标志（false-未完成，true-完成）
    volatile bool       dmaTxComplete;  ///< DMA传输完成标志（false-未完成，true-完成）
    uint8_t             transferStep;
    uint32_t            time;           ///< 读取time，用于计算超时
}I2C_Port;



static I2C_Port i2cPort[PORT_NUM];

extern uint32_t timer1TrigeCnt;

uint32_t HAL_GetTick(void)
{
    return timer1TrigeCnt;
}


void setIICMaster(void)
{
	I2C_MasterConfig(400);
	I2C_Start();//start
}



static I2C_Transfer_Status iicWrite(uint8_t port, uint32_t addr, uint8_t *data, uint16_t size)
{
    I2C_Transfer_Status err = I2C_TRANSFER_BUSY;
    I2C_Port *pPort = &i2cPort[port];
    
    switch(pPort->transferStep)
    {
    case 0:
        if(pPort->busyFlg == false)
        {
            pPort->busyFlg = true;
            pPort->transferStep = 1;
        }
        else
        {
            break;
        }
    case 1:
        if(pPort->read_mode == I2C_MODE_POLLING)
        {
            /// todo 添加轮询读取
            if(I2C_MasterPollWrite(addr, data, size) == size)
            {
                pPort->time = HAL_GetTick();
                pPort->transferStep = 2;
                pPort->dmaTxComplete = true;
            }
            else
            {
                err = I2C_TRANSFER_ERROR;
                pPort->transferStep = 0;
                break;
            }
        }
        else
        {

            pPort->dmaTxComplete = false;

            //status = HAL_I2C_Master_Transmit_DMA(pPort->hi2c, addr << 1, data, size);
            //if(status == HAL_OK)
            //{
            //    pPort->time = HAL_GetTick();
            //    pPort->transferStep = 2;
            //}
            //else
            //{
            //    HAL_I2C_DeInit(pPort->hi2c);  // 反初始化 I2C 外设
            //    HAL_I2C_Init(pPort->hi2c);    // 重新初始化 I2C 外设
            //    
            //    err = I2C_TRANSFER_ERROR;
            //    pPort->transferStep = 0;
            //    break;
            //}
        }
        
    case 2:
        if(pPort->dmaTxComplete == true)
        {
            pPort->dmaTxComplete = false;
            
            err = I2C_TRANSFER_DONE;

            pPort->transferStep = 0;
        }
        else
        {
            if(HAL_GetTick() > (100 + pPort->time))
            {
                err = I2C_TRANSFER_ERROR;
                pPort->transferStep = 0;
            }
        }
        
        break;
    default:
        pPort->transferStep = 0;
        err = I2C_TRANSFER_ERROR;
        break;
    }

    if((err == I2C_TRANSFER_DONE) || (err == I2C_TRANSFER_ERROR))
    {
        pPort->busyFlg = false;
    }
    
    return err;
}

static I2C_Transfer_Status iicRead(uint8_t port, uint32_t addr, uint8_t *data, uint16_t size)
{
    I2C_Transfer_Status err = I2C_TRANSFER_BUSY;
    I2C_Port *pPort = &i2cPort[port];
    
    switch(pPort->transferStep)
    {
    case 0:
        if(pPort->busyFlg == false)
        {
            pPort->busyFlg = true;
            pPort->transferStep = 1;
        }
        else
        {
            break;
        }
    case 1:
        if(pPort->read_mode == I2C_MODE_POLLING)
        {
            /// todo 添加轮询读取
            
            

            if(I2C_MasterPollRead(addr, pPort->rx_buffer, size) == size)
            {
                pPort->time = HAL_GetTick();
                pPort->transferStep = 2;

                pPort->dmaRxComplete = true;
            }
            else
            {
                err = I2C_TRANSFER_ERROR;
                pPort->transferStep = 0;
                break;
            }
        }
        else
        {
            //status = HAL_I2C_Master_Receive_DMA(pPort->hi2c, addr << 1, pPort->rx_buffer, size);
            //if(status == HAL_OK)
            //{
            //    pPort->time = HAL_GetTick();
            //    pPort->transferStep = 2;
            //}
            //else
            //{
            //    err = I2C_TRANSFER_ERROR;
            //    pPort->transferStep = 0;
            //    break;
            //}
        }
        
    case 2:
        if(pPort->dmaRxComplete == true)
        {
            pPort->dmaRxComplete = false;
            
            err = I2C_TRANSFER_DONE;
            memcpy((void *)data, pPort->rx_buffer, size);

            pPort->transferStep = 0;
        }
        else
        {
            if(HAL_GetTick() > (100 + pPort->time))
            {
                err = I2C_TRANSFER_ERROR;
                pPort->transferStep = 0;
            }
        }
        
        break;
    default:
        err = I2C_TRANSFER_ERROR;
        pPort->transferStep = 0;
        break;
    }

    if((err == I2C_TRANSFER_DONE) || (err == I2C_TRANSFER_ERROR))
    {
        pPort->busyFlg = false;
    }

    return err;
}



bool I2C_Init(uint8_t port, I2C_PlatformInterface_t *com)
{
    /// todo 添加port合法性判断
    memset((void *)&i2cPort[port], 0, sizeof(I2C_Port));
    
    setIICMaster();

    memset((void *)&rcvBuf[port], 0, sizeof(sizeof(rcvBuf)/PORT_NUM));

    com->read = iicRead;
    com->write = iicWrite;
    com->delayMs = delay_ms;
    com->getTimeMs = HAL_GetTick;
    com->port = port;

    i2cPort[port].read_mode = I2C_MODE_POLLING;
    i2cPort[port].port = port;
    i2cPort[port].buffer_size = sizeof(rcvBuf)/PORT_NUM;
    i2cPort[port].rx_buffer = (uint8_t *)&rcvBuf[port];
    
    return true;
}


