Skip to content

Commit

Permalink
[hydro-asetek] initial asetek hydro aio support
Browse files Browse the repository at this point in the history
  • Loading branch information
EvanMulawski committed Aug 5, 2023
1 parent 0e4000b commit f4f46ca
Show file tree
Hide file tree
Showing 16 changed files with 1,062 additions and 117 deletions.
120 changes: 60 additions & 60 deletions README.md

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions src/CorsairLink.Asetek/AsetekCoolerProtocol.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using CorsairLink.SiUsbXpress;
using System;

namespace CorsairLink.Asetek;

public class AsetekCoolerProtocol : IAsetekDeviceProxy, IDisposable
{
private bool _disposedValue;

public AsetekCoolerProtocol(ISiUsbXpressDevice device)
{
Device = device;
}

protected ISiUsbXpressDevice Device { get; }

protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
Device?.Dispose();
}

_disposedValue = true;
}
}

public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}

public virtual AsetekDeviceInfo GetDeviceInfo()
{
return new AsetekDeviceInfo(
Device.DeviceInfo.DevicePath,
Device.DeviceInfo.VendorId,
Device.DeviceInfo.ProductId,
Device.DeviceInfo.Name,
Device.DeviceInfo.SerialNumber);
}

public virtual (bool Opened, Exception? Exception) Open()
{
try
{
Device.Open();
return (true, default);
}
catch (Exception ex)
{
return (false, ex);
}
}

public virtual void Close()
{
Device.Close();
}

public virtual byte[] WriteAndRead(byte[] buffer)
{
return Device.WriteAndRead(buffer);
}
}
19 changes: 19 additions & 0 deletions src/CorsairLink.Asetek/AsetekDeviceInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace CorsairLink.Asetek;

public sealed class AsetekDeviceInfo
{
public AsetekDeviceInfo(string devicePath, int vendorId, int productId, string productName, string serialNumber)
{
DevicePath = devicePath;
VendorId = vendorId;
ProductId = productId;
ProductName = productName;
SerialNumber = serialNumber;
}

public string DevicePath { get; }
public int VendorId { get; }
public int ProductId { get; }
public string ProductName { get; }
public string SerialNumber { get; }
}
14 changes: 14 additions & 0 deletions src/CorsairLink.Asetek/CorsairLink.Asetek.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>Latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\CorsairLink.Abstractions\CorsairLink.Abstractions.csproj" />
<ProjectReference Include="..\CorsairLink.SiUsbXpress\CorsairLink.SiUsbXpress.csproj" />
</ItemGroup>

</Project>
11 changes: 11 additions & 0 deletions src/CorsairLink.Asetek/IAsetekDeviceProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace CorsairLink.Asetek;

public interface IAsetekDeviceProxy
{
AsetekDeviceInfo GetDeviceInfo();
(bool Opened, Exception? Exception) Open();
void Close();
byte[] WriteAndRead(byte[] buffer);
}
22 changes: 22 additions & 0 deletions src/CorsairLink.SiUsbXpress.Driver/AsetekSiUsbXpressDevice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace CorsairLink.SiUsbXpress.Driver;

public class AsetekSiUsbXpressDevice : SiUsbXpressDevice
{
private const uint DEFAULT_TIMEOUT = 500U;
private const uint READ_BUFFER_SIZE = 32;

public AsetekSiUsbXpressDevice(SiUsbXpressDeviceInfo deviceInfo)
: base(deviceInfo)
{
}

protected override uint ReadBufferSize { get; } = READ_BUFFER_SIZE;

public override void Open()
{
base.Open();

_ = SiUsbXpressDriver.SI_SetTimeouts(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT);
FlushBuffers();
}
}
66 changes: 66 additions & 0 deletions src/CorsairLink.SiUsbXpress.Driver/FlexSiUsbXpressDevice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
namespace CorsairLink.SiUsbXpress.Driver;

