Speeding up COM writing
This commit is contained in:
parent
83ed23280a
commit
ecca6c691a
|
@ -35,6 +35,17 @@ struct anim_layer
|
||||||
blend_mode BlendMode;
|
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_LAYERS_MAX 128
|
||||||
#define ANIMATION_SYSTEM_BLOCKS_MAX 128
|
#define ANIMATION_SYSTEM_BLOCKS_MAX 128
|
||||||
struct animation_system
|
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
|
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 = {};
|
gs_string Result = {};
|
||||||
if (ReadFieldIdentifier(Field, T))
|
if (ReadFieldIdentifier(Field, T))
|
||||||
|
@ -293,8 +293,13 @@ ReadStringField(assembly_field Field, assembly_tokenizer* T, gs_memory_arena* Ar
|
||||||
if (ReadFieldEnd(T))
|
if (ReadFieldEnd(T))
|
||||||
{
|
{
|
||||||
// Success
|
// Success
|
||||||
Result = PushString(Arena, ExistingString.Length);
|
u64 Length = ExistingString.Length + (ShouldNullTerminate ? 1 : 0);
|
||||||
|
Result = PushString(Arena, Length);
|
||||||
PrintF(&Result, "%S", ExistingString);
|
PrintF(&Result, "%S", ExistingString);
|
||||||
|
if (ShouldNullTerminate)
|
||||||
|
{
|
||||||
|
NullTerminate(&Result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -430,6 +435,7 @@ ParseAssemblyFile(assembly* Assembly, gs_const_string FileName, gs_string FileTe
|
||||||
if (StringsEqual(OutputModeString.ConstString, ConstString("UART")))
|
if (StringsEqual(OutputModeString.ConstString, ConstString("UART")))
|
||||||
{
|
{
|
||||||
Assembly->OutputMode = NetworkProtocol_UART;
|
Assembly->OutputMode = NetworkProtocol_UART;
|
||||||
|
Assembly->UARTComPort = ReadStringField(AssemblyField_UART_ComPort, &Tokenizer, &Assembly->Arena, true).ConstString;
|
||||||
}
|
}
|
||||||
else if (StringsEqual(OutputModeString.ConstString, ConstString("SACN")))
|
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))
|
if (ReadStructOpening(AssemblyField_OutputUART, &Tokenizer, PARSER_FIELD_OPTIONAL))
|
||||||
{
|
{
|
||||||
StripAt->UARTAddr.Channel = (u8)ReadIntField(AssemblyField_UART_Channel, &Tokenizer);
|
StripAt->UARTAddr.Channel = (u8)ReadIntField(AssemblyField_UART_Channel, &Tokenizer);
|
||||||
StripAt->UARTAddr.ComPort = ReadStringField(AssemblyField_UART_ComPort, &Tokenizer, &Assembly->Arena).ConstString;
|
|
||||||
|
|
||||||
if (!ReadStructClosing(&Tokenizer))
|
if (!ReadStructClosing(&Tokenizer))
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,6 +61,7 @@ AddressedDataBufferList_PushEmpty(addressed_data_buffer_list* List)
|
||||||
{
|
{
|
||||||
addressed_data_buffer* Result = PushStruct(List->Arena, addressed_data_buffer);
|
addressed_data_buffer* Result = PushStruct(List->Arena, addressed_data_buffer);
|
||||||
*Result = {0};
|
*Result = {0};
|
||||||
|
Result->Next = 0;
|
||||||
Result->MemorySize = 0;
|
Result->MemorySize = 0;
|
||||||
Result->Memory = 0;
|
Result->Memory = 0;
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,6 @@ struct strip_sacn_addr
|
||||||
struct strip_uart_addr
|
struct strip_uart_addr
|
||||||
{
|
{
|
||||||
u8 Channel;
|
u8 Channel;
|
||||||
gs_const_string ComPort;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct v2_strip
|
struct v2_strip
|
||||||
|
@ -103,6 +102,7 @@ struct assembly
|
||||||
v2_strip* Strips;
|
v2_strip* Strips;
|
||||||
|
|
||||||
network_protocol OutputMode;
|
network_protocol OutputMode;
|
||||||
|
gs_const_string UARTComPort;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct assembly_array
|
struct assembly_array
|
||||||
|
|
|
@ -81,25 +81,16 @@ UART_FillFooter(uart_footer* Footer, u8* BufferStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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
|
// 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
|
// to catch the error where they are different
|
||||||
Assert(ChannelSettings.PixelsCount == Strip.LedCount);
|
Assert(ChannelSettings.PixelsCount == Strip.LedCount);
|
||||||
|
|
||||||
u32 BufferSize = sizeof(uart_header) + sizeof(uart_channel);
|
uart_header* Header = PushStructOnCursor(WriteCursor, uart_header);
|
||||||
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_FillHeader(Header, Strip.UARTAddr.Channel, UART_SET_CHANNEL_WS2812);
|
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;
|
*Channel = ChannelSettings;
|
||||||
|
|
||||||
for (u32 i = 0; i < Channel->PixelsCount; i++)
|
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];
|
u32 LedIndex = Strip.LedLUT[i];
|
||||||
pixel Color = LedBuffer.Colors[LedIndex];
|
pixel Color = LedBuffer.Colors[LedIndex];
|
||||||
|
|
||||||
u8* OutputPixel = PushArrayOnCursor(&WriteCursor, u8, 3);
|
u8* OutputPixel = PushArrayOnCursor(WriteCursor, u8, 3);
|
||||||
|
|
||||||
OutputPixel[Channel->RedIndex] = Color.R;
|
OutputPixel[Channel->RedIndex] = Color.R;
|
||||||
OutputPixel[Channel->GreenIndex] = Color.G;
|
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_footer* Footer = PushStructOnCursor(WriteCursor, uart_footer);
|
||||||
UART_FillFooter(Footer, Buffer->Memory);
|
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
|
internal void
|
||||||
|
@ -137,17 +138,31 @@ UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assembli
|
||||||
ChannelSettings.BlueIndex = 3;
|
ChannelSettings.BlueIndex = 3;
|
||||||
ChannelSettings.WhiteIndex = 0;
|
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++)
|
for (u32 AssemblyIdx = 0; AssemblyIdx < Assemblies.Count; AssemblyIdx++)
|
||||||
{
|
{
|
||||||
assembly Assembly = Assemblies.Values[AssemblyIdx];
|
assembly Assembly = Assemblies.Values[AssemblyIdx];
|
||||||
led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly.LedBufferIndex);
|
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++)
|
for (u32 StripIdx = 0; StripIdx < Assembly.StripCount; StripIdx++)
|
||||||
{
|
{
|
||||||
v2_strip StripAt = Assembly.Strips[StripIdx];
|
v2_strip StripAt = Assembly.Strips[StripIdx];
|
||||||
ChannelSettings.PixelsCount = StripAt.LedCount;
|
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
|
#define FOLDHAUS_LOG_H
|
||||||
#endif // FOLDHAUS_LOG_H
|
#endif // FOLDHAUS_LOG_H
|
|
@ -364,6 +364,58 @@ Win32LoadSystemCursor(char* CursorIdentifier)
|
||||||
return Result;
|
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
|
int WINAPI
|
||||||
WinMain (
|
WinMain (
|
||||||
HINSTANCE HInstance,
|
HINSTANCE HInstance,
|
||||||
|
@ -504,6 +556,8 @@ WinMain (
|
||||||
Context.ReloadStaticData(Context, GlobalDebugServices);
|
Context.ReloadStaticData(Context, GlobalDebugServices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddressedDataBufferList_Clear(&OutputData);
|
||||||
|
|
||||||
{ // Mouse Position
|
{ // Mouse Position
|
||||||
POINT MousePos;
|
POINT MousePos;
|
||||||
GetCursorPos (&MousePos);
|
GetCursorPos (&MousePos);
|
||||||
|
@ -534,39 +588,10 @@ WinMain (
|
||||||
|
|
||||||
if (true)
|
if (true)
|
||||||
{
|
{
|
||||||
// NOTE(pjs): Send the network data
|
gs_data ProcArg = {};
|
||||||
|
ProcArg.Memory = (u8*)&OutputData;
|
||||||
// TODO(pjs): This should happen on another thread
|
ProcArg.Size = sizeof(OutputData);
|
||||||
/*
|
Win32PushWorkOnQueue(&WorkQueue, Win32_SendAddressedDataBuffers_Job, ProcArg, ConstString("Send UART Data"));
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.Mouse.LeftButtonState = GetMouseButtonStateAdvanced(Context.Mouse.LeftButtonState);
|
Context.Mouse.LeftButtonState = GetMouseButtonStateAdvanced(Context.Mouse.LeftButtonState);
|
||||||
|
@ -610,6 +635,8 @@ WinMain (
|
||||||
SwapBuffers(DeviceContext);
|
SwapBuffers(DeviceContext);
|
||||||
ReleaseDC(MainWindow.Handle, DeviceContext);
|
ReleaseDC(MainWindow.Handle, DeviceContext);
|
||||||
|
|
||||||
|
//Win32DoQueueWorkUntilDone(&WorkQueue, Context.ThreadContext);
|
||||||
|
|
||||||
s64 FinishedWorkTime = GetWallClock();
|
s64 FinishedWorkTime = GetWallClock();
|
||||||
r32 SecondsElapsed = GetSecondsElapsed(LastFrameEnd, FinishedWorkTime, PerformanceCountFrequency);
|
r32 SecondsElapsed = GetSecondsElapsed(LastFrameEnd, FinishedWorkTime, PerformanceCountFrequency);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ global gs_string* Win32SerialPortNames;
|
||||||
DCB
|
DCB
|
||||||
Win32SerialPort_GetState(HANDLE ComPortHandle)
|
Win32SerialPort_GetState(HANDLE ComPortHandle)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
DCB ControlSettings = {0};
|
DCB ControlSettings = {0};
|
||||||
ZeroStruct(&ControlSettings);
|
ZeroStruct(&ControlSettings);
|
||||||
ControlSettings.DCBlength = sizeof(ControlSettings);
|
ControlSettings.DCBlength = sizeof(ControlSettings);
|
||||||
|
@ -26,14 +27,45 @@ Win32SerialPort_GetState(HANDLE ComPortHandle)
|
||||||
void
|
void
|
||||||
Win32SerialPort_SetState(HANDLE ComPortHandle, u32 BaudRate, u8 ByteSize, u8 Parity, u8 StopBits)
|
Win32SerialPort_SetState(HANDLE ComPortHandle, u32 BaudRate, u8 ByteSize, u8 Parity, u8 StopBits)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
DCB ControlSettings = Win32SerialPort_GetState(ComPortHandle);
|
DCB ControlSettings = Win32SerialPort_GetState(ComPortHandle);
|
||||||
//PrintCommState(ControlSettings);
|
|
||||||
|
|
||||||
// TODO(pjs): Validate BaudRate - There's only certain rates that are valid right?
|
// TODO(pjs): Validate BaudRate - There's only certain rates that are valid right?
|
||||||
ControlSettings.BaudRate = BaudRate;
|
ControlSettings.BaudRate = BaudRate;
|
||||||
ControlSettings.ByteSize = ByteSize;
|
|
||||||
ControlSettings.Parity = Parity;
|
if (Parity == NOPARITY)
|
||||||
|
{
|
||||||
|
ControlSettings.Parity = Parity;
|
||||||
|
ControlSettings.fParity = 0;
|
||||||
|
}
|
||||||
|
if (Parity == EVENPARITY || Parity == ODDPARITY)
|
||||||
|
{
|
||||||
|
ControlSettings.Parity = Parity;
|
||||||
|
ControlSettings.fParity = 1;
|
||||||
|
}
|
||||||
|
|
||||||
ControlSettings.StopBits = StopBits;
|
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);
|
bool Success = SetCommState(ComPortHandle, &ControlSettings);
|
||||||
}
|
}
|
||||||
|
@ -41,6 +73,7 @@ Win32SerialPort_SetState(HANDLE ComPortHandle, u32 BaudRate, u8 ByteSize, u8 Par
|
||||||
HANDLE
|
HANDLE
|
||||||
Win32SerialPort_Open(char* PortName)
|
Win32SerialPort_Open(char* PortName)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
HANDLE ComPortHandle = CreateFile(PortName,
|
HANDLE ComPortHandle = CreateFile(PortName,
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
@ -52,11 +85,11 @@ Win32SerialPort_Open(char* PortName)
|
||||||
if (ComPortHandle != INVALID_HANDLE_VALUE)
|
if (ComPortHandle != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
COMMTIMEOUTS Timeouts = { 0 };
|
COMMTIMEOUTS Timeouts = { 0 };
|
||||||
Timeouts.ReadIntervalTimeout = 50; // in milliseconds
|
Timeouts.ReadIntervalTimeout = 0; // in milliseconds
|
||||||
Timeouts.ReadTotalTimeoutConstant = 50; // in milliseconds
|
Timeouts.ReadTotalTimeoutConstant = 0; // in milliseconds
|
||||||
Timeouts.ReadTotalTimeoutMultiplier = 10; // in milliseconds
|
Timeouts.ReadTotalTimeoutMultiplier = 0; // in milliseconds
|
||||||
Timeouts.WriteTotalTimeoutConstant = 50; // in milliseconds
|
Timeouts.WriteTotalTimeoutConstant = 0; // in milliseconds
|
||||||
Timeouts.WriteTotalTimeoutMultiplier = 10; // in milliseconds
|
Timeouts.WriteTotalTimeoutMultiplier = 0; // in milliseconds
|
||||||
|
|
||||||
if (SetCommTimeouts(ComPortHandle, &Timeouts))
|
if (SetCommTimeouts(ComPortHandle, &Timeouts))
|
||||||
{
|
{
|
||||||
|
@ -65,14 +98,14 @@ Win32SerialPort_Open(char* PortName)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s32 Error = GetLastError();
|
s32 Error = GetLastError();
|
||||||
InvalidCodePath;
|
// TODO(pjs): Error logging
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Error
|
// Error
|
||||||
s32 Error = GetLastError();
|
s32 Error = GetLastError();
|
||||||
InvalidCodePath;
|
// TODO(pjs): Error logging
|
||||||
}
|
}
|
||||||
|
|
||||||
return ComPortHandle;
|
return ComPortHandle;
|
||||||
|
@ -84,15 +117,18 @@ Win32SerialPort_Close(HANDLE PortHandle)
|
||||||
CloseHandle(PortHandle);
|
CloseHandle(PortHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
Win32SerialPort_Write(HANDLE PortHandle, gs_data Buffer)
|
Win32SerialPort_Write(HANDLE PortHandle, gs_data Buffer)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
Assert(PortHandle != INVALID_HANDLE_VALUE);
|
Assert(PortHandle != INVALID_HANDLE_VALUE);
|
||||||
|
bool Success = false;
|
||||||
|
|
||||||
DWORD BytesWritten = 0;
|
DWORD BytesWritten = 0;
|
||||||
if (WriteFile(PortHandle, Buffer.Memory, Buffer.Size, &BytesWritten, NULL))
|
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");
|
OutputDebugString("Error: Entire buffer not written.\n");
|
||||||
}
|
}
|
||||||
|
@ -103,6 +139,8 @@ Win32SerialPort_Write(HANDLE PortHandle, gs_data Buffer)
|
||||||
s32 Error = GetLastError();
|
s32 Error = GetLastError();
|
||||||
//InvalidCodePath;
|
//InvalidCodePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
|
@ -111,6 +149,8 @@ Win32SerialPort_Write(HANDLE PortHandle, gs_data Buffer)
|
||||||
void
|
void
|
||||||
Win32SerialArray_Create(gs_thread_context Context)
|
Win32SerialArray_Create(gs_thread_context Context)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
Win32SerialHandlesCountMax = 32;
|
Win32SerialHandlesCountMax = 32;
|
||||||
Win32SerialHandlesCount = 0;
|
Win32SerialHandlesCount = 0;
|
||||||
Win32SerialHandles = AllocatorAllocArray(Context.Allocator, HANDLE, Win32SerialHandlesCountMax);
|
Win32SerialHandles = AllocatorAllocArray(Context.Allocator, HANDLE, Win32SerialHandlesCountMax);
|
||||||
|
@ -124,6 +164,8 @@ Win32SerialArray_Create(gs_thread_context Context)
|
||||||
void
|
void
|
||||||
Win32SerialArray_Push(HANDLE SerialHandle, gs_const_string PortName)
|
Win32SerialArray_Push(HANDLE SerialHandle, gs_const_string PortName)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
Assert(Win32SerialHandlesCount < Win32SerialHandlesCountMax);
|
Assert(Win32SerialHandlesCount < Win32SerialHandlesCountMax);
|
||||||
u32 Index = Win32SerialHandlesCount++;
|
u32 Index = Win32SerialHandlesCount++;
|
||||||
Win32SerialHandles[Index] = SerialHandle;
|
Win32SerialHandles[Index] = SerialHandle;
|
||||||
|
@ -133,6 +175,8 @@ Win32SerialArray_Push(HANDLE SerialHandle, gs_const_string PortName)
|
||||||
HANDLE
|
HANDLE
|
||||||
Win32SerialArray_Get(gs_const_string PortName)
|
Win32SerialArray_Get(gs_const_string PortName)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
HANDLE PortHandle = INVALID_HANDLE_VALUE;
|
HANDLE PortHandle = INVALID_HANDLE_VALUE;
|
||||||
for (u32 i = 0; i < Win32SerialHandlesCount; i++)
|
for (u32 i = 0; i < Win32SerialHandlesCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -148,13 +192,18 @@ Win32SerialArray_Get(gs_const_string PortName)
|
||||||
HANDLE
|
HANDLE
|
||||||
Win32SerialArray_GetOrOpen(gs_const_string PortName, u32 BaudRate, u8 ByteSize, u8 Parity, u8 StopBits)
|
Win32SerialArray_GetOrOpen(gs_const_string PortName, u32 BaudRate, u8 ByteSize, u8 Parity, u8 StopBits)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
HANDLE PortHandle = Win32SerialArray_Get(PortName);
|
HANDLE PortHandle = Win32SerialArray_Get(PortName);
|
||||||
if (PortHandle == INVALID_HANDLE_VALUE)
|
if (PortHandle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
Assert(IsNullTerminated(PortName));
|
Assert(IsNullTerminated(PortName));
|
||||||
PortHandle = Win32SerialPort_Open(PortName.Str);
|
PortHandle = Win32SerialPort_Open(PortName.Str);
|
||||||
Win32SerialPort_SetState(PortHandle, BaudRate, ByteSize, Parity, StopBits);
|
if (PortHandle != INVALID_HANDLE_VALUE)
|
||||||
Win32SerialArray_Push(PortHandle, PortName);
|
{
|
||||||
|
Win32SerialPort_SetState(PortHandle, BaudRate, ByteSize, Parity, StopBits);
|
||||||
|
Win32SerialArray_Push(PortHandle, PortName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return PortHandle;
|
return PortHandle;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue