未验证 提交 62d161bf 编写于 作者: I Ian Bebbington 提交者: GitHub

Added LP55231 Support (#1763)

上级 c1e6e18d
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Iot.Device.Lp55231
{
/// <summary>
/// Flags related to the REG_CNTRL1 register
/// </summary>
[Flags]
internal enum Control1RegisterFlags : byte
{
/// <summary>
/// Enable the Lp55231
/// </summary>
Enabled = 0x40
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Device.I2c;
using System.IO;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
namespace Iot.Device.Lp55231
{
/// <summary>
/// Lp55231 9 channel I2C PWM LED controller
/// </summary>
public class Lp55231 : IDisposable
{
/// <summary>
/// Default I2C address of Motor Hat
/// </summary>
public const int DefaultI2cAddress = 0x32;
/// <summary>
/// Gets the channel of the red element of the specific instance
/// </summary>
/// <param name="instance">The RGB instance (0-2)</param>
/// <returns>The channel number</returns>
internal static byte RedChannel(byte instance) => (byte)(6 + instance);
/// <summary>
/// Gets the channel of the green element of the specific instance
/// </summary>
/// <param name="instance">The RGB instance (0-2)</param>
/// <returns>The channel number</returns>
internal static byte GreenChannel(byte instance) => (byte)(instance * 2);
/// <summary>
/// Gets the channel of the blue element of the specific instance
/// </summary>
/// <param name="instance">The RGB instance (0-2)</param>
/// <returns>The channel number</returns>
internal static byte BlueChannel(byte instance) => (byte)(instance * 2 + 1);
private readonly Color[] _leds;
private I2cDevice _i2cDevice;
/// <summary>
/// Initializes a new instance of the <see cref="Lp55231"/> class with the specified <see cref="I2cDevice"/>.
/// </summary>
/// <param name="i2cDevice">The I2C device to use to communicate with the Lp55231.</param>
/// <remarks>
/// The default i2c address is 0x32.
/// </remarks>
public Lp55231(I2cDevice i2cDevice)
{
_i2cDevice = i2cDevice ?? throw new ArgumentNullException(nameof(i2cDevice));
_leds = new[]
{
Color.FromRgba(0, 0, 0, byte.MaxValue),
Color.FromRgba(0, 0, 0, byte.MaxValue),
Color.FromRgba(0, 0, 0, byte.MaxValue)
};
}
private byte ReadRegister(Register register)
{
_i2cDevice.WriteByte((byte)register);
return _i2cDevice.ReadByte();
}
private void WriteRegister(Register register, byte data)
{
Span<byte> bytes = stackalloc byte[2];
bytes[0] = (byte)register;
bytes[1] = data;
_i2cDevice.Write(bytes);
}
private void SetIntensity(byte index, byte value)
{
WriteRegister(Register.REG_D1_PWM + index, value);
}
/// <inheritdoc/>
public void Dispose()
{
_i2cDevice?.Dispose();
_i2cDevice = null!;
}
/// <summary>
/// Resets the Lp55231
/// </summary>
/// <remarks>
/// You should delay after calling this method
/// </remarks>
public void Reset()
{
try
{
WriteRegister(Register.REG_RESET, 0xFF);
}
catch (IOException)
{
// Resetting will prevent the expected ack resulting
// in an IOException. It's fine to swallow this.
}
}
/// <summary>
/// Gets/sets whether the Lp55231 is enabled.
/// </summary>
/// <remarks>
/// Setting this value will stop eny programs currently running.
/// </remarks>
public bool Enabled
{
get
{
var register = ReadRegister(Register.REG_CNTRL1);
return (register & (byte)Control1RegisterFlags.Enabled) > 0;
}
set
{
byte flags = value
? (byte)Control1RegisterFlags.Enabled
: (byte)0x00;
WriteRegister(Register.REG_CNTRL1, flags);
}
}
/// <summary>
/// Gets/sets miscellaneous control flags
/// </summary>
public MiscFlags Misc
{
get
{
var flags = ReadRegister(Register.REG_MISC);
return (MiscFlags)flags;
}
set
{
var flags = (byte)value;
WriteRegister(Register.REG_MISC, flags);
}
}
/// <summary>
/// Gets or sets the <see cref="Color"/> of the LED at the specified <paramref name="index"/>.
/// </summary>
/// <param name="index">The index of the LED.</param>
/// <returns>The current <see cref="Color"/> of the LED.</returns>
/// <exception cref="ArgumentOutOfRangeException">Index must be between 0 and 2.</exception>
public Color this[byte index]
{
get
{
if (index < 0 || index > 2)
{
throw new ArgumentOutOfRangeException(nameof(index));
}
return _leds[index];
}
set
{
if (index < 0 || index > 2)
{
throw new ArgumentOutOfRangeException(nameof(index));
}
if (value != _leds[index])
{
var color = value.ToPixel<Rgba32>();
SetIntensity(RedChannel(index), color.R);
SetIntensity(GreenChannel(index), color.G);
SetIntensity(BlueChannel(index), color.B);
_leds[index] = value;
}
}
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(DefaultBindingTfms)</TargetFrameworks>
<!--Disabling default items so samples source won't get build by the main library-->
<EnableDefaultItems>false</EnableDefaultItems>
</PropertyGroup>
<ItemGroup>
<Compile Include="*.cs" />
<None Include="README.md" />
<ProjectReference Include="..\Common\CommonHelpers.csproj" />
</ItemGroup>
</Project>
\ No newline at end of file

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.32112.339
MinimumVisualStudioVersion = 15.0.26124.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{78DA6C88-DD5E-4280-ACFF-494978273FD5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lp55231", "Lp55231.csproj", "{37BD4AE4-290A-4F4C-912A-F0430068F157}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lp55231.Samples", "samples\Lp55231.Samples.csproj", "{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Debug|Any CPU.Build.0 = Debug|Any CPU
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Debug|x64.ActiveCfg = Debug|Any CPU
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Debug|x64.Build.0 = Debug|Any CPU
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Debug|x86.ActiveCfg = Debug|Any CPU
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Debug|x86.Build.0 = Debug|Any CPU
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Release|Any CPU.ActiveCfg = Release|Any CPU
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Release|Any CPU.Build.0 = Release|Any CPU
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Release|x64.ActiveCfg = Release|Any CPU
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Release|x64.Build.0 = Release|Any CPU
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Release|x86.ActiveCfg = Release|Any CPU
{37BD4AE4-290A-4F4C-912A-F0430068F157}.Release|x86.Build.0 = Release|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Debug|x64.ActiveCfg = Debug|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Debug|x64.Build.0 = Debug|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Debug|x86.ActiveCfg = Debug|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Debug|x86.Build.0 = Debug|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Release|Any CPU.Build.0 = Release|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Release|x64.ActiveCfg = Release|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Release|x64.Build.0 = Release|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Release|x86.ActiveCfg = Release|Any CPU
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{81C59B4A-4E1F-4136-AE3C-198D0A4CFFA1} = {78DA6C88-DD5E-4280-ACFF-494978273FD5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E3277930-E6B6-49D7-8640-884DF1F85538}
EndGlobalSection
EndGlobal
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Iot.Device.Lp55231
{
/// <summary>
/// Flags related to the REG_MISC register
/// </summary>
[Flags]
public enum MiscFlags : byte
{
/// <summary>
/// Use internal clock
/// </summary>
ClockSourceSelection = 0b0000_0001,
/// <summary>
/// Use external clock
/// </summary>
ExternalClockDetection = 0b0000_0010,
/// <summary>
/// Enable PWM cycle power save
/// </summary>
PwmCyclePowersaveEnable = 0b0000_0100,
/// <summary>
/// Charge mode gain low bit
/// </summary>
ChargeModeGainLowBit = 0b0000_1000,
/// <summary>
/// Charge mode gain high bit
/// </summary>
ChargeModeGainHighBit = 0b0001_0000,
/// <summary>
/// Enable power save mode
/// </summary>
PowersaveModeEnable = 0b0010_0000,
/// <summary>
/// Enable auto address increment
/// </summary>
AddressAutoIncrementEnable = 0b0100_0000
}
}
# Lp55231 - Nine-Channel RGB, White-LED Driver
The Lp55231 is a I2C controlled, Nine-Channel RGB, White-LED Driver With Internal Program Memory and Integrated Charge Pump.
## Documentation
- [Texas Instruments](https://www.ti.com/product/LP55231)
- [Sparkfun](https://www.sparkfun.com/products/13884)
## Usage
This driver currently provides just the fundamentals to drive RGB Leds. It does not currently support
- Individual control of PWM channels
- Setting LED drive current
- Programming
### RGB Leds
The following example show how to use the RGB leds on the Sparkfun Lp55231 breakout board.
```csharp
var i2cDevice = I2cDevice.Create(new I2cConnectionSettings(1, Lp55231.DefaultI2cAddress));
using (var device = new Lp55231(i2cDevice))
{
device.Reset();
// Give the IC time to restart
Thread.Sleep(100);
device.Enabled = true;
device.Misc = MiscFlags.ClockSourceSelection
| MiscFlags.ExternalClockDetection
| MiscFlags.ChargeModeGainHighBit
| MiscFlags.AddressAutoIncrementEnable;
ledDriver[0] = Color.FromArgb(0, 255, 0, 0);
ledDriver[1] = Color.FromArgb(0, 0, 255, 0);
ledDriver[2] = Color.FromArgb(0, 0, 0, 255);
}
```
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Iot.Device.Lp55231
{
/// <summary>
/// Registers for the Lp55231 based on this reference: https://www.ti.com/lit/gpn/lp55231
/// </summary>
internal enum Register : byte
{
/// <summary/>
REG_CNTRL1 = 0x00,
/// <summary/>
REG_CNTRL2 = 0x01,
/// <summary/>
REG_RATIO_MSB = 0x02,
/// <summary/>
REG_RATIO_LSB = 0x03,
/// <summary/>
REG_OUTPUT_ONOFF_MSB = 0x04,
/// <summary/>
REG_OUTPUT_ONOFF_LSB = 0x05,
// Per LED control channels - fader channel assig, log dimming enable, temperature compensation
/// <summary/>
REG_D1_CTRL = 0x06,
/// <summary/>
REG_D2_CTRL = 0x07,
/// <summary/>
REG_D3_CTRL = 0x08,
/// <summary/>
REG_D4_CTRL = 0x09,
/// <summary/>
REG_D5_CTRL = 0x0a,
/// <summary/>
REG_D6_CTRL = 0x0b,
/// <summary/>
REG_D7_CTRL = 0x0c,
/// <summary/>
REG_D8_CTRL = 0x0d,
/// <summary/>
REG_D9_CTRL = 0x0e,
// Direct PWM control registers
/// <summary/>
REG_D1_PWM = 0x16,
/// <summary/>
REG_D2_PWM = 0x17,
/// <summary/>
REG_D3_PWM = 0x18,
/// <summary/>
REG_D4_PWM = 0x19,
/// <summary/>
REG_D5_PWM = 0x1a,
/// <summary/>
REG_D6_PWM = 0x1b,
/// <summary/>
REG_D7_PWM = 0x1c,
/// <summary/>
REG_D8_PWM = 0x1d,
/// <summary/>
REG_D9_PWM = 0x1e,
// Drive cuttent registers
/// <summary/>
REG_D1_I_CTL = 0x26,
/// <summary/>
REG_D2_I_CTL = 0x27,
/// <summary/>
REG_D3_I_CTL = 0x28,
/// <summary/>
REG_D4_I_CTL = 0x29,
/// <summary/>
REG_D5_I_CTL = 0x2a,
/// <summary/>
REG_D6_I_CTL = 0x2b,
/// <summary/>
REG_D7_I_CTL = 0x2c,
/// <summary/>
REG_D8_I_CTL = 0x2d,
/// <summary/>
REG_D9_I_CTL = 0x2e,
/// <summary/>
REG_MISC = 0x36,
/// <summary/>
REG_PC1 = 0x37,
/// <summary/>
REG_PC2 = 0x38,
/// <summary/>
REG_PC3 = 0x39,
/// <summary/>
REG_STATUS_IRQ = 0x3A,
/// <summary/>
REG_RESET = 0x3D,
/// <summary/>
REG_PROG1_START = 0x4C,
/// <summary/>
REG_PROG2_START = 0x4D,
/// <summary/>
REG_PROG3_START = 0x4E,
/// <summary/>
REG_PROG_PAGE_SEL = 0x4f,
// Memory is more confusing - there are 4 pages, sel by addr 4f
/// <summary/>
REG_PROG_MEM_BASE = 0x50,
// static const uint8_t REG_PROG_MEM_SIZE = 0x;//
/// <summary/>
REG_PROG_MEM_END = 0x6f,
/// <summary/>
REG_ENG1_MAP_MSB = 0x70,
/// <summary/>
REG_ENG1_MAP_LSB = 0x71,
/// <summary/>
REG_ENG2_MAP_MSB = 0x72,
/// <summary/>
REG_ENG2_MAP_LSB = 0x73,
/// <summary/>
REG_ENG3_MAP_MSB = 0x74,
/// <summary/>
REG_ENG3_MAP_LSB = 0x75,
}
}
display
led
pwm
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>$(DefaultSampleTfms)</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="$(SystemDrawingCommonPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lp55231.csproj" />
</ItemGroup>
</Project>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Device.I2c;
using System.Threading;
using Iot.Device.Lp55231;
using SixLabors.ImageSharp;
var i2cDevice = I2cDevice.Create(new I2cConnectionSettings(1, Lp55231.DefaultI2cAddress));
using var ledDriver = new Lp55231(i2cDevice);
ledDriver.Reset();
Thread.Sleep(100);
ledDriver.Enabled = true;
ledDriver.Misc = MiscFlags.ClockSourceSelection
| MiscFlags.ExternalClockDetection
| MiscFlags.ChargeModeGainHighBit
| MiscFlags.AddressAutoIncrementEnable;
ledDriver[0] = Color.FromRgba(255, 0, 0, byte.MaxValue);
ledDriver[1] = Color.FromRgba(0, 255, 0, byte.MaxValue);
ledDriver[2] = Color.FromRgba(0, 0, 255, byte.MaxValue);
Console.WriteLine("Should be showing red, green, blue");
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册