public sealed class FlexSiUsbXpressDevice : SiUsbXpressDevice
{
private const uint MAX_BAUD_RATE = 115200U;
private const uint DEFAULT_TIMEOUT = 200U;
private const uint READ_BUFFER_SIZE = 16;

public FlexSiUsbXpressDevice(SiUsbXpressDeviceInfo deviceInfo)
: base(deviceInfo)
{
}

protected override uint ReadBufferSize { get; } = READ_BUFFER_SIZE;

public override void Open()
{
base.Open();

_ = SiUsbXpressDriver.SI_SetTimeouts(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT);
FlushBuffers();
_ = SiUsbXpressDriver.SI_SetBaudRate(DeviceHandle!.DangerousGetHandle(), MAX_BAUD_RATE);
}

protected override byte[] GetReadBuffer(byte[] originalBuffer)
{
var buffer = base.GetReadBuffer(originalBuffer);
return !EncodingHelper.HasError(buffer)
? EncodingHelper.DecodeData(buffer)
: throw new SiUsbXpressException("Failed to read - data error.");
}

protected override byte[] GetWriteBuffer(byte[] originalBuffer)
{
var buffer = base.GetWriteBuffer(originalBuffer);
return EncodingHelper.EncodeData(buffer);
}

private AckStatus ReadAckStatus()
=> AckParser.Parse(Read());

public override void WriteAndValidate(byte[] buffer)
{
ThrowIfDeviceNotReady();

Write(buffer);
AckStatus ackStatus = ReadAckStatus();
if (ackStatus != AckStatus.Ok)
throw new SiUsbXpressDeviceAckException(ackStatus);
}

public override void WriteWhileBusy(byte[] buffer)
{
ThrowIfDeviceNotReady();

AckStatus ackStatus;
do
{
Write(buffer);
ackStatus = ReadAckStatus();
}
while (ackStatus == AckStatus.Busy);
if (ackStatus != AckStatus.Ok)
throw new SiUsbXpressDeviceAckException(ackStatus);
}
}
89 changes: 35 additions & 54 deletions src/CorsairLink.SiUsbXpress.Driver/SiUsbXpressDevice.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
using Microsoft.Win32.SafeHandles;
using Microsoft.Win32.SafeHandles;
using System;
using System.Linq;
using System.Runtime.InteropServices;

namespace CorsairLink.SiUsbXpress.Driver;

