#include "fingerCmd.h"


#define CMD_GET_CHANNEL_NUM			         	0x01  ///< 读取通道数量
#define CMD_GET_SENSOR_CAP_DATA                 0x60  ///< 读取传感器数据
#define CMD_GET_SENSOR_CHANNEL                  0x62  ///< 读取通道数量
#define CMD_SET_SENSOR_AUTO_DAC                 0x63  ///< 自动dac
#define CMD_GET_SENSOR_TEST_HZ                  0x6C  ///< 读取采样率
													  ///<
#define CMD_SET_SENSOR_IIC_ADDR                 0x70  ///< 设置传感器IIC地址
#define CMD_GET_SENSOR_IIC_ADDR                 0x71  ///< 读取传感器IIC地址
#define CMD_SET_SENSOR_CDC_SYNC                 0x72  ///< 采集停止，用于同步
#define CMD_SET_SENSOR_CDC_START_OFFSET         0x73  ///< 设置电容开始偏移
#define CMD_SET_SENSOR_FACTOR                   0x76  ///< 恢复出厂设置
#define CMD_SET_SENSOR_RESTART                  0x77  ///< 软件复位
#define CMD_SET_SENSOR_CHANNEL_ENABLE           0x7B  ///< 通道使能
#define CMD_SET_SENSOR_CHANNEL_BASE_RESET       0x7C  ///< 单独通道复位
#define CMD_SET_SENSOR_SEND_TYPE                0x7F  ///< 数据传输类型
													  ///<
#define CMD_GET_VERSION                         0xA0  ///< 读取软件版本
#define CMD_SOFT_RESTART                        0xA1  ///< 软件复位
#define CMD_GET_PRG                             0xA6  ///< 获取项目类型




/**
* @brief		����У��ֵ
* @param[in]
* @return
* @details
*/
static void CalcSum(uint8_t *pdata, uint16_t n)
{
	uint16_t sum = 0;
	for (int i = 0; i < n; i++)
	{
		sum += *(pdata + i);
	}
	*(pdata + n) = sum & 0xFF;
	*(pdata + n + 1) = sum >> 8;
}

/**
* @brief		���У��ֵ
* @param[in]	pdata:����ָ��
*				n�����ݸ���
* @return		1����ȷ
*				0������
* @details
*/
bool CheckSum(uint8_t* pdata, uint16_t n)
{
    uint16_t sum = 0;
    for (int i = 0; i < n; i++)
    {
        sum += *(pdata + i);
    }
    if(*(pdata + n) == (sum & 0xFF) && *(pdata + n + 1) == (sum >> 8))
        return true;
    else
        return false;
}


/// 设置iic地址
I2C_Transfer_Status fingerCmdWriteAddr(I2C_PlatformInterface_t        *comPort, uint8_t addr, uint8_t addrNew)
{
    I2C_Transfer_Status err = I2C_TRANSFER_BUSY;
    I2C_Transfer_Status tranStatus = I2C_TRANSFER_BUSY;

    switch(comPort->step)
    {
    case 0:
        memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));

        comPort->cmd.header = 0x55AA;
        comPort->cmd.rev = 0x03;
        comPort->cmd.cmd = CMD_SET_SENSOR_IIC_ADDR;
        comPort->cmd.para[3] = addrNew;

        CalcSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
        comPort->step = 1;
    case 1:
        tranStatus = comPort->write(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            comPort->step = 2;
            memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }
        
        break;
    case 2:
        tranStatus = comPort->read(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            bool checkSum = CheckSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
            if((checkSum == true) && (comPort->cmd.cmd == (CMD_SET_SENSOR_IIC_ADDR|0x80)))
            {
                err = I2C_TRANSFER_DONE;
            }
            else
            {
                err = I2C_TRANSFER_ERROR;
            }
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }
        else
        {
            break;
        }
    default:
        comPort->step = 0;
        break;
    }

    if(err != I2C_TRANSFER_BUSY)
    {
        comPort->step = 0;
    }

    return err;
}

