Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
275 changes: 253 additions & 22 deletions FrameworkArgb/Device.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Module Name:
#include "driver.h"
#include "EcCommunication.h"
#include "device.tmh"
#define _USE_MATH_DEFINES
#include <math.h>

//
// This is the default report descriptor for the virtual Hid device returned
Expand Down Expand Up @@ -200,6 +202,101 @@ HID_DESCRIPTOR G_DefaultHidDescriptor = {
}
};

NTSTATUS
CalculateLampPositions(
PDEVICE_CONTEXT DeviceContext,
UINT16 LampCount,
UINT8 LedArrangement
)
{
UINT8 Layers = 0;
if (LampCount > MAX_LAMPARRAY_LAMP_COUNT) {
TraceError("LampCount %d over %d", LampCount, MAX_LAMPARRAY_LAMP_COUNT);
return STATUS_INVALID_PARAMETER;
}

switch (LedArrangement) {
// Circular, layers of 8
case 0:
DeviceContext->Width = 80000;
DeviceContext->Height = 80000;
DeviceContext->Depth = 2000 * (LampCount / 8);
for (UINT8 i = 0; i <= LampCount / 8; i++) {
// 8 LEDs in a circle
// z is 0 for all LEDs, they're all in the same plane
// Bottom LED
DeviceContext->LampPositions[i+0].x = 40000;
DeviceContext->LampPositions[i+0].y = 0;
DeviceContext->LampPositions[i+0].z = 2000 * i;
DeviceContext->LampPositions[i+1].x = 60000;
DeviceContext->LampPositions[i+1].y = 20000;
DeviceContext->LampPositions[i+1].z = 2000 * i;
// Right LED
DeviceContext->LampPositions[i+2].x = 80000;
DeviceContext->LampPositions[i+2].y = 40000;
DeviceContext->LampPositions[i+2].z = 2000 * i;
DeviceContext->LampPositions[i+3].x = 60000;
DeviceContext->LampPositions[i+3].y = 60000;
DeviceContext->LampPositions[i+3].z = 2000 * i;
// Top LED
DeviceContext->LampPositions[i+4].x = 40000;
DeviceContext->LampPositions[i+4].y = 80000;
DeviceContext->LampPositions[i+1].z = 2000 * i;
DeviceContext->LampPositions[i+4].x = 20000;
DeviceContext->LampPositions[i+5].y = 60000;
DeviceContext->LampPositions[i+5].z = 2000 * i;
// Left LED
DeviceContext->LampPositions[i+6].x = 0;
DeviceContext->LampPositions[i+6].y = 40000;
DeviceContext->LampPositions[i+6].z = 2000 * i;
DeviceContext->LampPositions[i+7].x = 20000;
DeviceContext->LampPositions[i+7].y = 20000;
DeviceContext->LampPositions[i+7].z = 2000 * i;
}
break;
// LEDs arranged in a circle single layer, even distance from each other
case 1:
DeviceContext->Width = 80000;
DeviceContext->Height = 80000;
{
// Place LampCount LEDs evenly spaced around a circle of radius 40000 (centered at 40000,40000)
double centerX = 40000.0;
double centerY = 40000.0;
double radius = 40000.0;
for (UINT8 i = 0; i < LampCount; i++) {
double angle = (2.0 * M_PI * i) / LampCount;
DeviceContext->LampPositions[i].x = (UINT32)(centerX + radius * cos(angle));
DeviceContext->LampPositions[i].y = (UINT32)(centerY + radius * sin(angle));
}
}
break;
// Linear, LED strip with 5mm distance
case 2:
DeviceContext->Width = LampCount * 5000;
DeviceContext->Height = 0;
for (UINT8 i = 0; i <= LampCount / 8; i++) {
DeviceContext->LampPositions[i].x = i * 5000;
DeviceContext->LampPositions[i].y = 0;
}
break;
// Square Matrix with 5mm distance
case 3:
Layers = (UINT8) sqrt((double) LampCount);
DeviceContext->Width = Layers * 5000;
DeviceContext->Height = Layers * 5000;
for (UINT8 i = 0; i <= LampCount; i++) {
DeviceContext->LampPositions[i].x = (i % Layers) * 5000;
DeviceContext->LampPositions[i].y = (i / Layers) * 5000;
}
break;
default:
TraceError("LedArrangement %d invalid.", LedArrangement);
return STATUS_INVALID_PARAMETER;
}

return STATUS_SUCCESS;
}

NTSTATUS
FrameworkArgbCreateDevice(
_Inout_ PWDFDEVICE_INIT DeviceInit
Expand Down Expand Up @@ -227,6 +324,8 @@ Return Value:
PHID_DEVICE_ATTRIBUTES hidAttributes;
WDFDEVICE device;
NTSTATUS status;
UINT8 LampCount;
UINT8 LedArrangement;

TraceInformation("%!FUNC! Entry");

Expand Down Expand Up @@ -261,28 +360,39 @@ Return Value:
deviceContext->Device = device;
deviceContext->CurrentLampId = 0;
deviceContext->AutonomousMode = TRUE;
// 8 LEDs in a circle
// z is 0 for all LEDs, they're all in the same plane
// Bottom LED
deviceContext->LampPositions[0].x = 40000;
deviceContext->LampPositions[0].y = 0;
deviceContext->LampPositions[1].x = 60000;
deviceContext->LampPositions[1].y = 20000;
// Right LED
deviceContext->LampPositions[2].x = 80000;
deviceContext->LampPositions[2].y = 40000;
deviceContext->LampPositions[3].x = 60000;
deviceContext->LampPositions[3].y = 60000;
// Top LED
deviceContext->LampPositions[4].x = 40000;
deviceContext->LampPositions[4].y = 80000;
deviceContext->LampPositions[5].x = 20000;
deviceContext->LampPositions[5].y = 60000;
// Left LED
deviceContext->LampPositions[6].x = 0;
deviceContext->LampPositions[6].y = 40000;
deviceContext->LampPositions[7].x = 20000;
deviceContext->LampPositions[7].y = 20000;

LampCount = 0;
deviceContext->LampCount = 0;
deviceContext->Width = 0;
deviceContext->Height = 0;
deviceContext->Depth = 2000;
LedArrangement = 0;
status = CheckRegistryForLedConfig(device);
if (NT_SUCCESS(status)) {
//
// We need to read read descriptor from registry
//
status = ReadLedConfigFromRegistry(device, &LampCount, &LedArrangement);
if (!NT_SUCCESS(status)) {
TraceError("Failed to read LED config from registry\n");
}
}

status = CalculateLampPositions(deviceContext, LampCount, LedArrangement);
if (!NT_SUCCESS(status)) {
TraceError("Failed to calulcate lamp positions\n");
deviceContext->LampCount = 0;
}
else {
deviceContext->LampCount = LampCount;
}

// Default 8 LED fan
if (deviceContext->LampCount == 0) {
TraceError("No lamps set, falling back to default");
deviceContext->LampCount = 8;
LedArrangement = 0;
}

hidAttributes = &deviceContext->HidDeviceAttributes;
RtlZeroMemory(hidAttributes, sizeof(HID_DEVICE_ATTRIBUTES));
Expand Down Expand Up @@ -526,3 +636,124 @@ Return Value:
status = RequestCopyFromBuffer(Request, string, stringSizeCb);
return status;
}

NTSTATUS
CheckRegistryForLedConfig(
WDFDEVICE Device
)
/*++

Routine Description:

Read "ReadFromRegistry" key value from device parameters in the registry.

Arguments:

device - pointer to a device object.

Return Value:

NT status code.

--*/

{
WDFKEY hKey = NULL;
NTSTATUS status;
UNICODE_STRING valueName;
ULONG value;

TraceInformation("%!FUNC! Entry");
status = WdfDeviceOpenRegistryKey(Device,
PLUGPLAY_REGKEY_DEVICE,
KEY_READ,
WDF_NO_OBJECT_ATTRIBUTES,
&hKey);
if (NT_SUCCESS(status)) {
TraceInformation("%!FUNC! Found driver Registry key");
RtlInitUnicodeString(&valueName, L"ReadFromRegistry");

status = WdfRegistryQueryULong(hKey,
&valueName,
&value);

if (NT_SUCCESS(status)) {
TraceInformation("%!FUNC! ReadFromRegistry has value: %d", value);
if (value == 0) {
status = STATUS_UNSUCCESSFUL;
}
}

WdfRegistryClose(hKey);
}

TraceInformation("%!FUNC! Exiting with %!STATUS!", status);
return status;
}

NTSTATUS
ReadLedConfigFromRegistry(
WDFDEVICE Device,
UINT8 *LampCount,
UINT8 *LedArrangement
)
/*++

Routine Description:

Read LED config report descriptor from registry

Arguments:

device - pointer to a device object.

Return Value:

NT status code.

--*/
{
WDFKEY hKey = NULL;
NTSTATUS status;
UNICODE_STRING valueName;
PDEVICE_CONTEXT deviceContext;
ULONG value;

TraceInformation("%!FUNC! Entry");
deviceContext = GetDeviceContext(Device);

status = WdfDeviceOpenRegistryKey(Device,
PLUGPLAY_REGKEY_DEVICE,
KEY_READ,
WDF_NO_OBJECT_ATTRIBUTES,
&hKey);

if (!NT_SUCCESS(status)) {
TraceError("%!FUNC! Failed to find driver registry key");
return status;
}

RtlInitUnicodeString(&valueName, L"LedCount");
status = WdfRegistryQueryULong(hKey, &valueName, &value);
if (!NT_SUCCESS(status)) {
TraceError("%!FUNC! Failed to WdfRegistryQueryULong LedCount: %!STATUS!", status);
WdfRegistryClose(hKey);
return status;
}
TraceInformation("%!FUNC! LedCount has value: %d", value);
*LampCount = (UINT8) value;

RtlInitUnicodeString(&valueName, L"LedArrangement");
status = WdfRegistryQueryULong(hKey, &valueName, &value);
if (!NT_SUCCESS(status)) {
TraceError("%!FUNC! Failed to WdfRegistryQueryULong LedArrangement: %!STATUS!", status);
WdfRegistryClose(hKey);
return status;
}
TraceInformation("%!FUNC! LedArrangement has value: %d", value);
*LedArrangement = (UINT8) value;

WdfRegistryClose(hKey);

return status;
}
26 changes: 20 additions & 6 deletions FrameworkArgb/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_DEVICE_ADD EvtDeviceAdd;
EVT_WDF_TIMER EvtTimerFunc;

