1
0
mirror of https://github.com/DarthAffe/RGB.NET-PicoPi.git synced 2025-12-13 05:48:37 +00:00

Compare commits

..

4 Commits
v1 ... master

4 changed files with 16 additions and 206 deletions

View File

@ -97,7 +97,7 @@ uint8_t const desc_configuration[] =
{
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 250),
TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID, 0, HID_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, 0x80 | EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 1),
TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, 0x80 | EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 1),
#if CFG_TUD_VENDOR > 0
TUD_VENDOR_DESCRIPTOR(ITF_NUM_DATA, 1, USBD_DATA_EP_OUT, USBD_DATA_EP_IN, 64),
#endif

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
@ -25,7 +25,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HidSharp" Version="2.1.0" />
<PackageReference Include="RGB.NET.Devices.PicoPi" Version="2.1.0" />
</ItemGroup>
</Project>

View File

@ -1,201 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using HidSharp;
//TODO DarthAffe 24.04.2021: Replace with RGB.NET PicoPiSDK once it's merged to main
namespace RGB.NET.Devices.PicoPi
{
public class PicoPiSDK : IDisposable
{
#region Constants
public const int VENDOR_ID = 0x1209;
public const int HID_BULK_CONTROLLER_PID = 0x2812;
private const byte COMMAND_CHANNEL_COUNT = 0x01;
private const byte COMMAND_LEDCOUNTS = 0x0A;
private const byte COMMAND_PINS = 0x0B;
private const byte COMMAND_ID = 0x0E;
private const byte COMMAND_VERSION = 0x0F;
private const byte COMMAND_UPDATE = 0x01;
private const byte COMMAND_UPDATE_BULK = 0x02;
#endregion
#region Properties & Fields
private readonly HidDevice _hidDevice;
private readonly HidStream _hidStream;
private readonly byte[] _hidSendBuffer;
private readonly byte[] _bulkSendBuffer;
private int _bulkTransferLength = 0;
public string Id { get; }
public int Version { get; }
public IReadOnlyList<(int channel, int ledCount, int pin)> Channels { get; }
#endregion
#region Constructors
public PicoPiSDK(HidDevice device)
{
this._hidDevice = device;
_hidSendBuffer = new byte[_hidDevice.GetMaxOutputReportLength() - 1];
_hidStream = _hidDevice.Open();
Id = GetId();
Version = GetVersion();
Channels = new ReadOnlyCollection<(int channel, int ledCount, int pin)>(GetChannels().ToList());
_bulkSendBuffer = new byte[(Channels.Sum(c => c.ledCount + 1) * 3) + 5];
}
#endregion
#region Methods
public void SetLedCounts(params (int channel, int ledCount)[] ledCounts)
{
byte[] data = new byte[Channels.Count + 2];
data[1] = COMMAND_LEDCOUNTS;
foreach ((int channel, int ledCount, _) in Channels)
data[channel + 1] = (byte)ledCount;
foreach ((int channel, int ledCount) in ledCounts)
data[channel + 1] = (byte)ledCount;
SendHID(data);
}
public void SetPins(params (int channel, int pin)[] pins)
{
byte[] data = new byte[Channels.Count + 2];
data[1] = COMMAND_PINS;
foreach ((int channel, _, int pin) in Channels)
data[channel + 1] = (byte)pin;
foreach ((int channel, int pin) in pins)
data[channel + 1] = (byte)pin;
SendHID(data);
}
private string GetId()
{
SendHID(0x00, COMMAND_ID);
return ConversionHelper.ToHex(Read().Skip(1).Take(8).ToArray());
}
private int GetVersion()
{
SendHID(0x00, COMMAND_VERSION);
return Read()[1];
}
private IEnumerable<(int channel, int ledCount, int pin)> GetChannels()
{
SendHID(0x00, COMMAND_CHANNEL_COUNT);
int channelCount = Read()[1];
for (int i = 1; i <= channelCount; i++)
{
SendHID(0x00, (byte)((i << 4) | COMMAND_LEDCOUNTS));
int ledCount = Read()[1];
SendHID(0x00, (byte)((i << 4) | COMMAND_PINS));
int pin = Read()[1];
yield return (i, ledCount, pin);
}
}
public void SendHidUpdate(in Span<byte> data, int channel, int chunk, bool update)
{
if (data.Length == 0) return;
Span<byte> sendBuffer = _hidSendBuffer;
sendBuffer[0] = 0x00;
sendBuffer[1] = (byte)((channel << 4) | COMMAND_UPDATE);
sendBuffer[2] = update ? (byte)1 : (byte)0;
sendBuffer[3] = (byte)chunk;
data.CopyTo(sendBuffer.Slice(4, data.Length));
SendHID(_hidSendBuffer);
}
private void SendHID(params byte[] data) => _hidStream.Write(data);
private byte[] Read() => _hidStream.Read();
public void Dispose()
{
_hidStream.Dispose();
}
#endregion
}
/// <summary>
/// Contains helper methods for converting things.
/// </summary>
public static class ConversionHelper
{
#region Methods
// Source: https://web.archive.org/web/20180224104425/https://stackoverflow.com/questions/623104/byte-to-hex-string/3974535
/// <summary>
/// Converts an array of bytes to a HEX-representation.
/// </summary>
/// <param name="bytes">The array of bytes.</param>
/// <returns>The HEX-representation of the provided bytes.</returns>
public static string ToHex(params byte[] bytes)
{
char[] c = new char[bytes.Length * 2];
for (int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx)
{
byte b = ((byte)(bytes[bx] >> 4));
c[cx] = (char)(b > 9 ? b + 0x37 : b + 0x30);
b = ((byte)(bytes[bx] & 0x0F));
c[++cx] = (char)(b > 9 ? b + 0x37 : b + 0x30);
}
return new string(c);
}
// Source: https://web.archive.org/web/20180224104425/https://stackoverflow.com/questions/623104/byte-to-hex-string/3974535
/// <summary>
/// Converts the HEX-representation of a byte array to that array.
/// </summary>
/// <param name="hexString">The HEX-string to convert.</param>
/// <returns>The correspondending byte array.</returns>
public static byte[] HexToBytes(ReadOnlySpan<char> hexString)
{
if ((hexString.Length == 0) || ((hexString.Length % 2) != 0))
return Array.Empty<byte>();
byte[] buffer = new byte[hexString.Length / 2];
for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx)
{
// Convert first half of byte
char c = hexString[sx];
buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? ((c - 'a') + 10) : ((c - 'A') + 10)) : (c - '0')) << 4);
// Convert second half of byte
c = hexString[++sx];
buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? ((c - 'a') + 10) : ((c - 'A') + 10)) : (c - '0'));
}
return buffer;
}
#endregion
}
}

