Simplify CDC driver layer
This commit is contained in:
@@ -1,75 +1,15 @@
|
||||
#include "DRI/Dri_Cdc.h"
|
||||
|
||||
#include "COM/Com_Cdc.h"
|
||||
#include "COM/Com_CdcDecode.h"
|
||||
#include "COM/Com_CdcEncode.h"
|
||||
|
||||
#include <QtCore/QElapsedTimer>
|
||||
#include <QtCore/QtGlobal>
|
||||
#include <QtSerialPort/QSerialPort>
|
||||
#include <QtSerialPort/QSerialPortInfo>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool Dri_Cdc_Func_TryReadFrame(
|
||||
QSerialPort* p_Serial,
|
||||
QByteArray* p_ReadBuffer,
|
||||
int TimeoutMs,
|
||||
Packet* p_Packet)
|
||||
{
|
||||
if ((p_Serial == nullptr) || (p_ReadBuffer == nullptr) || (p_Packet == nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Com_Cdc_Func_TryTakeFrame(p_ReadBuffer, p_Packet))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QElapsedTimer Timer;
|
||||
Timer.start();
|
||||
while (Timer.elapsed() < TimeoutMs)
|
||||
{
|
||||
const int RemainingMs = TimeoutMs - static_cast<int>(Timer.elapsed());
|
||||
const int WaitMs = qMin(20, RemainingMs);
|
||||
if (WaitMs <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!p_Serial->waitForReadyRead(WaitMs))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const QByteArray ReadBytes = p_Serial->readAll();
|
||||
if (!ReadBytes.isEmpty())
|
||||
{
|
||||
p_ReadBuffer->append(ReadBytes);
|
||||
}
|
||||
|
||||
if (Com_Cdc_Func_TryTakeFrame(p_ReadBuffer, p_Packet))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
QVector<Dri_Cdc_Struct_PortInfo> Dri_Cdc_Enum()
|
||||
{
|
||||
QVector<Dri_Cdc_Struct_PortInfo> PortList;
|
||||
|
||||
const QList<QSerialPortInfo> InfoList = QSerialPortInfo::availablePorts();
|
||||
for (int Index = 0; Index < InfoList.size(); ++Index)
|
||||
for (const QSerialPortInfo& Info : InfoList)
|
||||
{
|
||||
const QSerialPortInfo& Info = InfoList.at(Index);
|
||||
|
||||
Dri_Cdc_Struct_PortInfo PortInfo;
|
||||
PortInfo.PortName = Info.portName();
|
||||
PortInfo.Description = Info.description();
|
||||
@@ -80,130 +20,89 @@ QVector<Dri_Cdc_Struct_PortInfo> Dri_Cdc_Enum()
|
||||
return PortList;
|
||||
}
|
||||
|
||||
void Dri_Cdc_Deinit(Dri_Cdc_Struct_Port* p_Port)
|
||||
void Dri_Cdc_Close(Dri_Cdc_Struct_Port* p_Port)
|
||||
{
|
||||
if (p_Port == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_Port->p_Port != nullptr)
|
||||
{
|
||||
if (p_Port->p_Port->isOpen())
|
||||
{
|
||||
p_Port->p_Port->close();
|
||||
}
|
||||
|
||||
delete p_Port->p_Port;
|
||||
}
|
||||
|
||||
*p_Port = Dri_Cdc_Struct_Port();
|
||||
}
|
||||
|
||||
bool Dri_Cdc_Init(
|
||||
bool Dri_Cdc_Open(
|
||||
Dri_Cdc_Struct_Port* p_Port,
|
||||
const Dri_Cdc_Struct_InitConfig& Config)
|
||||
const QString& PortName,
|
||||
const Dri_Cdc_Struct_OpenConfig& Config)
|
||||
{
|
||||
Dri_Cdc_Deinit(p_Port);
|
||||
|
||||
const QVector<Dri_Cdc_Struct_PortInfo> PortList = Dri_Cdc_Enum();
|
||||
if (PortList.isEmpty())
|
||||
if ((p_Port == nullptr) || PortName.trimmed().isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Packet_HelloReq HelloReq;
|
||||
const QByteArray HelloReqFrame = Com_Cdc_Func_BuildHelloReq(HelloReq);
|
||||
Dri_Cdc_Close(p_Port);
|
||||
|
||||
for (int Index = 0; Index < PortList.size(); ++Index)
|
||||
QSerialPort* const p_Serial = new QSerialPort();
|
||||
p_Serial->setPortName(PortName);
|
||||
p_Serial->setBaudRate(Config.BaudRate);
|
||||
p_Serial->setDataBits(QSerialPort::Data8);
|
||||
p_Serial->setParity(QSerialPort::NoParity);
|
||||
p_Serial->setStopBits(QSerialPort::OneStop);
|
||||
p_Serial->setFlowControl(QSerialPort::NoFlowControl);
|
||||
|
||||
if (!p_Serial->open(QIODevice::ReadWrite))
|
||||
{
|
||||
const Dri_Cdc_Struct_PortInfo& PortInfo = PortList.at(Index);
|
||||
|
||||
QSerialPort* p_Serial = new QSerialPort();
|
||||
p_Serial->setPortName(PortInfo.PortName);
|
||||
p_Serial->setBaudRate(Config.BaudRate);
|
||||
p_Serial->setDataBits(QSerialPort::Data8);
|
||||
p_Serial->setParity(QSerialPort::NoParity);
|
||||
p_Serial->setStopBits(QSerialPort::OneStop);
|
||||
p_Serial->setFlowControl(QSerialPort::NoFlowControl);
|
||||
|
||||
if (!p_Serial->open(QIODevice::ReadWrite))
|
||||
{
|
||||
delete p_Serial;
|
||||
continue;
|
||||
}
|
||||
|
||||
p_Serial->readAll();
|
||||
|
||||
if (p_Serial->write(HelloReqFrame) != HelloReqFrame.size())
|
||||
{
|
||||
p_Serial->close();
|
||||
delete p_Serial;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!p_Serial->waitForBytesWritten(Config.HandshakeTimeoutMs))
|
||||
{
|
||||
p_Serial->close();
|
||||
delete p_Serial;
|
||||
continue;
|
||||
}
|
||||
|
||||
QByteArray HandshakeBuffer;
|
||||
QElapsedTimer Timer;
|
||||
Timer.start();
|
||||
while (Timer.elapsed() < Config.HandshakeTimeoutMs)
|
||||
{
|
||||
Packet PacketData;
|
||||
const int RemainingMs =
|
||||
Config.HandshakeTimeoutMs - static_cast<int>(Timer.elapsed());
|
||||
if (!Dri_Cdc_Func_TryReadFrame(
|
||||
p_Serial,
|
||||
&HandshakeBuffer,
|
||||
qMin(20, RemainingMs),
|
||||
&PacketData))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PacketData.type == Com_Type_HelloRsp)
|
||||
{
|
||||
p_Port->p_Port = p_Serial;
|
||||
p_Port->IsOpened = true;
|
||||
p_Port->PortName = PortInfo.PortName;
|
||||
p_Port->ReadBuffer = HandshakeBuffer;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
p_Serial->close();
|
||||
delete p_Serial;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
p_Port->p_Port = p_Serial;
|
||||
p_Port->IsOpened = true;
|
||||
p_Port->PortName = PortName;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Dri_Cdc_Read(
|
||||
bool Dri_Cdc_ReadBytes(
|
||||
Dri_Cdc_Struct_Port* p_Port,
|
||||
QByteArray& ByteArray)
|
||||
QByteArray* p_ByteArray,
|
||||
int TimeoutMs)
|
||||
{
|
||||
ByteArray.clear();
|
||||
if (p_ByteArray != nullptr)
|
||||
{
|
||||
p_ByteArray->clear();
|
||||
}
|
||||
|
||||
if (!p_Port->IsOpened || (p_Port->p_Port == nullptr))
|
||||
if ((p_Port == nullptr) || (p_ByteArray == nullptr) ||
|
||||
!p_Port->IsOpened || (p_Port->p_Port == nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Packet PacketData;
|
||||
if (Com_Cdc_Func_TryTakeFrame(&p_Port->ReadBuffer, &PacketData) ||
|
||||
Dri_Cdc_Func_TryReadFrame(p_Port->p_Port, &p_Port->ReadBuffer, 50, &PacketData))
|
||||
if (TimeoutMs > 0)
|
||||
{
|
||||
ByteArray = Com_Cdc_Func_BuildFrame(PacketData);
|
||||
return !ByteArray.isEmpty();
|
||||
p_Port->p_Port->waitForReadyRead(TimeoutMs);
|
||||
}
|
||||
|
||||
return false;
|
||||
*p_ByteArray = p_Port->p_Port->readAll();
|
||||
return !p_ByteArray->isEmpty();
|
||||
}
|
||||
|
||||
bool Dri_Cdc_Write(
|
||||
bool Dri_Cdc_WriteBytes(
|
||||
Dri_Cdc_Struct_Port* p_Port,
|
||||
const QByteArray& ByteArray)
|
||||
const QByteArray& ByteArray,
|
||||
int TimeoutMs)
|
||||
{
|
||||
if (!p_Port->IsOpened || (p_Port->p_Port == nullptr))
|
||||
if ((p_Port == nullptr) || !p_Port->IsOpened || (p_Port->p_Port == nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -218,10 +117,5 @@ bool Dri_Cdc_Write(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!p_Port->p_Port->waitForBytesWritten(200))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return p_Port->p_Port->waitForBytesWritten(TimeoutMs);
|
||||
}
|
||||
|
||||
@@ -13,10 +13,9 @@ struct Dri_Cdc_Struct_PortInfo
|
||||
QString Manufacturer;
|
||||
};
|
||||
|
||||
struct Dri_Cdc_Struct_InitConfig
|
||||
struct Dri_Cdc_Struct_OpenConfig
|
||||
{
|
||||
qint32 BaudRate = 115200;
|
||||
int HandshakeTimeoutMs = 200;
|
||||
};
|
||||
|
||||
struct Dri_Cdc_Struct_Port
|
||||
@@ -24,17 +23,19 @@ struct Dri_Cdc_Struct_Port
|
||||
QSerialPort* p_Port = nullptr;
|
||||
bool IsOpened = false;
|
||||
QString PortName;
|
||||
QByteArray ReadBuffer;
|
||||
};
|
||||
|
||||
QVector<Dri_Cdc_Struct_PortInfo> Dri_Cdc_Enum();
|
||||
void Dri_Cdc_Deinit(Dri_Cdc_Struct_Port* p_Port);
|
||||
bool Dri_Cdc_Init(
|
||||
void Dri_Cdc_Close(Dri_Cdc_Struct_Port* p_Port);
|
||||
bool Dri_Cdc_Open(
|
||||
Dri_Cdc_Struct_Port* p_Port,
|
||||
const Dri_Cdc_Struct_InitConfig& Config);
|
||||
bool Dri_Cdc_Read(
|
||||
const QString& PortName,
|
||||
const Dri_Cdc_Struct_OpenConfig& Config);
|
||||
bool Dri_Cdc_ReadBytes(
|
||||
Dri_Cdc_Struct_Port* p_Port,
|
||||
QByteArray& ByteArray);
|
||||
bool Dri_Cdc_Write(
|
||||
QByteArray* p_ByteArray,
|
||||
int TimeoutMs);
|
||||
bool Dri_Cdc_WriteBytes(
|
||||
Dri_Cdc_Struct_Port* p_Port,
|
||||
const QByteArray& ByteArray);
|
||||
const QByteArray& ByteArray,
|
||||
int TimeoutMs);
|
||||
|
||||
Reference in New Issue
Block a user