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