134 lines
4.1 KiB
C++
134 lines
4.1 KiB
C++
#include "ehs/io/COM.h"
|
|
#include "ehs/Str.h"
|
|
#include "ehs/Log.h"
|
|
|
|
namespace ehs
|
|
{
|
|
COM::COM()
|
|
: port(0), baudRate(9600), byteSize(8), parity(Parity::NONE), stopBits(StopBits::ONE), hdl(nullptr), initialized(false)
|
|
{
|
|
}
|
|
|
|
COM::COM(const UInt_8 port, const UInt_32 baudRate, const UInt_8 byteSize, const Parity parity, const StopBits stopBits)
|
|
: port(port), baudRate(baudRate), byteSize(byteSize), parity(parity), stopBits(stopBits), hdl(nullptr), initialized(false)
|
|
{
|
|
}
|
|
|
|
void COM::Initialize()
|
|
{
|
|
if (initialized)
|
|
return;
|
|
|
|
hdl = CreateFileW(L"\\\\.\\COM" + Str_16::FromNum(port), GENERIC_READ | GENERIC_WRITE,
|
|
0, nullptr, OPEN_EXISTING, 0,
|
|
nullptr);
|
|
if (hdl == INVALID_HANDLE_VALUE)
|
|
{
|
|
EHS_LOG_INT(LogType::ERR, 0, "Failed to create handle at COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
return;
|
|
}
|
|
|
|
DCB dcb = {};
|
|
dcb.DCBlength = sizeof(DCB);
|
|
|
|
if (!GetCommState(hdl, &dcb))
|
|
{
|
|
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve COM" + Str_8::FromNum(port) + " state with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
UnInitialize();
|
|
return;
|
|
}
|
|
|
|
dcb.BaudRate = (DWORD)baudRate;
|
|
dcb.ByteSize = (BYTE)byteSize;
|
|
dcb.fParity = (DWORD)parity;
|
|
dcb.StopBits = (BYTE)stopBits;
|
|
dcb.fDtrControl = DTR_CONTROL_ENABLE;
|
|
|
|
if (!SetCommState(hdl, &dcb))
|
|
{
|
|
EHS_LOG_INT(LogType::ERR, 2, "Failed to set COM" + Str_8::FromNum(port) + " state with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
UnInitialize();
|
|
return;
|
|
}
|
|
|
|
SetCommMask(hdl, EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY);
|
|
|
|
PurgeComm(hdl, PURGE_RXCLEAR | PURGE_TXCLEAR);
|
|
|
|
initialized = true;
|
|
}
|
|
|
|
void COM::UnInitialize()
|
|
{
|
|
if (hdl)
|
|
{
|
|
if (!CloseHandle(hdl))
|
|
EHS_LOG_INT(LogType::ERR, 0, "Failed to close COM" + Str_8::FromNum(port) + " handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
|
|
hdl = nullptr;
|
|
}
|
|
|
|
initialized = false;
|
|
}
|
|
|
|
UInt_32 COM::Wait()
|
|
{
|
|
UInt_32 event = 0;
|
|
|
|
if (!WaitCommEvent(hdl, (DWORD*)&event, nullptr))
|
|
{
|
|
EHS_LOG_INT(LogType::ERR, 0, "Failed to wait for COM" + Str_8::FromNum(port) + " event with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
UnInitialize();
|
|
}
|
|
|
|
return event;
|
|
}
|
|
|
|
void COM::Transmit(const Char_8 data)
|
|
{
|
|
if (!initialized)
|
|
return;
|
|
|
|
if (!TransmitCommChar(hdl, data))
|
|
{
|
|
EHS_LOG_INT(LogType::ERR, 0, "Failed to transmit character to COM" + Str_8::FromNum(port) + " with error #" +
|
|
Str_8::FromNum(GetLastError()) + ".");
|
|
UnInitialize();
|
|
}
|
|
}
|
|
|
|
UInt_32 COM::Send(const Char_8* data, const UInt_32 size)
|
|
{
|
|
UInt_32 sent = 0;
|
|
|
|
if (!WriteFile(hdl, (void*)data, (DWORD)size, (DWORD*)&sent, nullptr))
|
|
{
|
|
EHS_LOG_INT(LogType::ERR, 0, "Failed to receive data from COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
UnInitialize();
|
|
}
|
|
|
|
return sent;
|
|
}
|
|
|
|
UInt_32 COM::Receive(const Char_8* data, const UInt_32 size)
|
|
{
|
|
UInt_32 received = 0;
|
|
|
|
if (!ReadFile(hdl, (void*)data, (DWORD)size, (DWORD*)&received, nullptr))
|
|
{
|
|
EHS_LOG_INT(LogType::ERR, 0, "Failed to receive data from COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
UnInitialize();
|
|
}
|
|
|
|
return received;
|
|
}
|
|
|
|
void COM::Flush()
|
|
{
|
|
if (!FlushFileBuffers(hdl))
|
|
{
|
|
EHS_LOG_INT(LogType::ERR, 0, "Failed to flush data for COM" + Str_8::FromNum(port) + " with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
UnInitialize();
|
|
}
|
|
}
|
|
} |