Speeding up COM writing
This commit is contained in:
parent
83ed23280a
commit
ecca6c691a
|
@ -35,6 +35,17 @@ struct anim_layer
|
|||
blend_mode BlendMode;
|
||||
};
|
||||
|
||||
struct animation
|
||||
{
|
||||
anim_layer* Layers;
|
||||
u32 LayersCount;
|
||||
u32 LayersMax;
|
||||
|
||||
gs_list<animation_block> Blocks;
|
||||
|
||||
frame_range PlayableRange;
|
||||
};
|
||||
|
||||
#define ANIMATION_SYSTEM_LAYERS_MAX 128
|
||||
#define ANIMATION_SYSTEM_BLOCKS_MAX 128
|
||||
struct animation_system
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
//
|
||||
// File: foldhaus_animation_serializer.cpp
|
||||
// Author: Peter Slattery
|
||||
// Creation Date: 2020-10-04
|
||||
//
|
||||
#ifndef FOLDHAUS_ANIMATION_SERIALIZER_CPP
|
||||
|
||||
|
||||
#define FOLDHAUS_ANIMATION_SERIALIZER_CPP
|
||||
#endif // FOLDHAUS_ANIMATION_SERIALIZER_CPP
|
|
@ -284,7 +284,7 @@ ReadInt(assembly_tokenizer* T)
|
|||
}
|
||||
|
||||
internal gs_string
|
||||
ReadStringField(assembly_field Field, assembly_tokenizer* T, gs_memory_arena* Arena)
|
||||
ReadStringField(assembly_field Field, assembly_tokenizer* T, gs_memory_arena* Arena, bool ShouldNullTerminate = false)
|
||||
{
|
||||
gs_string Result = {};
|
||||
if (ReadFieldIdentifier(Field, T))
|
||||
|
@ -293,8 +293,13 @@ ReadStringField(assembly_field Field, assembly_tokenizer* T, gs_memory_arena* Ar
|
|||
if (ReadFieldEnd(T))
|
||||
{
|
||||
// Success
|
||||
Result = PushString(Arena, ExistingString.Length);
|
||||
u64 Length = ExistingString.Length + (ShouldNullTerminate ? 1 : 0);
|
||||
Result = PushString(Arena, Length);
|
||||
PrintF(&Result, "%S", ExistingString);
|
||||
if (ShouldNullTerminate)
|
||||
{
|
||||
NullTerminate(&Result);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
|
@ -430,6 +435,7 @@ ParseAssemblyFile(assembly* Assembly, gs_const_string FileName, gs_string FileTe
|
|||
if (StringsEqual(OutputModeString.ConstString, ConstString("UART")))
|
||||
{
|
||||
Assembly->OutputMode = NetworkProtocol_UART;
|
||||
Assembly->UARTComPort = ReadStringField(AssemblyField_UART_ComPort, &Tokenizer, &Assembly->Arena, true).ConstString;
|
||||
}
|
||||
else if (StringsEqual(OutputModeString.ConstString, ConstString("SACN")))
|
||||
{
|
||||
|
@ -459,7 +465,6 @@ ParseAssemblyFile(assembly* Assembly, gs_const_string FileName, gs_string FileTe
|
|||
if (ReadStructOpening(AssemblyField_OutputUART, &Tokenizer, PARSER_FIELD_OPTIONAL))
|
||||
{
|
||||
StripAt->UARTAddr.Channel = (u8)ReadIntField(AssemblyField_UART_Channel, &Tokenizer);
|
||||
StripAt->UARTAddr.ComPort = ReadStringField(AssemblyField_UART_ComPort, &Tokenizer, &Assembly->Arena).ConstString;
|
||||
|
||||
if (!ReadStructClosing(&Tokenizer))
|
||||
{
|
||||
|
|
|
@ -61,6 +61,7 @@ AddressedDataBufferList_PushEmpty(addressed_data_buffer_list* List)
|
|||
{
|
||||
addressed_data_buffer* Result = PushStruct(List->Arena, addressed_data_buffer);
|
||||
*Result = {0};
|
||||
Result->Next = 0;
|
||||
Result->MemorySize = 0;
|
||||
Result->Memory = 0;
|
||||
|
||||
|
|
|
@ -58,7 +58,6 @@ struct strip_sacn_addr
|
|||
struct strip_uart_addr
|
||||
{
|
||||
u8 Channel;
|
||||
gs_const_string ComPort;
|
||||
};
|
||||
|
||||
struct v2_strip
|
||||
|
@ -103,6 +102,7 @@ struct assembly
|
|||
v2_strip* Strips;
|
||||
|
||||
network_protocol OutputMode;
|
||||
gs_const_string UARTComPort;
|
||||
};
|
||||
|
||||
struct assembly_array
|
||||
|
|
|
@ -81,25 +81,16 @@ UART_FillFooter(uart_footer* Footer, u8* BufferStart)
|
|||
}
|
||||
|
||||
internal void
|
||||
UART_SetChannelBuffer_Create(addressed_data_buffer_list* Output, uart_channel ChannelSettings, v2_strip Strip, led_buffer LedBuffer)
|
||||
UART_SetChannelBuffer_Create(gs_memory_cursor* WriteCursor, uart_channel ChannelSettings, v2_strip Strip, led_buffer LedBuffer)
|
||||
{
|
||||
// NOTE(pjs): This is just here because the information is duplicated and I want to be sure
|
||||
// to catch the error where they are different
|
||||
Assert(ChannelSettings.PixelsCount == Strip.LedCount);
|
||||
|
||||
u32 BufferSize = sizeof(uart_header) + sizeof(uart_channel);
|
||||
BufferSize += ChannelSettings.ElementsCount * ChannelSettings.PixelsCount;
|
||||
BufferSize += sizeof(uart_footer);
|
||||
|
||||
addressed_data_buffer* Buffer = AddressedDataBufferList_Push(Output, BufferSize);
|
||||
AddressedDataBuffer_SetCOMPort(Buffer, Strip.UARTAddr.ComPort);
|
||||
|
||||
gs_memory_cursor WriteCursor = CreateMemoryCursor(Buffer->Data);
|
||||
|
||||
uart_header* Header = PushStructOnCursor(&WriteCursor, uart_header);
|
||||
uart_header* Header = PushStructOnCursor(WriteCursor, uart_header);
|
||||
UART_FillHeader(Header, Strip.UARTAddr.Channel, UART_SET_CHANNEL_WS2812);
|
||||
|
||||
uart_channel* Channel = PushStructOnCursor(&WriteCursor, uart_channel);
|
||||
uart_channel* Channel = PushStructOnCursor(WriteCursor, uart_channel);
|
||||
*Channel = ChannelSettings;
|
||||
|
||||
for (u32 i = 0; i < Channel->PixelsCount; i++)
|
||||
|
@ -107,7 +98,7 @@ UART_SetChannelBuffer_Create(addressed_data_buffer_list* Output, uart_channel Ch
|
|||
u32 LedIndex = Strip.LedLUT[i];
|
||||
pixel Color = LedBuffer.Colors[LedIndex];
|
||||
|
||||
u8* OutputPixel = PushArrayOnCursor(&WriteCursor, u8, 3);
|
||||
u8* OutputPixel = PushArrayOnCursor(WriteCursor, u8, 3);
|
||||
|
||||
OutputPixel[Channel->RedIndex] = Color.R;
|
||||
OutputPixel[Channel->GreenIndex] = Color.G;
|
||||
|
@ -123,8 +114,18 @@ UART_SetChannelBuffer_Create(addressed_data_buffer_list* Output, uart_channel Ch
|
|||
}
|
||||
}
|
||||
|
||||
uart_footer* Footer = PushStructOnCursor(&WriteCursor, uart_footer);
|
||||
UART_FillFooter(Footer, Buffer->Memory);
|
||||
uart_footer* Footer = PushStructOnCursor(WriteCursor, uart_footer);
|
||||
UART_FillFooter(Footer, (u8*)Header);
|
||||
}
|
||||
|
||||
internal void
|
||||
UART_DrawAll_Create(gs_memory_cursor* WriteCursor)
|
||||
{
|
||||
uart_header* Header = PushStructOnCursor(WriteCursor, uart_header);
|
||||
UART_FillHeader(Header, 1, UART_DRAW_ALL);
|
||||
|
||||
uart_footer* Footer = PushStructOnCursor(WriteCursor, uart_footer);
|
||||
UART_FillFooter(Footer, (u8*)Header);
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -137,17 +138,31 @@ UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assembli
|
|||
ChannelSettings.BlueIndex = 3;
|
||||
ChannelSettings.WhiteIndex = 0;
|
||||
|
||||
// NOTE(pjs): This is the minimum size of every UART message. SetChannelBuffer messages will
|
||||
// be bigger than this, but their size is based on the number of pixels in each channel
|
||||
u32 MessageBaseSize = sizeof(uart_header) + sizeof(uart_channel) + sizeof(uart_footer);
|
||||
|
||||
for (u32 AssemblyIdx = 0; AssemblyIdx < Assemblies.Count; AssemblyIdx++)
|
||||
{
|
||||
assembly Assembly = Assemblies.Values[AssemblyIdx];
|
||||
led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly.LedBufferIndex);
|
||||
|
||||
u32 TotalBufferSize = MessageBaseSize * Assembly.StripCount; // SetChannelBuffer messages
|
||||
TotalBufferSize += MessageBaseSize; // DrawAll message
|
||||
TotalBufferSize += ChannelSettings.ElementsCount * Assembly.LedCountTotal; // pixels * channels per pixel
|
||||
|
||||
addressed_data_buffer* Buffer = AddressedDataBufferList_Push(Output, TotalBufferSize);
|
||||
AddressedDataBuffer_SetCOMPort(Buffer, Assembly.UARTComPort);
|
||||
gs_memory_cursor WriteCursor = CreateMemoryCursor(Buffer->Data);
|
||||
|
||||
for (u32 StripIdx = 0; StripIdx < Assembly.StripCount; StripIdx++)
|
||||
{
|
||||
v2_strip StripAt = Assembly.Strips[StripIdx];
|
||||
ChannelSettings.PixelsCount = StripAt.LedCount;
|
||||
UART_SetChannelBuffer_Create(Output, ChannelSettings, StripAt, *LedBuffer);
|
||||
UART_SetChannelBuffer_Create(&WriteCursor, ChannelSettings, StripAt, *LedBuffer);
|
||||
}
|
||||
|
||||
UART_DrawAll_Create(&WriteCursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,5 +44,6 @@ PushLogEntry(event_log* Log, gs_string Message, log_entry_type Type)
|
|||
|
||||
|
||||
|
||||
|
||||
#define FOLDHAUS_LOG_H
|
||||
#endif // FOLDHAUS_LOG_H
|
|
@ -364,6 +364,58 @@ Win32LoadSystemCursor(char* CursorIdentifier)
|
|||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
Win32_SendAddressedDataBuffers(gs_thread_context Context, addressed_data_buffer_list OutputData)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
|
||||
u32 BuffersSent = 0;
|
||||
|
||||
for (addressed_data_buffer* BufferAt = OutputData.Root;
|
||||
BufferAt != 0;
|
||||
BufferAt = BufferAt->Next)
|
||||
{
|
||||
switch(BufferAt->AddressType)
|
||||
{
|
||||
case AddressType_NetworkIP:
|
||||
{
|
||||
Win32Socket_SendTo(BufferAt->SendSocket,
|
||||
BufferAt->V4SendAddress,
|
||||
BufferAt->SendPort,
|
||||
(const char*)BufferAt->Memory,
|
||||
BufferAt->MemorySize,
|
||||
0);
|
||||
}break;
|
||||
|
||||
case AddressType_ComPort:
|
||||
{
|
||||
HANDLE SerialPort = Win32SerialArray_GetOrOpen(BufferAt->ComPort, 2000000, 8, NOPARITY, 1);
|
||||
if (SerialPort != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (Win32SerialPort_Write(SerialPort, BufferAt->Data))
|
||||
{
|
||||
BuffersSent += 1;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
InvalidDefaultCase;
|
||||
}
|
||||
}
|
||||
|
||||
gs_string OutputStr = AllocatorAllocString(Context.Allocator, 256);
|
||||
PrintF(&OutputStr, "Buffers Sent: %d\n", BuffersSent);
|
||||
NullTerminate(&OutputStr);
|
||||
OutputDebugStringA(OutputStr.Str);
|
||||
}
|
||||
|
||||
internal void
|
||||
Win32_SendAddressedDataBuffers_Job(gs_thread_context Context, gs_data Arg)
|
||||
{
|
||||
addressed_data_buffer_list* OutputData = (addressed_data_buffer_list*)Arg.Memory;
|
||||
Win32_SendAddressedDataBuffers(Context, *OutputData);
|
||||
}
|
||||
|
||||
int WINAPI
|
||||
WinMain (
|
||||
HINSTANCE HInstance,
|
||||
|
@ -504,6 +556,8 @@ WinMain (
|
|||
Context.ReloadStaticData(Context, GlobalDebugServices);
|
||||
}
|
||||
|
||||
AddressedDataBufferList_Clear(&OutputData);
|
||||
|
||||
{ // Mouse Position
|
||||
POINT MousePos;
|
||||
GetCursorPos (&MousePos);
|
||||
|
@ -534,39 +588,10 @@ WinMain (
|
|||
|
||||
if (true)
|
||||
{
|
||||
// NOTE(pjs): Send the network data
|
||||
|
||||
// TODO(pjs): This should happen on another thread
|
||||
/*
|
||||
Saved this lien as an example of pushing onto a queue
|
||||
Context->GeneralWorkQueue->PushWorkOnQueue(Context->GeneralWorkQueue, SACNSendDMXBufferListJob, Job, "SACN Send Data Job");
|
||||
*/
|
||||
|
||||
for (addressed_data_buffer* BufferAt = OutputData.Root;
|
||||
BufferAt != 0;
|
||||
BufferAt = BufferAt->Next)
|
||||
{
|
||||
switch(BufferAt->AddressType)
|
||||
{
|
||||
case AddressType_NetworkIP:
|
||||
{
|
||||
Win32Socket_SendTo(BufferAt->SendSocket,
|
||||
BufferAt->V4SendAddress,
|
||||
BufferAt->SendPort,
|
||||
(const char*)BufferAt->Memory,
|
||||
BufferAt->MemorySize,
|
||||
0);
|
||||
}break;
|
||||
|
||||
case AddressType_ComPort:
|
||||
{
|
||||
HANDLE SerialPort = Win32SerialArray_GetOrOpen(BufferAt->ComPort, 9600, 8, 0, 1);
|
||||
Win32SerialPort_Write(SerialPort, BufferAt->Data);
|
||||
}break;
|
||||
|
||||
InvalidDefaultCase;
|
||||
}
|
||||
}
|
||||
gs_data ProcArg = {};
|
||||
ProcArg.Memory = (u8*)&OutputData;
|
||||
ProcArg.Size = sizeof(OutputData);
|
||||
Win32PushWorkOnQueue(&WorkQueue, Win32_SendAddressedDataBuffers_Job, ProcArg, ConstString("Send UART Data"));
|
||||
}
|
||||
|
||||
Context.Mouse.LeftButtonState = GetMouseButtonStateAdvanced(Context.Mouse.LeftButtonState);
|
||||
|
@ -610,6 +635,8 @@ WinMain (
|
|||
SwapBuffers(DeviceContext);
|
||||
ReleaseDC(MainWindow.Handle, DeviceContext);
|
||||
|
||||
//Win32DoQueueWorkUntilDone(&WorkQueue, Context.ThreadContext);
|
||||
|
||||
s64 FinishedWorkTime = GetWallClock();
|
||||
r32 SecondsElapsed = GetSecondsElapsed(LastFrameEnd, FinishedWorkTime, PerformanceCountFrequency);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ global gs_string* Win32SerialPortNames;
|
|||
DCB
|
||||
Win32SerialPort_GetState(HANDLE ComPortHandle)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
DCB ControlSettings = {0};
|
||||
ZeroStruct(&ControlSettings);
|
||||
ControlSettings.DCBlength = sizeof(ControlSettings);
|
||||
|
@ -26,14 +27,45 @@ Win32SerialPort_GetState(HANDLE ComPortHandle)
|
|||
void
|
||||
Win32SerialPort_SetState(HANDLE ComPortHandle, u32 BaudRate, u8 ByteSize, u8 Parity, u8 StopBits)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
DCB ControlSettings = Win32SerialPort_GetState(ComPortHandle);
|
||||
//PrintCommState(ControlSettings);
|
||||
|
||||
// TODO(pjs): Validate BaudRate - There's only certain rates that are valid right?
|
||||
ControlSettings.BaudRate = BaudRate;
|
||||
ControlSettings.ByteSize = ByteSize;
|
||||
|
||||
if (Parity == NOPARITY)
|
||||
{
|
||||
ControlSettings.Parity = Parity;
|
||||
ControlSettings.fParity = 0;
|
||||
}
|
||||
if (Parity == EVENPARITY || Parity == ODDPARITY)
|
||||
{
|
||||
ControlSettings.Parity = Parity;
|
||||
ControlSettings.fParity = 1;
|
||||
}
|
||||
|
||||
ControlSettings.StopBits = StopBits;
|
||||
ControlSettings.ByteSize = ByteSize;
|
||||
|
||||
ControlSettings.fBinary = true;
|
||||
|
||||
ControlSettings.fOutxCtsFlow = false;
|
||||
ControlSettings.fOutxDsrFlow = false;
|
||||
ControlSettings.fDtrControl = DTR_CONTROL_DISABLE;
|
||||
ControlSettings.fDsrSensitivity = 0;
|
||||
ControlSettings.fRtsControl = RTS_CONTROL_DISABLE;
|
||||
ControlSettings.fOutX = false;
|
||||
ControlSettings.fInX = false;
|
||||
|
||||
ControlSettings.fErrorChar = 0;
|
||||
ControlSettings.fNull = false;
|
||||
ControlSettings.fAbortOnError = false;
|
||||
ControlSettings.wReserved = false;
|
||||
ControlSettings.XonLim = 2;
|
||||
ControlSettings.XoffLim = 4;
|
||||
ControlSettings.XonChar = 0x13;
|
||||
ControlSettings.XoffChar = 0x19;
|
||||
ControlSettings.EvtChar = 0;
|
||||
|
||||
bool Success = SetCommState(ComPortHandle, &ControlSettings);
|
||||
}
|
||||
|
@ -41,6 +73,7 @@ Win32SerialPort_SetState(HANDLE ComPortHandle, u32 BaudRate, u8 ByteSize, u8 Par
|
|||
HANDLE
|
||||
Win32SerialPort_Open(char* PortName)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
HANDLE ComPortHandle = CreateFile(PortName,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
|
@ -52,11 +85,11 @@ Win32SerialPort_Open(char* PortName)
|
|||
if (ComPortHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
COMMTIMEOUTS Timeouts = { 0 };
|
||||
Timeouts.ReadIntervalTimeout = 50; // in milliseconds
|
||||
Timeouts.ReadTotalTimeoutConstant = 50; // in milliseconds
|
||||
Timeouts.ReadTotalTimeoutMultiplier = 10; // in milliseconds
|
||||
Timeouts.WriteTotalTimeoutConstant = 50; // in milliseconds
|
||||
Timeouts.WriteTotalTimeoutMultiplier = 10; // in milliseconds
|
||||
Timeouts.ReadIntervalTimeout = 0; // in milliseconds
|
||||
Timeouts.ReadTotalTimeoutConstant = 0; // in milliseconds
|
||||
Timeouts.ReadTotalTimeoutMultiplier = 0; // in milliseconds
|
||||
Timeouts.WriteTotalTimeoutConstant = 0; // in milliseconds
|
||||
Timeouts.WriteTotalTimeoutMultiplier = 0; // in milliseconds
|
||||
|
||||
if (SetCommTimeouts(ComPortHandle, &Timeouts))
|
||||
{
|
||||
|
@ -65,14 +98,14 @@ Win32SerialPort_Open(char* PortName)
|
|||
else
|
||||
{
|
||||
s32 Error = GetLastError();
|
||||
InvalidCodePath;
|
||||
// TODO(pjs): Error logging
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error
|
||||
s32 Error = GetLastError();
|
||||
InvalidCodePath;
|
||||
// TODO(pjs): Error logging
|
||||
}
|
||||
|
||||
return ComPortHandle;
|
||||
|
@ -84,15 +117,18 @@ Win32SerialPort_Close(HANDLE PortHandle)
|
|||
CloseHandle(PortHandle);
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
Win32SerialPort_Write(HANDLE PortHandle, gs_data Buffer)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
Assert(PortHandle != INVALID_HANDLE_VALUE);
|
||||
bool Success = false;
|
||||
|
||||
DWORD BytesWritten = 0;
|
||||
if (WriteFile(PortHandle, Buffer.Memory, Buffer.Size, &BytesWritten, NULL))
|
||||
{
|
||||
if (BytesWritten != Buffer.Size)
|
||||
Success = (BytesWritten == Buffer.Size);
|
||||
if (!Success)
|
||||
{
|
||||
OutputDebugString("Error: Entire buffer not written.\n");
|
||||
}
|
||||
|
@ -103,6 +139,8 @@ Win32SerialPort_Write(HANDLE PortHandle, gs_data Buffer)
|
|||
s32 Error = GetLastError();
|
||||
//InvalidCodePath;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
|
@ -111,6 +149,8 @@ Win32SerialPort_Write(HANDLE PortHandle, gs_data Buffer)
|
|||
void
|
||||
Win32SerialArray_Create(gs_thread_context Context)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
|
||||
Win32SerialHandlesCountMax = 32;
|
||||
Win32SerialHandlesCount = 0;
|
||||
Win32SerialHandles = AllocatorAllocArray(Context.Allocator, HANDLE, Win32SerialHandlesCountMax);
|
||||
|
@ -124,6 +164,8 @@ Win32SerialArray_Create(gs_thread_context Context)
|
|||
void
|
||||
Win32SerialArray_Push(HANDLE SerialHandle, gs_const_string PortName)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
|
||||
Assert(Win32SerialHandlesCount < Win32SerialHandlesCountMax);
|
||||
u32 Index = Win32SerialHandlesCount++;
|
||||
Win32SerialHandles[Index] = SerialHandle;
|
||||
|
@ -133,6 +175,8 @@ Win32SerialArray_Push(HANDLE SerialHandle, gs_const_string PortName)
|
|||
HANDLE
|
||||
Win32SerialArray_Get(gs_const_string PortName)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
|
||||
HANDLE PortHandle = INVALID_HANDLE_VALUE;
|
||||
for (u32 i = 0; i < Win32SerialHandlesCount; i++)
|
||||
{
|
||||
|
@ -148,14 +192,19 @@ Win32SerialArray_Get(gs_const_string PortName)
|
|||
HANDLE
|
||||
Win32SerialArray_GetOrOpen(gs_const_string PortName, u32 BaudRate, u8 ByteSize, u8 Parity, u8 StopBits)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
|
||||
HANDLE PortHandle = Win32SerialArray_Get(PortName);
|
||||
if (PortHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Assert(IsNullTerminated(PortName));
|
||||
PortHandle = Win32SerialPort_Open(PortName.Str);
|
||||
if (PortHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Win32SerialPort_SetState(PortHandle, BaudRate, ByteSize, Parity, StopBits);
|
||||
Win32SerialArray_Push(PortHandle, PortName);
|
||||
}
|
||||
}
|
||||
return PortHandle;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue