Skip to content
Open
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
18 changes: 18 additions & 0 deletions src/StreamDeckSharp/Hardware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ static Hardware()
ElgatoUsbId(0x0063),
ElgatoUsbId(0x0090)
);
// .----------------------.
// | Stream Deck Module 6 |
// '----------------------'

StreamDeckModule6 =
RegisterNewHardwareInternal(
"Stream Deck Module 6",
new GridKeyLayout(3, 2, 80, 25),
new HidComDriverStreamDeckModule6(),
ElgatoUsbId(0x00B8)
);
}

/// <summary>
Expand All @@ -118,6 +129,10 @@ static Hardware()
/// Details about the Stream Deck Mini
/// </summary>
public static IUsbHidHardware StreamDeckMini { get; }
/// <summary>
/// Details about the Stream Deck Module 6
/// </summary>
public static IUsbHidHardware StreamDeckModule6 { get; }

/// <summary>
/// This method registers a new (currently unknown to this library) hardware driver.
Expand Down Expand Up @@ -196,3 +211,6 @@ internal static UsbHardwareIdAndDriver GetInternalHardwareInfos(UsbVendorProduct
}
}
}



20 changes: 10 additions & 10 deletions src/StreamDeckSharp/Internals/HidComDriverStreamDeckMini.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace StreamDeckSharp.Internals
/// <summary>
/// HID Stream Deck communication driver for the Stream Deck Mini.
/// </summary>
public sealed class HidComDriverStreamDeckMini
public class HidComDriverStreamDeckMini
: IStreamDeckHidComDriver
{
private const int ColorChannels = 3;
Expand Down Expand Up @@ -46,22 +46,22 @@ public HidComDriverStreamDeckMini(int imgSize)
public int ReportSize => 1024;

/// <inheritdoc/>
public int ExpectedFeatureReportLength => 17;
public virtual int ExpectedFeatureReportLength => 17;

/// <inheritdoc/>
public int ExpectedOutputReportLength => 1024;
public virtual int ExpectedOutputReportLength => 1024;

/// <inheritdoc/>
public int ExpectedInputReportLength => 17;
public virtual int ExpectedInputReportLength => 17;

/// <inheritdoc/>
public int KeyReportOffset => 1;
public virtual int KeyReportOffset => 1;

/// <inheritdoc/>
public byte FirmwareVersionFeatureId => 4;
public virtual byte FirmwareVersionFeatureId => 4;

/// <inheritdoc/>
public byte SerialNumberFeatureId => 3;
public virtual byte SerialNumberFeatureId => 3;

/// <inheritdoc/>
public int FirmwareVersionReportSkip => 5;
Expand Down Expand Up @@ -112,7 +112,7 @@ public int HardwareKeyIdToExtKeyId(int hardwareKeyId)
}

/// <inheritdoc/>
public void PrepareDataForTransmission(
public virtual void PrepareDataForTransmission(
byte[] data,
int pageNumber,
int payloadLength,
Expand All @@ -128,7 +128,7 @@ bool isLast
}

/// <inheritdoc/>
public byte[] GetBrightnessMessage(byte percent)
public virtual byte[] GetBrightnessMessage(byte percent)
{
if (percent > 100)
{
Expand All @@ -147,7 +147,7 @@ public byte[] GetBrightnessMessage(byte percent)
}

/// <inheritdoc/>
public byte[] GetLogoMessage()
public virtual byte[] GetLogoMessage()
{
return new byte[] { 0x0B, 0x63 };
}
Expand Down
100 changes: 100 additions & 0 deletions src/StreamDeckSharp/Internals/HidComDriverStreamDeckModule6.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using System;

namespace StreamDeckSharp.Internals
{
/// <summary>
/// HID communication driver for Stream Deck Module 6 Keys
/// Based on official Elgato HID documentation: https://docs.elgato.com/streamdeck/hid/module-6
/// Inherits shared image processing logic from <see cref="HidComDriverStreamDeckMini"/>.
/// </summary>
public sealed class HidComDriverStreamDeckModule6 : HidComDriverStreamDeckMini
{
private const int ImageSize = 80; // Module 6 uses 80�80 pixel keys per official specs

/// <summary>
/// Initializes a new instance of the <see cref="HidComDriverStreamDeckModule6"/> class.
/// </summary>
public HidComDriverStreamDeckModule6()
: base(ImageSize)
{
}

// Module 6 specifications per official docs (override Mini's values where different)

/// <inheritdoc/>
public override int ExpectedFeatureReportLength => 32; // Feature reports are 32 bytes

/// <inheritdoc/>
public override int ExpectedInputReportLength => 65; // Input reports are 65 bytes

/// <inheritdoc/>
public override byte FirmwareVersionFeatureId => 0xA1; // AP2 (Primary firmware)

/// <summary>
/// Prepares packet header for Module 6 image upload
/// Per official docs: https://docs.elgato.com/streamdeck/hid/module-6/#upload-data-to-image-memory-bank
/// Offset 0x00: Report ID (0x02)
/// Offset 0x01: Command (0x01)
/// Offset 0x02: Chunk Index
/// Offset 0x03: Reserved (0x00)
/// Offset 0x04: Show Image flag (0x01 to display immediately)
/// Offset 0x05: Key Index
/// Offset 0x06-0x0F: Reserved (10 bytes of 0x00)
/// Offset 0x10+: Chunk Data
/// </summary>
public override void PrepareDataForTransmission(byte[] data, int pageNumber, int payloadLength, int keyId, bool isLast)
{
data[0] = 0x02; // Report ID
data[1] = 0x01; // Command: Upload Data to Image Memory Bank
data[2] = (byte)pageNumber; // Chunk Index
data[3] = 0x00; // Reserved
data[4] = (byte)(isLast ? 0x01 : 0x00); // Show Image flag (show on last packet)
data[5] = (byte)(keyId + 1); // Key Index (0-5 for Module 6)

// Reserved space (bytes 6-15, total 10 bytes)
for (int i = 6; i < 16; i++)
{
data[i] = 0x00;
}

// Payload data starts at offset 0x10 (byte 16)
}

/// <summary>
/// Creates brightness control message for Module 6
/// Per official docs Report ID: 0x05, Command: 0x55
/// </summary>
public override byte[] GetBrightnessMessage(byte percent)
{
if (percent > 100)
{
throw new ArgumentOutOfRangeException(nameof(percent));
}

// Feature Report format for Set Backlight Brightness
var buffer = new byte[32]; // Feature reports are 32 bytes, zero-padded
buffer[0] = 0x05; // Report ID
buffer[1] = 0x55; // Command
buffer[2] = 0xAA;
buffer[3] = 0xD1;
buffer[4] = 0x01;
buffer[5] = percent; // Brightness value (0-100)

return buffer;
}

/// <summary>
/// Creates show logo message for Module 6
/// Per official docs Report ID: 0x0B, Command: 0x63, Payload: 0x00
/// </summary>
public override byte[] GetLogoMessage()
{
var buffer = new byte[32]; // Feature reports are 32 bytes, zero-padded
buffer[0] = 0x0B; // Report ID
buffer[1] = 0x63; // Command
buffer[2] = 0x00; // Show Boot Logo

return buffer;
}
}
}
2 changes: 1 addition & 1 deletion src/StreamDeckSharp/StreamDeckSharp.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net462;net8.0</TargetFrameworks>
Expand Down