#include "drv_uart.h"
#include <QDateTime>
#include <QDebug>  // 用于调试输出
#include <QThread>

DRV_Uart::DRV_Uart(QObject *parent)
    : QObject(parent)  // 假设有8个通道
{

}

DRV_Uart::~DRV_Uart()
{

}

// 枚举当前的所有UART设备：返回搜索到的设备数目
ULONG DRV_Uart::Uart_enumDevice()
{
    ULONG i;

    mDeviceInforS DevInfor = {0};

    // 当前设备数目清零
    this->m_DRV_Uart_Infors.ulDevCnt = 0;

    // 依次搜索设备
    for(i=0;i<16;i++)
    {
        // 打开设备
        if(CH347Uart_Open(i) != INVALID_HANDLE_VALUE)
        {
            // 获取设备信息
            CH347Uart_GetDeviceInfor(i,&DevInfor);
            // 格式化设备名称
            sprintf(this->m_DRV_Uart_Infors.bDeviceName[this->m_DRV_Uart_Infors.ulDevCnt], "%d# %s", i,DevInfor.FuncDescStr);
            // 输出设备名称
            DbgPrint("UART:%s.", this->m_DRV_Uart_Infors.bDeviceName[this->m_DRV_Uart_Infors.ulDevCnt]);

            // copy设备信息至SpiI2cDevInfor结构体
            memcpy(&this->m_DRV_Uart_Infors.UartDevInfor[this->m_DRV_Uart_Infors.ulDevCnt], &DevInfor,sizeof(DevInfor));
            // 设备数量自增
            this->m_DRV_Uart_Infors.ulDevCnt++;
        }
        // 关闭设备
        CH347CloseDevice(i);
    }
    return this->m_DRV_Uart_Infors.ulDevCnt;
}

//打开设备
BOOL DRV_Uart::Uart_openDevice(ULONG UartIndex)
{
    // 判断设备的索引是否在正确的范围内，否则直接跳出
    if((this->m_DRV_Uart_Infors.ulDevCnt == 0) || (UartIndex >= this->m_DRV_Uart_Infors.ulDevCnt))
    {
        DbgPrint("Failed to open the device. Please refresh device first!");
        return FALSE;
    }
    // 打开串口设备
    this->m_DRV_Uart_Infors.devIsOpened = (CH347Uart_Open(UartIndex) != INVALID_HANDLE_VALUE);
    // 判断是否打开成功
    if(this->m_DRV_Uart_Infors.devIsOpened){
        // 设置当前的设备索引号
        this->m_DRV_Uart_Infors.opendDevIndex = UartIndex;
        // 设置默认的延迟时间
        CH347Uart_SetTimeout(UartIndex,500,500);
        // 设置接收和发送线程
        // StopTxThread = FALSE;
        // StopRxThread = FALSE;
    }
    // 显示日志信息
    DbgPrint(">>%d#Open Device...%s",UartIndex,this->m_DRV_Uart_Infors.devIsOpened?"Success":"Failed");
    return this->m_DRV_Uart_Infors.devIsOpened;
}

//关闭设备
BOOL DRV_Uart::Uart_closeDevice()
{
    // 设置接收和发送线程
    // StopTxThread = TRUE;
    // StopRxThread = TRUE;
    // 判断是否打开成功
    if(this->m_DRV_Uart_Infors.devIsOpened){
        Sleep(300);
        CH347Uart_Close(this->m_DRV_Uart_Infors.opendDevIndex);
        this->m_DRV_Uart_Infors.devIsOpened = FALSE;
        DbgPrint(">>%d#Close device",this->m_DRV_Uart_Infors.opendDevIndex);
    }
    return TRUE;
}

//设置串口参数
BOOL DRV_Uart::Uart_setPara(ULONG Baudrate, UCHAR StopBits, UCHAR Parity, UCHAR DataSize, UCHAR Timeout)
{
    BOOL RetVal = FALSE;

    if(this->m_DRV_Uart_Infors.devIsOpened){
        RetVal = CH347Uart_Init(this->m_DRV_Uart_Infors.opendDevIndex,Baudrate,DataSize,Parity,StopBits,Timeout);
        DbgPrint("Uart_Set %s,Baudrate:%d,DataSize:%d,Parity:%d,StopBits:%d,Timeout:%d",RetVal?"succ":"failure",
                 Baudrate,DataSize,Parity,StopBits,Timeout);
    }
    return RetVal;
}

//串口发送数据
BOOL DRV_Uart::Uart_Write(QByteArray &sendData)
{
    // 获取数据包的长度
    ULONG OutLen = sendData.length();
    // 将QByteArray转化为UCHAR
    const UCHAR *OutBuf = reinterpret_cast<const unsigned char*>(sendData.constData());

    BOOL RetVal = FALSE;
    // 调用底层串口发送函数发送数据
    RetVal = CH347Uart_Write(this->m_DRV_Uart_Infors.opendDevIndex, (UCHAR *)OutBuf, &OutLen);
    // 日志窗口输出调试信息
    DbgPrint("frame:%d,Uart_Write %dBytes %s.",sendData.at(14), OutLen,RetVal?"succ":"failure");

    return RetVal;
}

//读取串口缓冲区数据大小
LONGLONG DRV_Uart::Uart_readRxBufcnt(void)
{
    LONGLONG rxBufSize = 0;

    BOOL RetVal = FALSE;
    // 调用底层串口接收数据缓冲区的大小
    RetVal = CH347Uart_QueryBufUpload(this->m_DRV_Uart_Infors.opendDevIndex, &rxBufSize);
    // 日志窗口输出调试信息
    DbgPrint("read uart rx buf count:%d.", rxBufSize, RetVal?"succ":"failure");

    return rxBufSize;
}

BOOL DRV_Uart::Uart_Read(QByteArray &revData)
{
    ULONG InLen = 4096;     // 设置读取的长度，读取完后会将该值赋值为真实的长度
    UCHAR InBuf[4096] = {0x00};

    BOOL RetVal = FALSE;

    // 读取串口数据
    RetVal = CH347Uart_Read(this->m_DRV_Uart_Infors.opendDevIndex,InBuf,&InLen);

    DbgPrint("CH347Uart_Read %dB %s.",InLen,RetVal?"succ":"failure");

    if(RetVal)
    {
        //将数据存入revData变量中，返回给调用的函数
        revData = QByteArray::fromRawData(reinterpret_cast<const char*>(InBuf), InLen);
    }
    return RetVal;
}