/// 读取iic地址, 一般使用广播地址读取，addr=0,返回>0小于7f
I2C_Transfer_Status fingerCmdReadAddr(I2C_PlatformInterface_t        *comPort, uint8_t addr, uint8_t *pAddrData)
{
    I2C_Transfer_Status err = I2C_TRANSFER_BUSY;
    I2C_Transfer_Status tranStatus = I2C_TRANSFER_BUSY;

    switch(comPort->step)
    {
    case 0:
        memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));

        comPort->cmd.header = 0x55AA;
        comPort->cmd.rev = 0x03;
        comPort->cmd.cmd = CMD_GET_SENSOR_IIC_ADDR;

        CalcSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
        comPort->step = 1;
    case 1:
        tranStatus = comPort->write(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            comPort->step = 2;
            memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }
        
        break;

    case 2:
        tranStatus = comPort->read(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            bool checkSum = CheckSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
            if(checkSum == true)
            {
                *pAddrData = comPort->cmd.para[3];
                err = I2C_TRANSFER_DONE;
            }
            else
            {
                err = I2C_TRANSFER_ERROR;
            }
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }
        else
        {
            break;
        }
    default:
        comPort->step = 0;
        break;
    }

    if(err != I2C_TRANSFER_BUSY)
    {
        comPort->step = 0;
    }

    return err;
}

/// 读取软件版本号
I2C_Transfer_Status fingerCmdReadVersion(I2C_PlatformInterface_t        *comPort, uint8_t addr, uint8_t *pVersion)
{
    I2C_Transfer_Status err = I2C_TRANSFER_BUSY;
    I2C_Transfer_Status tranStatus = I2C_TRANSFER_BUSY;

    switch(comPort->step)
    {
    case 0:
        memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));

        comPort->cmd.header = 0x55AA;
        comPort->cmd.rev = 0x03;
        comPort->cmd.cmd = CMD_GET_VERSION;

        CalcSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
        comPort->step = 1;
    case 1:
        tranStatus = comPort->write(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            comPort->step = 2;
            memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }

        break;
    case 2:
        tranStatus = comPort->read(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            bool checkSum = CheckSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
            if(checkSum == true)
            {
                *pVersion = comPort->cmd.para[3];
                err = I2C_TRANSFER_DONE;
            }
            else
            {
                err = I2C_TRANSFER_ERROR;
            }
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }
        else
        {
            break;
        }
    default:
        comPort->step = 0;
        break;
    }

    if(err != I2C_TRANSFER_BUSY)
    {
        comPort->step = 0;
    }

    return err;
}

/// 读取pn
I2C_Transfer_Status fingerCmdReadPN(I2C_PlatformInterface_t        *comPort, uint8_t addr, uint8_t *pn)
{
    I2C_Transfer_Status err = I2C_TRANSFER_BUSY;
    I2C_Transfer_Status tranStatus = I2C_TRANSFER_BUSY;

    switch(comPort->step)
    {
    case 0:
        memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));

        comPort->cmd.header = 0x55AA;
        comPort->cmd.rev = 0x03;
        comPort->cmd.cmd = CMD_GET_PRG;

        CalcSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
        comPort->step = 1;
    case 1:
        tranStatus = comPort->write(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            comPort->step = 2;
            memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }

        break;
    case 2:
        tranStatus = comPort->read(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            bool checkSum = CheckSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
            if(checkSum == true)
            {
                *pn = comPort->cmd.para[3];
                err = I2C_TRANSFER_DONE;
            }
            else
            {
                err = I2C_TRANSFER_ERROR;
            }
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }
        else
        {
            break;
        }
    default:
        comPort->step = 0;
        break;
    }

    if(err != I2C_TRANSFER_BUSY)
    {
        comPort->step = 0;
    }

    return err;
}