#define LAMPARRAY_LAMP_COUNT 8
#define LAMPARRAY_WIDTH 80000 // 80mm
#define LAMPARRAY_HEIGHT 80000 // 80mm
#define LAMPARRAY_DEPTH 20000 // 20mm
#define MAX_LAMPARRAY_LAMP_COUNT 256
//#define LAMPARRAY_WIDTH 80000 // 80mm
//#define LAMPARRAY_HEIGHT 80000 // 80mm
//#define LAMPARRAY_DEPTH 20000 // 20mm
#define LAMPARRAY_KIND 0x07 // LampArrayKindChassis
#define LAMPARRAY_UPDATE_INTERVAL 100000 // 10ms

Expand All @@ -48,10 +48,13 @@ typedef struct _DEVICE_CONTEXT
HANDLE CrosEcHandle;
UINT16 CurrentLampId;
BOOLEAN AutonomousMode;
Position LampPositions[LAMPARRAY_LAMP_COUNT];
UINT16 LampCount;
UINT32 Width;
UINT32 Height;
UINT32 Depth;
Position LampPositions[MAX_LAMPARRAY_LAMP_COUNT];
HID_DESCRIPTOR HidDescriptor;
PHID_REPORT_DESCRIPTOR ReportDescriptor;
BOOLEAN ReadReportDescFromRegistry;
} DEVICE_CONTEXT, * PDEVICE_CONTEXT;

//
Expand Down Expand Up @@ -168,6 +171,17 @@ RequestGetHidXferPacket_ToWriteToDevice(
_Out_ HID_XFER_PACKET* Packet
);

NTSTATUS
CheckRegistryForLedConfig(
_In_ WDFDEVICE Device
);

NTSTATUS
ReadLedConfigFromRegistry(
_In_ WDFDEVICE Device,
_Out_ UINT8 *LampCount,
_Out_ UINT8 *LedArrangement
);

//
// Misc definitions
Expand Down
4 changes: 2 additions & 2 deletions FrameworkArgb/FrameworkArgb.inf
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
; INF file for installing HID minidriver (UMDF 2 version)
;
; Installation Notes:
; Using Devcon: Type "devcon install FrameworkArgb.inf root\FrameworkArgb" to install
; Using pnputil: Type "sudo pnputil /add-driver FrameworkArgb.inf /install" to install
;
; Important:
; This INF depends on MsHidUmdf.inf, which was introduced in build 22000
Expand Down Expand Up @@ -40,7 +40,7 @@ FrameworkArgb.dll = 1
%ManufacturerName% = Standard,NT$ARCH$.10.0...22000 ; wudfrd.inf introduced in build 22000

[Standard.NT$ARCH$.10.0...22000]
%DeviceName% = FrameworkArgb, Root\FrameworkArgb ; TODO: edit hw-id
%DeviceName% = FrameworkArgb, ACPI\FRMW0006


; =================== UMDF Device ==================================
Expand Down
10 changes: 5 additions & 5 deletions FrameworkArgb/LampArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ GetLampArrayAttributesReport(
DeviceContext = DeviceContext;

LampArrayAttributesReport report = {
LAMPARRAY_LAMP_COUNT,
LAMPARRAY_WIDTH,
LAMPARRAY_HEIGHT,
LAMPARRAY_DEPTH,
DeviceContext->LampCount,
DeviceContext->Width,
DeviceContext->Height,
DeviceContext->Depth,
LAMPARRAY_KIND,
LAMPARRAY_UPDATE_INTERVAL
};
Expand Down Expand Up @@ -112,7 +112,7 @@ GetLampAttributesResponseReport(
};

RtlCopyMemory(ReportBuffer, &report, sizeof(LampAttributesResponseReport));
DeviceContext->CurrentLampId = CurrentLampId + 1 >= LAMPARRAY_LAMP_COUNT ? CurrentLampId : CurrentLampId + 1;
DeviceContext->CurrentLampId = CurrentLampId + 1 >= DeviceContext->LampCount ? CurrentLampId : CurrentLampId + 1;

return Size;

Expand Down
Loading