public sealed class SiUsbXpressDevice : ISiUsbXpressDevice
public abstract class SiUsbXpressDevice : ISiUsbXpressDevice
{
private const uint MAX_BAUD_RATE = 115200U;
private const uint DEFAULT_TIMEOUT = 200U;
private const uint READ_BUFFER_SIZE = 16;

private uint _deviceNumber = 0;
protected uint _deviceNumber = 0;

public SiUsbXpressDevice(SiUsbXpressDeviceInfo deviceInfo)
{
Expand All @@ -22,11 +18,13 @@ public SiUsbXpressDevice(SiUsbXpressDeviceInfo deviceInfo)

public SiUsbXpressDeviceInfo DeviceInfo { get; }

protected abstract uint ReadBufferSize { get; }

public bool IsOpen => DeviceHandle != null && !DeviceHandle.IsInvalid && !DeviceHandle.IsClosed;

public void Dispose() => Close();
public virtual void Dispose() => Close();

public void Close()
public virtual void Close()
{
if (!IsOpen)
return;
Expand All @@ -42,7 +40,7 @@ public void Close()
}
}

public void Open()
public virtual void Open()
{
if (IsOpen)
return;
Expand All @@ -60,99 +58,82 @@ public void Open()

_deviceNumber = (uint)deviceNumber.Value;
DeviceHandle = new SafeFileHandle(handle, true);

_ = SiUsbXpressDriver.SI_SetTimeouts(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT);
FlushBuffers();
_ = SiUsbXpressDriver.SI_SetBaudRate(DeviceHandle!.DangerousGetHandle(), MAX_BAUD_RATE);

}

private static void WriteDataImpl(SafeHandle handle, byte[] data)
protected void WriteInternal(byte[] data)
{
uint lpdwBytesWritten = 0;
SiUsbXpressDriver.SI_STATUS code = SiUsbXpressDriver.SI_Write(handle.DangerousGetHandle(), data, (uint)data.Length, ref lpdwBytesWritten, IntPtr.Zero);
SiUsbXpressDriver.SI_STATUS code = SiUsbXpressDriver.SI_Write(DeviceHandle!.DangerousGetHandle(), data, (uint)data.Length, ref lpdwBytesWritten, IntPtr.Zero);
if (code.IsError() || lpdwBytesWritten != data.Length)
throw new SiUsbXpressDriverException(code);
}

private static byte[] ReadDataImpl(SafeHandle handle)
protected byte[] ReadInternal()
{
byte[] buffer = new byte[READ_BUFFER_SIZE];
byte[] buffer = new byte[ReadBufferSize];
uint lpdwBytesReturned = 0;
SiUsbXpressDriver.SI_STATUS code = SiUsbXpressDriver.SI_Read(handle.DangerousGetHandle(), buffer, (uint)buffer.Length, ref lpdwBytesReturned, IntPtr.Zero);
SiUsbXpressDriver.SI_STATUS code = SiUsbXpressDriver.SI_Read(DeviceHandle!.DangerousGetHandle(), buffer, (uint)buffer.Length, ref lpdwBytesReturned, IntPtr.Zero);
if (code.IsError())
throw new SiUsbXpressDriverException(code);
return buffer.Take((int)lpdwBytesReturned).ToArray();
}

public void Write(byte[] buffer)
protected virtual byte[] GetWriteBuffer(byte[] originalBuffer)
{
ThrowIfDeviceNotReady();

byte[] encodedData = EncodingHelper.EncodeData(buffer);
WriteDataImpl(DeviceHandle!, encodedData);
return originalBuffer;
}

public byte[] Read()
public virtual void Write(byte[] buffer)
{
ThrowIfDeviceNotReady();

byte[] encodedData = ReadDataImpl(DeviceHandle!);
return !EncodingHelper.HasError(encodedData)
? EncodingHelper.DecodeData(encodedData)
: throw new SiUsbXpressException("Failed to read - data error.");
WriteInternal(GetWriteBuffer(buffer));
}

public AckStatus ReadAckStatus()
=> AckParser.Parse(Read());

public void WriteAndValidate(byte[] buffer)
protected virtual byte[] GetReadBuffer(byte[] originalBuffer)
{
ThrowIfDeviceNotReady();

Write(buffer);
AckStatus ackStatus = ReadAckStatus();
if (ackStatus != AckStatus.Ok)
throw new SiUsbXpressDeviceAckException(ackStatus);
return originalBuffer;
}

public void WriteWhileBusy(byte[] buffer)
public virtual byte[] Read()
{
ThrowIfDeviceNotReady();

AckStatus ackStatus;
do
{
Write(buffer);
ackStatus = ReadAckStatus();
}
while (ackStatus == AckStatus.Busy);
if (ackStatus != AckStatus.Ok)
throw new SiUsbXpressDeviceAckException(ackStatus);
return GetReadBuffer(ReadInternal());
}

public byte[] WriteAndRead(byte[] buffer)
public virtual byte[] WriteAndRead(byte[] buffer)
{
ThrowIfDeviceNotReady();

Write(buffer);
return Read();
}

public void FlushBuffers()
public virtual void WriteAndValidate(byte[] buffer)
{
throw new NotSupportedException();
}

public virtual void WriteWhileBusy(byte[] buffer)
{
throw new NotSupportedException();
}

public virtual void FlushBuffers()
{
ThrowIfDeviceNotReady();

_ = SiUsbXpressDriver.SI_FlushBuffers(DeviceHandle!.DangerousGetHandle(), 0x01, 0x01);
}

private void ThrowIfDeviceNotReady()
protected void ThrowIfDeviceNotReady()
{
if (!IsOpen)
throw new SiUsbXpressException("Device not ready.");
}

public string GetProductString(ProductString productString)
public virtual string GetProductString(ProductString productString)
{
byte[] data = new byte[SiUsbXpressDriver.SI_MAX_DEVICE_STRLEN];
return SiUsbXpressDriver.SI_GetProductString(_deviceNumber, data, (byte)productString).IsError()
Expand Down
Loading

0 comments on commit f4f46ca

Please sign in to comment.