/// 设置数据类型
I2C_Transfer_Status fingerCmdWriteDataType(I2C_PlatformInterface_t        *comPort, uint8_t addr, uint8_t type)
{
    I2C_Transfer_Status err = I2C_TRANSFER_BUSY;
    I2C_Transfer_Status tranStatus = I2C_TRANSFER_BUSY;

    switch(comPort->step)
    {
    case 0:
        memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));

        comPort->cmd.header = 0x55AA;
        comPort->cmd.rev = 0x03;
        comPort->cmd.cmd = CMD_SET_SENSOR_SEND_TYPE;
        comPort->cmd.para[3] = type;

        CalcSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
        comPort->step = 1;
    case 1:
        tranStatus = comPort->write(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            comPort->step = 2;
            memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }

        break;
    case 2:
        tranStatus = comPort->read(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            bool checkSum = CheckSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
            if((checkSum == true) && (comPort->cmd.cmd == (CMD_SET_SENSOR_SEND_TYPE|0x80)))
            {
                err = I2C_TRANSFER_DONE;
            }
            else
            {
                err = I2C_TRANSFER_ERROR;
            }
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }
        else
        {
            break;
        }
    default:
        comPort->step = 0;
        break;
    }

    if(err != I2C_TRANSFER_BUSY)
    {
        comPort->step = 0;
    }

    return err;
}

/// 设置采集偏置
I2C_Transfer_Status fingerCmdWriteSampleOffset(I2C_PlatformInterface_t        *comPort, uint8_t addr, uint8_t offset)
{
    I2C_Transfer_Status err = I2C_TRANSFER_BUSY;
    I2C_Transfer_Status tranStatus = I2C_TRANSFER_BUSY;

    switch(comPort->step)
    {
    case 0:
        memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));

        comPort->cmd.header = 0x55AA;
        comPort->cmd.rev = 0x03;
        comPort->cmd.cmd = CMD_SET_SENSOR_CDC_START_OFFSET;
        comPort->cmd.para[3] = offset;

        CalcSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
        comPort->step = 1;
    case 1:
        tranStatus = comPort->write(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            comPort->step = 2;
            err = I2C_TRANSFER_DONE;
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }
        else
        {
            break;
        }
    default:
        comPort->step = 0;
        break;
    }

    if(err != I2C_TRANSFER_BUSY)
    {
        comPort->step = 0;
    }

    return err;
}

/// 设置同步采集
I2C_Transfer_Status fingerCmdWriteSampleSync(I2C_PlatformInterface_t        *comPort, uint8_t addr)
{
    I2C_Transfer_Status err = I2C_TRANSFER_BUSY;
    I2C_Transfer_Status tranStatus = I2C_TRANSFER_BUSY;

    switch(comPort->step)
    {
    case 0:
        memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));

        comPort->cmd.header = 0x55AA;
        comPort->cmd.rev = 0x03;
        comPort->cmd.cmd = CMD_SET_SENSOR_CDC_SYNC;

        CalcSum((uint8_t *)&comPort->cmd, sizeof(comPort->cmd)-2);
        comPort->step = 1;
    case 1:
        tranStatus = comPort->write(comPort->port, addr, (uint8_t *)&comPort->cmd, sizeof(comPort->cmd));
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            err = I2C_TRANSFER_DONE;
            memset((void *)&comPort->cmd, 0, sizeof(comPort->cmd));
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }
        else
        {
            break;
        }
    default:
        comPort->step = 0;
        break;
    }

    if(err != I2C_TRANSFER_BUSY)
    {
        comPort->step = 0;
    }

    return err;
}

/// 读取电容数据
I2C_Transfer_Status fingerCmdReadCapData(I2C_PlatformInterface_t        *comPort, uint8_t addr, uint8_t *pBuf, uint16_t len)
{
    I2C_Transfer_Status err = I2C_TRANSFER_BUSY;
    I2C_Transfer_Status tranStatus = I2C_TRANSFER_BUSY;

    switch(comPort->step)
    {
    case 0:
        tranStatus = comPort->read(comPort->port, addr, pBuf, len);
        if(tranStatus == I2C_TRANSFER_DONE)
        {
            bool checkSum = CheckSum(pBuf, len-2);
            if(checkSum == true)
            {
                err = I2C_TRANSFER_DONE;
            }
            else
            {
                err = I2C_TRANSFER_ERROR;
            }
        }
        else if(tranStatus == I2C_TRANSFER_ERROR)
        {
            err = I2C_TRANSFER_ERROR;
            break;
        }
        else
        {
            break;
        }
    default:
        comPort->step = 0;
        break;
    }

    if(err != I2C_TRANSFER_BUSY)
    {
        comPort->step = 0;
    }

    return err;
}



