EHS/src/io/COM.cpp

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();
}
}
}