Skip to content

Commit

Permalink
Attempting to fix the "non-blittable data" problem as outlined in the…
Browse files Browse the repository at this point in the history
  • Loading branch information
tillig committed Jan 28, 2019
1 parent 639cf04 commit 9d7a067
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 28 deletions.
4 changes: 2 additions & 2 deletions src/AddressableLed/Interop/ws2811_t.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal struct ws2811_t
public IntPtr rpi_hw;
public uint freq;
public int dmanum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = NativeMethods.RPI_PWM_CHANNELS)]
public ws2811_channel_t[] channel;
public ws2811_channel_t channel_0;
public ws2811_channel_t channel_1;
}
}
9 changes: 4 additions & 5 deletions src/AddressableLed/Settings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using AddressableLed.Interop;

namespace AddressableLed
Expand All @@ -17,15 +18,13 @@ public Settings(uint frequency = 800000, int dmaChannel = 10)
{
this.Frequency = frequency;
this.DMAChannel = dmaChannel;
this.Channels = new Channel[NativeMethods.RPI_PWM_CHANNELS];
this.Channels = new List<Channel>();
}

/// <summary>
/// Gets the channels which holds the LEDs.
/// </summary>
// TODO: Refactor this to be a list or collection if it won't impact interop.
[SuppressMessage("CA1819", "CA1819", Justification = "Need to refactor this if possible.")]
public Channel[] Channels { get; private set; }
public IList<Channel> Channels { get; private set; }

/// <summary>
/// Gets the DMA channel.
Expand Down
51 changes: 32 additions & 19 deletions src/AddressableLed/WS281x.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,11 @@ public WS281x(Settings settings)

this._ws2811.dmanum = settings.DMAChannel;
this._ws2811.freq = settings.Frequency;
this._ws2811.channel = new ws2811_channel_t[NativeMethods.RPI_PWM_CHANNELS];

for (var i = 0; i <= this._ws2811.channel.Length - 1; i++)
{
if (settings.Channels[i] != null)
{
this.InitChannel(i, settings.Channels[i]);
}
}
this._ws2811.channel_0 = default(ws2811_channel_t);
this._ws2811.channel_1 = default(ws2811_channel_t);

this.InitChannel(this._ws2811.channel_0, settings.Channels[0]);
this.InitChannel(this._ws2811.channel_1, settings.Channels[1]);
this.Settings = settings;

var initResult = NativeMethods.ws2811_init(ref this._ws2811);
Expand Down Expand Up @@ -80,12 +75,29 @@ public void Dispose()
/// </summary>
public void Render()
{
for (var i = 0; i <= this.Settings.Channels.Length - 1; i++)
for (var i = 0; i < this.Settings.Channels.Count; i++)
{
var channel = default(ws2811_channel_t);
channel.leds = IntPtr.Zero;
if (this.Settings.Channels[i] != null)
{
var ledColor = this.Settings.Channels[i].LEDs.Select(x => x.RGBValue).ToArray();
Marshal.Copy(ledColor, 0, this._ws2811.channel[i].leds, ledColor.Count());
switch (i)
{
case 0:
channel = this._ws2811.channel_0;
break;
case 1:
channel = this._ws2811.channel_1;
break;
default:
break;
}

if (channel.leds != IntPtr.Zero)
{
var ledColor = this.Settings.Channels[i].LEDs.Select(x => x.RGBValue).ToArray();
Marshal.Copy(ledColor, 0, channel.leds, ledColor.Count());
}
}
}

Expand Down Expand Up @@ -137,20 +149,21 @@ private static string GetMessageForStatusCode(ws2811_return_t statusCode)
/// <summary>
/// Initialize the channel properties.
/// </summary>
/// <param name="channelIndex">Index of the channel to initialize.</param>
/// <param name="channel">Channel to initialize.</param>
/// <param name="channelSettings">Settings for the channel.</param>
private void InitChannel(int channelIndex, Channel channelSettings)
private void InitChannel(ws2811_channel_t channel, Channel channelSettings)
{
this._ws2811.channel[channelIndex].count = channelSettings.LEDs.Count;
this._ws2811.channel[channelIndex].gpionum = channelSettings.GPIOPin;
this._ws2811.channel[channelIndex].brightness = channelSettings.Brightness;
this._ws2811.channel[channelIndex].invert = Convert.ToInt32(channelSettings.Invert);
channel.leds = IntPtr.Zero;
channel.count = channelSettings.LEDs.Count;
channel.gpionum = channelSettings.GPIOPin;
channel.brightness = channelSettings.Brightness;
channel.invert = Convert.ToInt32(channelSettings.Invert);

if (channelSettings.StripType != StripType.Unknown)
{
// Strip type is set by the native assembly if not explicitly set.
// This type defines the ordering of the colors e. g. RGB or GRB, ...
this._ws2811.channel[channelIndex].strip_type = (int)channelSettings.StripType;
channel.strip_type = (int)channelSettings.StripType;
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/ConsoleDemo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ private static void Main()
// https:/rpi-ws281x/rpi-ws281x-csharp
// https:/chris579/rpi_ws281x.Net
var settings = new Settings();
settings.Channels[0] = new Channel(540, 18, 64, false, StripType.WS2812_STRIP);
settings.Channels.Add(new Channel(540, 18, 64, false, StripType.WS2812_STRIP));

using (var controller = new WS281x(settings))
// TODO: using (ILedController controller = new WS281x(settings))
using (ILedController controller = new StubLedController(settings))
{
var animations = new IAnimation[]
{
Expand All @@ -38,12 +39,15 @@ private static void Main()
{
foreach (var animation in animations)
{
Console.WriteLine(animation.ToString());
animation.Execute(tokenSource.Token);
Thread.Sleep(1000);
}
}
},
tokenSource.Token);
Console.ReadKey();
Console.WriteLine("Finishing up.");
tokenSource.Cancel();
task.Wait();
var off = new ColorWipe(controller, Color.Black);
Expand Down

0 comments on commit 9d7a067

Please sign in to comment.