View File

@ -1,7 +1,18 @@
# RGB.NET-PicoPi
Firmware for the Raspberr Py Pico (RP2040) to be used with [RGB.NET](https://github.com/DarthAffe/RGB.NET).
Firmware for the Raspberry Pi Pico (RP2040) to be used with [RGB.NET](https://github.com/DarthAffe/RGB.NET).
Building the firmware requires the [pico sdk](https://github.com/raspberrypi/pico-sdk) and a recent version of [tinyusb](https://github.com/hathach/tinyusb).
Building the firmware requires the [pico sdk](https://github.com/raspberrypi/pico-sdk).
For precompiled binaries check https://github.com/DarthAffe/RGB.NET-PicoPi/releases
## How to use
1. Load the Pico in boot-mode (pressing the small button on startup) and copy the firmware file (RGB.NET.uf2) onto it.
2. Restart the Pico and open the Config-tool. Configure the amount of leds (set channels to 0 if unused) and if needed the used pins.
3. Restart the Pico
The HID-endpoint is usable with default drivers on windows, if you want to use the Bulk-endpoint (better performance for higher amounts of leds) you need to install the libusb driver for it using Zadig (https://zadig.akeo.ie/).
libusb-win32 works best for me, but the others should work too.
If you're using linux you'll likely need to run applications using this device as root. This can be prevented by changing the read/write permissions of the PicoPi-Device by adding a new udev-rule (for example `85-rgbnet.rules`) in your udev rules directory (most likely something like `/etc/udev/rules.d` containing this single line:
`SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2812", MODE="666"`