提交 b39333e1 编写于 作者: D Dmitriy Shelpanov 提交者: Krzysztof Wicher

Added support for SSD1327 display 96x96 (#316)

* Added support for SSD1327 display 96x96

* Fixed some comments

* Typo fixes

* Removed unnecessary virtal method

* Removed unnecessary cast

* Implemented common buffer

* Little document change

* Little fixes.

* throw ArgumentOutOfRangeException where appropriate
上级 41e22025
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands
{
public class ActivateScroll : ICommand
public class ActivateScroll : ISharedCommand
{
/// <summary>
/// This command starts the motion of scrolling and should only be issued
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands
{
public class DeactivateScroll : ICommand
public class DeactivateScroll : ISharedCommand
{
/// <summary>
/// This command stops the motion of scrolling. After sending 2Eh command to deactivate
......
......@@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands
{
public interface ICommand
{
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd13xx.Commands
{
public interface ISharedCommand : ICommand
{
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd13xx.Commands
{
public interface ISsd1306Command : ICommand
{
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd13xx.Commands
{
public interface ISsd1327Command : ICommand
{
}
}
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands
{
public class SetContrastControlForBank0 : ICommand
public class SetContrastControlForBank0 : ISharedCommand
{
/// <summary>
/// This command sets the Contrast Setting of the display.
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands
{
public class SetDisplayOff : ICommand
public class SetDisplayOff : ISharedCommand
{
/// <summary>
/// This command turns the OLED panel display off.
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands
{
public class SetDisplayOn : ICommand
public class SetDisplayOn : ISharedCommand
{
/// <summary>
/// This command turns the OLED panel display on.
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands
{
public class SetInverseDisplay : ICommand
public class SetInverseDisplay : ISharedCommand
{
/// <summary>
/// This command sets the display to be inverse. Displays a RAM data of 0 indicates an ON pixel.
......
......@@ -4,18 +4,18 @@
using System;
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands
{
public class SetMultiplexRatio : ICommand
public class SetMultiplexRatio : ISharedCommand
{
/// <summary>
/// This command switches the default 63 multiplex mode to any multiplex ratio, ranging from 15 to 63.
/// This command switches the default 63 multiplex mode to any multiplex ratio, ranging from 15 to 127.
/// The output pads COM0-COM63 will be switched to the corresponding COM signal.
/// </summary>
/// <param name="multiplexRatio">Multiplex ratio with a range of 15-63.</param>
/// <param name="multiplexRatio">Multiplex ratio with a range of 15-127.</param>
public SetMultiplexRatio(byte multiplexRatio = 63)
{
if (!Ssd1306.InRange(multiplexRatio, 0x0F, 0x3F))
if (!Ssd13xx.InRange(multiplexRatio, 0x0F, 0x7F))
{
throw new ArgumentException("The multiplex ratio is invalid.", nameof(multiplexRatio));
}
......
......@@ -4,9 +4,9 @@
using System;
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class ContinuousVerticalAndHorizontalScrollSetup : ICommand
public class ContinuousVerticalAndHorizontalScrollSetup : ISsd1306Command
{
/// <summary>
/// This command consists of 6 consecutive bytes to set up the continuous vertical
......@@ -27,7 +27,7 @@ namespace Iot.Device.Ssd1306.Command
{
if (verticalScrollingOffset > 0x3F)
{
throw new ArgumentException("The vertical scrolling offset is invalid.", nameof(verticalScrollingOffset));
throw new ArgumentOutOfRangeException(nameof(verticalScrollingOffset));
}
ScrollType = scrollType;
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class EntireDisplayOn : ICommand
public class EntireDisplayOn : ISsd1306Command
{
/// <summary>
/// This command turns the entire display on or off.
......
......@@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public enum FrameFrequencyType
{
......@@ -16,7 +16,7 @@ namespace Iot.Device.Ssd1306.Command
Frames256 = 0x03
}
public class HorizontalScrollSetup : ICommand
public class HorizontalScrollSetup : ISsd1306Command
{
/// <summary>
/// This command consists of consecutive bytes to set up the horizontal scroll parameters
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class NoOperation : ICommand
public class NoOperation : ISsd1306Command
{
/// <summary>
/// This command is a no operation command.
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetChargePump : ICommand
public class SetChargePump : ISsd1306Command
{
/// <summary>
/// This command controls the switching capacitor regulator circuit.
......
......@@ -4,9 +4,9 @@
using System;
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetColumnAddress : ICommand
public class SetColumnAddress : ISsd1306Command
{
/// <summary>
/// This triple byte command specifies column start address and end address of the display data RAM.
......@@ -23,12 +23,12 @@ namespace Iot.Device.Ssd1306.Command
{
if (startAddress > 0x7F)
{
throw new ArgumentException("The column start address is invalid.", nameof(startAddress));
throw new ArgumentOutOfRangeException(nameof(startAddress));
}
if (endAddress > 0x7F)
{
throw new ArgumentException("The column end address is invalid.", nameof(endAddress));
throw new ArgumentOutOfRangeException(nameof(endAddress));
}
StartAddress = startAddress;
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetComOutputScanDirection : ICommand
public class SetComOutputScanDirection : ISsd1306Command
{
/// <summary>
/// This command sets the scan direction of the COM output, allowing layout flexibility
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetComPinsHardwareConfiguration : ICommand
public class SetComPinsHardwareConfiguration : ISsd1306Command
{
/// <summary>
/// This command sets the COM signals pin configuration to match the OLED panel hardware layout.
......
......@@ -4,9 +4,9 @@
using System;
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetDisplayClockDivideRatioOscillatorFrequency : ICommand
public class SetDisplayClockDivideRatioOscillatorFrequency : ISsd1306Command
{
/// <summary>
/// This command sets the divide ratio to generate DCLK (Display Clock) from CLK and
......@@ -18,12 +18,12 @@ namespace Iot.Device.Ssd1306.Command
{
if (displayClockDivideRatio > 0x0F)
{
throw new ArgumentException("The display clock divide ratio is invalid.", nameof(displayClockDivideRatio));
throw new ArgumentOutOfRangeException(nameof(displayClockDivideRatio));
}
if (oscillatorFrequency > 0x0F)
{
throw new ArgumentException("The oscillator frequency is invalid.", nameof(oscillatorFrequency));
throw new ArgumentOutOfRangeException(nameof(oscillatorFrequency));
}
DisplayClockDivideRatio = displayClockDivideRatio;
......
......@@ -4,9 +4,9 @@
using System;
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetDisplayOffset : ICommand
public class SetDisplayOffset : ISsd1306Command
{
/// <summary>
/// This command specifies the mapping of the display start line to one of COM0-COM63
......@@ -17,7 +17,7 @@ namespace Iot.Device.Ssd1306.Command
{
if (displayOffset > 0x3F)
{
throw new ArgumentException("The display offset is invalid.", nameof(displayOffset));
throw new ArgumentOutOfRangeException(nameof(displayOffset));
}
DisplayOffset = displayOffset;
......
......@@ -4,9 +4,9 @@
using System;
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetDisplayStartLine : ICommand
public class SetDisplayStartLine : ISsd1306Command
{
/// <summary>
/// This command sets the Display Start Line register to determine starting address of display RAM,
......@@ -18,7 +18,7 @@ namespace Iot.Device.Ssd1306.Command
{
if (displayStartLine > 0x3F)
{
throw new ArgumentException("The display start line is invalid.", nameof(displayStartLine));
throw new ArgumentOutOfRangeException(nameof(displayStartLine));
}
DisplayStartLine = displayStartLine;
......
......@@ -4,9 +4,9 @@
using System;
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetHigherColumnStartAddressForPageAddressingMode : ICommand
public class SetHigherColumnStartAddressForPageAddressingMode : ISsd1306Command
{
/// <summary>
/// This command specifies the higher nibble of the 8-bit column start address for the display
......@@ -18,7 +18,7 @@ namespace Iot.Device.Ssd1306.Command
{
if (higherColumnStartAddress > 0x0F)
{
throw new ArgumentException("The higher column start address is invalid.", nameof(higherColumnStartAddress));
throw new ArgumentOutOfRangeException(nameof(higherColumnStartAddress));
}
HigherColumnStartAddress = higherColumnStartAddress;
......
......@@ -4,9 +4,9 @@
using System;
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetLowerColumnStartAddressForPageAddressingMode : ICommand
public class SetLowerColumnStartAddressForPageAddressingMode : ISsd1306Command
{
/// <summary>
/// This command specifies the lower nibble of the 8-bit column start address for the display
......@@ -18,7 +18,7 @@ namespace Iot.Device.Ssd1306.Command
{
if (lowerColumnStartAddress > 0x0F)
{
throw new ArgumentException("The lower column start address is invalid.", nameof(lowerColumnStartAddress));
throw new ArgumentOutOfRangeException(nameof(lowerColumnStartAddress));
}
LowerColumnStartAddress = lowerColumnStartAddress;
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetMemoryAddressingMode : ICommand
public class SetMemoryAddressingMode : ISsd1306Command
{
/// <summary>
/// This command sets the memory addressing mode.
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetNormalDisplay : ICommand
public class SetNormalDisplay : ISsd1306Command
{
/// <summary>
/// This command sets the display to be normal. Displays a RAM data of 1 indicates an ON pixel.
......
......@@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public enum PageAddress
{
......@@ -16,7 +16,7 @@ namespace Iot.Device.Ssd1306.Command
Page7 = 0x07
}
public class SetPageAddress : ICommand
public class SetPageAddress : ISsd1306Command
{
/// <summary>
/// This triple byte command specifies page start address and end address of the display data RAM.
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetPageStartAddressForPageAddressingMode : ICommand
public class SetPageStartAddressForPageAddressingMode : ISsd1306Command
{
/// <summary>
/// This command positions the page start address from 0 to 7 in GDDRAM under Page Addressing Mode.
......
......@@ -4,9 +4,9 @@
using System;
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetPreChargePeriod : ICommand
public class SetPreChargePeriod : ISsd1306Command
{
/// <summary>
/// This command is used to set the duration of the pre-charge period.
......@@ -16,14 +16,14 @@ namespace Iot.Device.Ssd1306.Command
/// <param name="phase2Period">Phase 2 period with a range of 1-15.</param>
public SetPreChargePeriod(byte phase1Period = 0x02, byte phase2Period = 0x02)
{
if (!Ssd1306.InRange(phase1Period, 0x01, 0x0F))
if (!Ssd13xx.InRange(phase1Period, 0x01, 0x0F))
{
throw new ArgumentException("The phase 1 period is invalid.", nameof(phase1Period));
throw new ArgumentOutOfRangeException(nameof(phase1Period));
}
if (!Ssd1306.InRange(phase2Period, 0x01, 0x0F))
if (!Ssd13xx.InRange(phase2Period, 0x01, 0x0F))
{
throw new ArgumentException("The phase 2 period is invalid.", nameof(phase2Period));
throw new ArgumentOutOfRangeException(nameof(phase2Period));
}
Phase1Period = phase1Period;
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetSegmentReMap : ICommand
public class SetSegmentReMap : ISsd1306Command
{
/// <summary>
/// This command changes the mapping between the display data column address and the segment driver.
......
......@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetVcomhDeselectLevel : ICommand
public class SetVcomhDeselectLevel : ISsd1306Command
{
/// <summary>
/// This command adjusts the VCOMH regulator output.
......
......@@ -4,9 +4,9 @@
using System;
namespace Iot.Device.Ssd1306.Command
namespace Iot.Device.Ssd13xx.Commands.Ssd1306Commands
{
public class SetVerticalScrollArea : ICommand
public class SetVerticalScrollArea : ISsd1306Command
{
/// <summary>
/// This command consists of 3 consecutive bytes to set up the vertical scroll area.
......@@ -19,12 +19,12 @@ namespace Iot.Device.Ssd1306.Command
{
if (topFixedAreaRows > 0x3F)
{
throw new ArgumentException("The top fixed area rows are invalid.", nameof(topFixedAreaRows));
throw new ArgumentOutOfRangeException(nameof(topFixedAreaRows));
}
if (scrollAreaRows > 0x7F)
{
throw new ArgumentException("The scroll area rows are invalid.", nameof(scrollAreaRows));
throw new ArgumentOutOfRangeException(nameof(scrollAreaRows));
}
TopFixedAreaRows = topFixedAreaRows;
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SelectDefaultLinearGrayScaleTable : ISsd1327Command
{
/// <summary>
/// This command reloads the preset linear Gray Scale table.
/// </summary>
public SelectDefaultLinearGrayScaleTable()
{
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xB9;
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetColumnAddress : ISsd1327Command
{
/// <summary>
// Set column address.
// Start from 8th column of driver IC. This is 0th column for OLED.
// End at (8 + 47)th column. Each column has 2 pixels(or segments).
/// </summary>
/// <param name="startAddress">Column start address with a range of 8-55.</param>
/// <param name="endAddress">Column end address with a range of 8-55.</param>
public SetColumnAddress(byte startAddress = 0x08, byte endAddress = 0x37)
{
if (startAddress > 0x37)
{
throw new ArgumentOutOfRangeException(nameof(startAddress));
}
if (endAddress > 0x37)
{
throw new ArgumentOutOfRangeException(nameof(endAddress));
}
StartAddress = startAddress;
EndAddress = endAddress;
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0x15;
/// <summary>
/// Column start address.
/// </summary>
public byte StartAddress { get; set; }
/// <summary>
/// Column end address.
/// </summary>
public byte EndAddress { get; set; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, StartAddress, EndAddress };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetComDeselectVoltageLevel : ISsd1327Command
{
/// <summary>
/// This command sets the high voltage level of common pins, Vcomh.
/// </summary>
/// <param name="level">COM deselect voltage level.</param>
public SetComDeselectVoltageLevel(byte level = 0x05)
{
if (level > 0x07)
{
throw new ArgumentOutOfRangeException(nameof(level));
}
Level = level;
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xBE;
/// <summary>
/// COM deselect voltage level.
/// </summary>
public byte Level { get; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, Level };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetDisplayClockDivideRatioOscillatorFrequency : ISsd1327Command
{
/// <summary>
/// This command sets the divide ratio to generate DCLK (Display Clock) from CLK and
/// programs the oscillator frequency Fosc that is the source of CLK if CLS pin is pulled high.
/// </summary>
/// <param name="displayClockDivideRatio">Display clock divide ratio with a range of 0-15. For more information see device documentations.</param>
/// <param name="oscillatorFrequency">Oscillator frequency with a range of 0-15 in Kilohertz. For more information see device documentations.</param>
public SetDisplayClockDivideRatioOscillatorFrequency(byte displayClockDivideRatio = 0x00, byte oscillatorFrequency = 0x00)
{
if (displayClockDivideRatio > 0x0F)
{
throw new ArgumentOutOfRangeException(nameof(displayClockDivideRatio));
}
if (oscillatorFrequency > 0x0F)
{
throw new ArgumentOutOfRangeException(nameof(oscillatorFrequency));
}
DisplayClockDivideRatio = displayClockDivideRatio;
OscillatorFrequency = oscillatorFrequency;
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xB3;
/// <summary>
/// Display clock divide ratio with a range of 0-15.
/// </summary>
public byte DisplayClockDivideRatio { get; }
/// <summary>
/// Oscillator frequency with a range of 0-15.
/// </summary>
public byte OscillatorFrequency { get; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
byte displayClockDivideRatioOscillatorFrequency = (byte)((OscillatorFrequency << 4) | DisplayClockDivideRatio);
return new byte[] { Id, displayClockDivideRatioOscillatorFrequency };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetDisplayOffset : ISsd1327Command
{
/// <summary>
/// This command specifies the mapping of the display start line to one of COM0-COM127
/// (assuming that COM0 is the display start line then the display start line register is equal to 0).
/// </summary>
/// <param name="displayOffset">Display offset with a range of 0-127.</param>
public SetDisplayOffset(byte displayOffset = 0x00)
{
if (displayOffset > 0x5F)
{
throw new ArgumentOutOfRangeException(nameof(displayOffset));
}
DisplayOffset = displayOffset;
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xA2;
/// <summary>
/// Display offset with a range of 0-127.
/// </summary>
public byte DisplayOffset { get; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, DisplayOffset };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetDisplayStartLine : ISsd1327Command
{
/// <summary>
/// This command sets the Display Start Line register to determine starting address of display RAM,
/// by selecting a value from 0 to 127. With value equal to 0, RAM row 0 is mapped to COM0.
/// With value equal to 1, RAM row 1 is mapped to COM0 and so on.
/// </summary>
/// <param name="displayStartLine">Display start line with a range of 0-63.</param>
public SetDisplayStartLine(byte displayStartLine = 0x00)
{
if (displayStartLine > 0x7F)
{
throw new ArgumentOutOfRangeException(nameof(displayStartLine));
}
DisplayStartLine = displayStartLine;
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xA1;
/// <summary>
/// Display start line with a range of 0-127.
/// </summary>
public byte DisplayStartLine { get; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, DisplayStartLine };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetInternalVddRegulator : ISsd1327Command
{
/// <summary>
/// This command is used to enable internal Vdd regulator.
/// </summary>
/// <param name="enable">Represents if internal Vdd have to be enabled.</param>
public SetInternalVddRegulator(bool enable)
{
UseInternalVdd = (byte)(enable ? 0b_0000_0001 : 0b_0000_0000);
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xAB;
/// <summary>
/// The value that represent if internal or external Vdd should be used.
/// </summary>
public byte UseInternalVdd { get; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, UseInternalVdd };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetNormalDisplay : ISsd1327Command
{
/// <summary>
/// This command sets the display to be normal.
/// </summary>
public SetNormalDisplay()
{
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xA4;
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetPhaseLength : ISsd1327Command
{
/// <summary>
/// This command sets the length of phase 1 and 2 of segment waveform of the driver.
/// </summary>
public SetPhaseLength(byte phase1Period = 0x02, byte phase2Period = 0x02)
{
CheckPeriods(phase1Period, phase2Period);
Phase1Period = phase1Period;
Phase2Period = phase2Period;
PhasePeriod = (byte)((Phase2Period << 4) | Phase1Period);
}
public SetPhaseLength(byte phasePeriod)
{
byte phase1Period = (byte)(phasePeriod & 0x0F);
byte phase2Period = (byte)((phasePeriod & 0xF0) >> 4);
CheckPeriods(phase1Period, phase2Period);
Phase1Period = phase1Period;
Phase2Period = phase2Period;
PhasePeriod = phasePeriod;
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xB1;
/// <summary>
/// Phase 1 period with a range of 1-15.
/// </summary>
public byte Phase1Period { get; }
/// <summary>
/// Phase 2 period with a range of 1-15.
/// </summary>
public byte Phase2Period { get; }
/// <summary>
/// Phase period.
/// </summary>
public byte PhasePeriod { get; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, PhasePeriod };
}
private void CheckPeriods(byte phase1Period, byte phase2Period)
{
if (!Ssd13xx.InRange(phase1Period, 0x01, 0x0F))
{
throw new ArgumentOutOfRangeException(nameof(phase1Period));
}
if (!Ssd13xx.InRange(phase2Period, 0x01, 0x0F))
{
throw new ArgumentOutOfRangeException(nameof(phase2Period));
}
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetPreChargeVoltage : ISsd1327Command
{
/// <summary>
/// This command sets the first pre-charge voltage (phase 2) level of segment pins.
/// </summary>
/// <param name="level">
/// Pre-charge voltage level.
/// Parameter values between 0b_0000 and 0b_0111 leads to voltage values between 0.2 x Vcc and 0.613 x Vcc Volts.
/// Parameter value 0b_1XXX leads to voltage value equals to Vcomh.
/// </param>
public SetPreChargeVoltage(byte level = 0x05)
{
if (level > 0x08)
{
throw new ArgumentOutOfRangeException(nameof(level));
}
Level = level;
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xBC;
/// <summary>
/// Pre-charge voltage level.
/// </summary>
public byte Level { get; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, Level };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetReMap : ISsd1327Command
{
/// <summary>
/// Re-map setting in Graphic Display Data RAM(GDDRAM)
/// </summary>
public SetReMap(
bool columnAddressRemap = false,
bool nibbleRemap = true,
bool verticalMode = true,
bool comRemap = false,
bool comSplitOddEven = true)
{
config = 0b_0000_0000;
if (columnAddressRemap)
{
config |= 0b_0000_0001;
}
if (nibbleRemap)
{
config |= 0b_0000_0010;
}
if (verticalMode)
{
config |= 0b_0000_0100;
}
if (comRemap)
{
config |= 0b_0001_0000;
}
if (comSplitOddEven)
{
config |= 0b_0100_0000;
}
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xA0;
// <summary>
/// ReMap config.
/// </summary>
public byte config { get; set; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, config };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetRowAddress : ISsd1327Command
{
/// <summary>
// Set row address
/// </summary>
/// <param name="startAddress">Column start address with a range of 0-95.</param>
/// <param name="endAddress">Column end address with a range of 0-95.</param>
public SetRowAddress(byte startAddress = 0x00, byte endAddress = 0x5f)
{
if (startAddress > 0x5f)
{
throw new ArgumentOutOfRangeException(nameof(startAddress));
}
if (endAddress > 0x5f)
{
throw new ArgumentOutOfRangeException(nameof(endAddress));
}
StartAddress = startAddress;
EndAddress = endAddress;
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0x75;
/// <summary>
/// Row start address.
/// </summary>
public byte StartAddress { get; set; }
/// <summary>
/// Row end address.
/// </summary>
public byte EndAddress { get; set; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, StartAddress, EndAddress };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetSecondPreChargePeriod : ISsd1327Command
{
/// <summary>
/// This command is used to set the phase 3 second pre-charge period.
/// </summary>
/// <param name="period">Second pre-charge period.</param>
public SetSecondPreChargePeriod(byte period = 0x04)
{
if (period > 0x0F)
{
throw new ArgumentOutOfRangeException(nameof(period));
}
Period = period;
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xB6;
/// <summary>
/// Second Pre-charge period.
/// </summary>
public byte Period { get; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, Period };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetSecondPreChargeVsl : ISsd1327Command
{
/// <summary>
/// This command sets the first pre-charge voltage (phase 2) level of segment pins.
/// </summary>
/// <param name="secondPrecharge">Enable/disable second precharge.</param>
/// <param name="externalVsl"> Switch between internal and external VSL.</param>
public SetSecondPreChargeVsl(bool secondPrecharge = false, bool externalVsl = false)
{
Config = (byte)(secondPrecharge ? 0b_0110_0010 : 0b_0110_0000);
Config |= (byte)(externalVsl ? 0b_0110_0001 : 0b_0110_0000);
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xD5;
public byte Config { get; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, Config };
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Iot.Device.Ssd13xx.Commands.Ssd1327Commands
{
public class SetUnlockDriver : ISsd1327Command
{
/// <summary>
/// This command sets the display to be normal.
/// </summary>
/// <param name="unlock">Represents if driver have to be unlocked.</param>
public SetUnlockDriver(bool unlock)
{
SetUnlock = (byte)(unlock ? 0b_0001_0010 : 0b_0001_0110);
}
/// <summary>
/// The value that represents the command.
/// </summary>
public byte Id => 0xFD;
/// <summary>
/// The value that represents if driver should be unlocked.
/// </summary>
byte SetUnlock { get; }
/// <summary>
/// Gets the bytes that represent the command.
/// </summary>
/// <returns>The bytes that represent the command.</returns>
public byte[] GetBytes()
{
return new byte[] { Id, SetUnlock };
}
}
}
......@@ -6,6 +6,8 @@ The SSD1306 is a single-chip CMOS OLED/PLED driver with controller for organic/p
## Device Family
**SSD1306**: https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf
**SSD1327**: [SSD1327 datasheet pdf](https://github.com/SeeedDocument/Grove_OLED_1.12/raw/master/resources/SSD1327_datasheet.pdf)
### Related Devices
- [Adafruit PiOLED - 128x32 Monochrome OLED Add-on for Raspberry Pi](https://www.adafruit.com/product/3527)
- [SunFounder 0.96" Inch Blue I2C IIC Serial 128x64 OLED LCD LED SSD1306 Modul](https://www.amazon.com/SunFounder-SSD1306-Arduino-Raspberry-Display/dp/B014KUB1SA)
......
......@@ -2,20 +2,18 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using System;
using System.Device.I2c;
namespace Iot.Device.Ssd1306
namespace Iot.Device.Ssd13xx
{
/// <summary>
/// A single-chip CMOS OLED/PLED driver with controller for organic/polymer
/// light emitting diode dot-matrix graphic display system.
/// </summary>
public class Ssd1306 : IDisposable
public class Ssd1306 : Ssd13xx
{
private I2cDevice _i2cDevice;
/// <summary>
/// Initializes new instance of Ssd1306 device that will communicate using I2C bus.
/// A single-chip CMOS OLED/PLED driver with controller for organic/polymer
......@@ -23,29 +21,26 @@ namespace Iot.Device.Ssd1306
/// </summary>
/// <param name="i2cDevice">>The I2C device used for communication.</param>
public Ssd1306(I2cDevice i2cDevice)
: base(i2cDevice)
{
_i2cDevice = i2cDevice;
}
/// <summary>
/// Verifies value is within a specific range.
/// </summary>
/// <param name="value">Value to check.</param>
/// <param name="start">Starting value of range.</param>
/// <param name="end">Ending value of range.</param>
/// <returns>Determines if value is within range.</returns>
internal static bool InRange(uint value, uint start, uint end)
public void SendCommand(ISsd1306Command command)
{
SendCommand((ICommand)command);
}
public override void SendCommand(ISharedCommand command)
{
return (value - start) <= (end - start);
SendCommand(command);
}
/// <summary>
/// Send a command to the display controller.
/// </summary>
/// <param name="command">The command to send to the display controller.</param>
public void SendCommand(ICommand command)
private void SendCommand(ICommand command)
{
const int StackThreshold = 32;
byte[] commandBytes = command.GetBytes();
if (commandBytes == null)
......@@ -58,9 +53,7 @@ namespace Iot.Device.Ssd1306
throw new ArgumentException("The command did not contain any bytes to send.");
}
Span<byte> writeBuffer = commandBytes.Length < StackThreshold ?
stackalloc byte[commandBytes.Length + 1] :
new byte[commandBytes.Length + 1];
Span<byte> writeBuffer = SliceGenericBuffer(commandBytes.Length + 1);
commandBytes.CopyTo(writeBuffer.Slice(1));
......@@ -70,33 +63,5 @@ namespace Iot.Device.Ssd1306
_i2cDevice.Write(writeBuffer);
}
/// <summary>
/// Send data to the display controller.
/// </summary>
/// <param name="data">The data to send to the display controller.</param>
public void SendData(byte[] data)
{
const int StackThreshold = 512;
if (data == null)
{
throw new ArgumentNullException(nameof(data));
}
Span<byte> writeBuffer = data.Length < StackThreshold ?
stackalloc byte[data.Length + 1] :
new byte[data.Length + 1];
writeBuffer[0] = 0x40; // Control byte.
data.CopyTo(writeBuffer.Slice(1));
_i2cDevice.Write(writeBuffer);
}
public void Dispose()
{
_i2cDevice?.Dispose();
_i2cDevice = null;
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd13xx.Commands;
using Ssd1327Cmnds = Iot.Device.Ssd13xx.Commands.Ssd1327Commands;
using System;
using System.Device.I2c;
namespace Iot.Device.Ssd13xx
{
public class Ssd1327 : Ssd13xx
{
private const byte Command_Mode = 0x80;
private const byte Data_Mode = 0x40;
private const int CleaningBufferSize = 48 * 96;
/// <summary>
/// Initializes new instance of Ssd1327 device that will communicate using I2C bus.
/// </summary>
/// <param name="i2cDevice">>The I2C device used for communication.</param>
public Ssd1327(I2cDevice i2cDevice)
: base(i2cDevice)
{
}
public void SetColumnAddress(byte startAddress = 0x08, byte endAddress = 0x37)
{
SendCommand(new Ssd1327Cmnds.SetColumnAddress(startAddress, endAddress));
}
public void SetRowAddress(byte startAddress = 0x00, byte endAddress = 0x5f)
{
SendCommand(new Ssd1327Cmnds.SetRowAddress(startAddress, endAddress));
}
public void ClearDisplay()
{
SendCommand(new SetDisplayOff());
SetColumnAddress();
SetRowAddress();
byte[] data = new byte[CleaningBufferSize];
SendData(data);
SendCommand(new SetDisplayOn());
}
/// <summary>
/// Send a command to the display controller.
/// </summary>
/// <param name="command">The command to send to the display controller.</param>
public void SendCommand(byte command)
{
Span<byte> writeBuffer = new byte[] { Command_Mode, command };
_i2cDevice.Write(writeBuffer);
}
public void SendCommand(ISsd1327Command command)
{
SendCommand((ICommand)command);
}
public override void SendCommand(ISharedCommand command)
{
SendCommand(command);
}
/// <summary>
/// Send data to the display controller.
/// </summary>
/// <param name="data">The data to send to the display controller.</param>
public void SendData(byte data)
{
Span<byte> writeBuffer = new byte[] { Data_Mode, data };
_i2cDevice.Write(writeBuffer);
}
private void SendCommand(ICommand command)
{
byte[] commandBytes = command.GetBytes();
if (commandBytes == null)
{
throw new ArgumentNullException(nameof(commandBytes));
}
if (commandBytes.Length == 0)
{
throw new ArgumentException("The command did not contain any bytes to send.");
}
foreach (var item in commandBytes)
{
SendCommand(item);
}
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd13xx.Commands;
using System;
using System.Device.I2c;
namespace Iot.Device.Ssd13xx
{
public abstract class Ssd13xx : IDisposable
{
// Multiply of screen resolution plus single command byte.
private const int DefaultBufferSize = 48 * 96 + 1;
private byte[] _genericBuffer;
protected I2cDevice _i2cDevice;
public Ssd13xx(I2cDevice i2cDevice, int bufferSize = DefaultBufferSize)
{
_genericBuffer = new byte[bufferSize];
_i2cDevice = i2cDevice;
}
/// <summary>
/// Verifies value is within a specific range.
/// </summary>
/// <param name="value">Value to check.</param>
/// <param name="start">Starting value of range.</param>
/// <param name="end">Ending value of range.</param>
/// <returns>Determines if value is within range.</returns>
internal static bool InRange(uint value, uint start, uint end)
{
return (value - start) <= (end - start);
}
/// <summary>
/// Send a command to the display controller.
/// </summary>
/// <param name="command">The command to send to the display controller.</param>
public abstract void SendCommand(ISharedCommand command);
/// <summary>
/// Send data to the display controller.
/// </summary>
/// <param name="data">The data to send to the display controller.</param>
public virtual void SendData(byte[] data)
{
if (data == null)
{
throw new ArgumentNullException(nameof(data));
}
Span<byte> writeBuffer = SliceGenericBuffer(data.Length + 1);
writeBuffer[0] = 0x40; // Control byte.
data.CopyTo(writeBuffer.Slice(1));
_i2cDevice.Write(writeBuffer);
}
public void Dispose()
{
_i2cDevice?.Dispose();
_i2cDevice = null;
}
protected Span<byte> SliceGenericBuffer(int length)
{
return SliceGenericBuffer(0, length);
}
protected Span<byte> SliceGenericBuffer(int start, int length)
{
if (_genericBuffer.Length < length)
{
var newBuffer = new byte[_genericBuffer.Length * 2];
_genericBuffer.CopyTo(newBuffer, 0);
_genericBuffer = newBuffer;
}
return _genericBuffer.AsSpan(start, length);
}
}
}
......@@ -7,8 +7,10 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="Command\*.cs" />
<Compile Include="Ssd1306.cs" />
<Compile Include="Commands\*.cs" />
<Compile Include="Commands\Ssd1327Commands\*.cs" />
<Compile Include="Commands\Ssd1306Commands\*.cs" />
<Compile Include="*.cs" />
</ItemGroup>
<ItemGroup>
......
......@@ -4,7 +4,7 @@
using System.Collections.Generic;
namespace Iot.Device.Ssd1306.Samples
namespace Iot.Device.Ssd13xx.Samples
{
// NOTE: As mentioned in GitHub issue #189 (Need OLED Graphics API).
// https://github.com/dotnet/iot/issues/189
......
......@@ -2,7 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Ssd1306Cmnds = Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using Ssd1327Cmnds = Iot.Device.Ssd13xx.Commands.Ssd1327Commands;
using System;
using System.Collections.Generic;
using System.Device.I2c;
......@@ -18,7 +20,7 @@ using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
namespace Iot.Device.Ssd1306.Samples
namespace Iot.Device.Ssd13xx.Samples
{
static class Program
{
......@@ -26,85 +28,161 @@ namespace Iot.Device.Ssd1306.Samples
{
Console.WriteLine("Hello Ssd1306 Sample!");
using (Ssd1306 ssd1306 = GetSsd1306WithI2c())
#if SSD1327
using (Ssd1327 device = GetSsd1327WithI2c())
{
InitializeSsd1306(ssd1306);
ClearScreen(ssd1306);
//SendMessage(ssd1306, "Hello .NET IoT!!!");
//DisplayIpAddress(ssd1306);
DisplayImages(ssd1306);
DisplayClock(ssd1306);
ClearScreen(ssd1306);
Initialize(device);
ClearScreen(device);
//SendMessage(device, "Hello .NET IoT!");
SendMessage(device, DisplayIpAddress());
}
#else
using (Ssd1306 device = GetSsd1306WithI2c())
{
Initialize(device);
ClearScreen(device);
//SendMessage(device, "Hello .NET IoT!!!");
//SendMessage(device, DisplayIpAddress());
DisplayImages(device);
DisplayClock(device);
ClearScreen(device);
}
#endif
}
private static Ssd1306 GetSsd1306WithI2c()
{
private static UnixI2cDevice GetI2CDevice(){
Console.WriteLine("Using I2C protocol");
var connectionSettings = new I2cConnectionSettings(1, 0x3C);
var i2cDevice = new UnixI2cDevice(connectionSettings);
var ssd1306 = new Ssd1306(i2cDevice);
return ssd1306;
return new UnixI2cDevice(connectionSettings);
}
private static Ssd1327 GetSsd1327WithI2c()
{
return new Ssd1327(GetI2CDevice());
}
private static Ssd1306 GetSsd1306WithI2c()
{
return new Ssd1306(GetI2CDevice());
}
// Display size 128x32.
private static void InitializeSsd1306(Ssd1306 ssd1306)
private static void Initialize(Ssd1306 device)
{
device.SendCommand(new SetDisplayOff());
device.SendCommand(new Ssd1306Cmnds.SetDisplayClockDivideRatioOscillatorFrequency(0x00, 0x08));
device.SendCommand(new SetMultiplexRatio(0x1F));
device.SendCommand(new Ssd1306Cmnds.SetDisplayOffset(0x00));
device.SendCommand(new Ssd1306Cmnds.SetDisplayStartLine(0x00));
device.SendCommand(new Ssd1306Cmnds.SetChargePump(true));
device.SendCommand(new Ssd1306Cmnds.SetMemoryAddressingMode(Ssd1306Cmnds.SetMemoryAddressingMode.AddressingMode.Horizontal));
device.SendCommand(new Ssd1306Cmnds.SetSegmentReMap(true));
device.SendCommand(new Ssd1306Cmnds.SetComOutputScanDirection(false));
device.SendCommand(new Ssd1306Cmnds.SetComPinsHardwareConfiguration(false, false));
device.SendCommand(new SetContrastControlForBank0(0x8F));
device.SendCommand(new Ssd1306Cmnds.SetPreChargePeriod(0x01, 0x0F));
device.SendCommand(new Ssd1306Cmnds.SetVcomhDeselectLevel(Ssd1306Cmnds.SetVcomhDeselectLevel.DeselectLevel.Vcc1_00));
device.SendCommand(new Ssd1306Cmnds.EntireDisplayOn(false));
device.SendCommand(new Ssd1306Cmnds.SetNormalDisplay());
device.SendCommand(new SetDisplayOn());
device.SendCommand(new Ssd1306Cmnds.SetColumnAddress());
device.SendCommand(new Ssd1306Cmnds.SetPageAddress(Ssd1306Cmnds.PageAddress.Page1, Ssd1306Cmnds.PageAddress.Page3));
}
// Display size 96x96.
private static void Initialize(Ssd1327 device)
{
ssd1306.SendCommand(new SetDisplayOff());
ssd1306.SendCommand(new SetDisplayClockDivideRatioOscillatorFrequency(0x00, 0x08));
ssd1306.SendCommand(new SetMultiplexRatio(0x1F));
ssd1306.SendCommand(new SetDisplayOffset(0x00));
ssd1306.SendCommand(new SetDisplayStartLine(0x00));
ssd1306.SendCommand(new SetChargePump(true));
ssd1306.SendCommand(new SetMemoryAddressingMode(SetMemoryAddressingMode.AddressingMode.Horizontal));
ssd1306.SendCommand(new SetSegmentReMap(true));
ssd1306.SendCommand(new SetComOutputScanDirection(false));
ssd1306.SendCommand(new SetComPinsHardwareConfiguration(false, false));
ssd1306.SendCommand(new SetContrastControlForBank0(0x8F));
ssd1306.SendCommand(new SetPreChargePeriod(0x01, 0x0F));
ssd1306.SendCommand(new SetVcomhDeselectLevel(SetVcomhDeselectLevel.DeselectLevel.Vcc1_00));
ssd1306.SendCommand(new EntireDisplayOn(false));
ssd1306.SendCommand(new SetNormalDisplay());
ssd1306.SendCommand(new SetDisplayOn());
ssd1306.SendCommand(new SetColumnAddress());
ssd1306.SendCommand(new SetPageAddress(PageAddress.Page1, PageAddress.Page3));
device.SendCommand(new Ssd1327Cmnds.SetUnlockDriver(true));
device.SendCommand(new SetDisplayOff());
device.SendCommand(new SetMultiplexRatio(0x5F));
device.SendCommand(new Ssd1327Cmnds.SetDisplayStartLine());
device.SendCommand(new Ssd1327Cmnds.SetDisplayOffset(0x5F));
device.SendCommand(new Ssd1327Cmnds.SetReMap());
device.SendCommand(new Ssd1327Cmnds.SetInternalVddRegulator(true));
device.SendCommand(new SetContrastControlForBank0(0x53));
device.SendCommand(new Ssd1327Cmnds.SetPhaseLength(0X51));
device.SendCommand(new Ssd1327Cmnds.SetDisplayClockDivideRatioOscillatorFrequency(0x01, 0x00));
device.SendCommand(new Ssd1327Cmnds.SelectDefaultLinearGrayScaleTable());
device.SendCommand(new Ssd1327Cmnds.SetPreChargeVoltage(0x08));
device.SendCommand(new Ssd1327Cmnds.SetComDeselectVoltageLevel(0X07));
device.SendCommand(new Ssd1327Cmnds.SetSecondPreChargePeriod(0x01));
device.SendCommand(new Ssd1327Cmnds.SetSecondPreChargeVsl(true));
device.SendCommand(new Ssd1327Cmnds.SetNormalDisplay());
device.SendCommand(new DeactivateScroll());
device.SendCommand(new SetDisplayOn());
device.SendCommand(new Ssd1327Cmnds.SetRowAddress());
device.SendCommand(new Ssd1327Cmnds.SetColumnAddress());
}
private static void ClearScreen(Ssd1306 ssd1306)
private static void ClearScreen(Ssd1306 device)
{
ssd1306.SendCommand(new SetColumnAddress());
ssd1306.SendCommand(new SetPageAddress(PageAddress.Page0, PageAddress.Page3));
device.SendCommand(new Ssd1306Cmnds.SetColumnAddress());
device.SendCommand(new Ssd1306Cmnds.SetPageAddress(Ssd1306Cmnds.PageAddress.Page0, Ssd1306Cmnds.PageAddress.Page3));
for (int cnt = 0; cnt < 32; cnt++)
{
byte[] data = new byte[16];
ssd1306.SendData(data);
device.SendData(data);
}
}
private static void SendMessage(Ssd1306 ssd1306, string message)
private static void ClearScreen(Ssd1327 device)
{
ssd1306.SendCommand(new SetColumnAddress());
ssd1306.SendCommand(new SetPageAddress(PageAddress.Page0, PageAddress.Page3));
device.ClearDisplay();
}
private static void SendMessage(Ssd1306 device, string message)
{
device.SendCommand(new Ssd1306Cmnds.SetColumnAddress());
device.SendCommand(new Ssd1306Cmnds.SetPageAddress(Ssd1306Cmnds.PageAddress.Page0, Ssd1306Cmnds.PageAddress.Page3));
foreach (char character in message)
{
ssd1306.SendData(BasicFont.GetCharacterBytes(character));
device.SendData(BasicFont.GetCharacterBytes(character));
}
}
private static void DisplayIpAddress(Ssd1306 ssd1306)
private static void SendMessage(Ssd1327 device, string message)
{
device.SetRowAddress(0x00, 0x07);
foreach (char character in message)
{
byte[] charBitMap = BasicFont.GetCharacterBytes(character);
List<byte> data = new List<byte>();
for(var i = 0; i < charBitMap.Length; i = i + 2)
{
for(var j = 0; j < 8; j++)
{
byte cdata = 0x00;
int bit1 = (byte)((charBitMap[i] >> j) & 0x01);
cdata |= (bit1 == 1) ? (byte)0xF0 : (byte)0x00;
var secondBitIndex = i + 1;
if (secondBitIndex < charBitMap.Length) {
int bit2 = (byte)((charBitMap[i + 1] >> j) & 0x01);
cdata |= (bit2 == 1) ? (byte)0x0F : (byte)0x00;
}
data.Add(cdata);
}
}
device.SendData(data.ToArray());
}
}
private static string DisplayIpAddress()
{
string ipAddress = GetIpAddress();
if (ipAddress != null)
{
SendMessage(ssd1306, $"IP: {ipAddress}");
return $"IP:{ipAddress}";
}
else
{
SendMessage(ssd1306, $"Error: IP Address Not Found");
return $"Error: IP Address Not Found";
}
}
......@@ -214,6 +292,5 @@ namespace Iot.Device.Ssd1306.Samples
s.SendData(buffer.Skip(i).Take(chunk_size).ToArray());
}
}
}
}
......@@ -14,7 +14,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\Ssd1306.csproj" />
<ProjectReference Include="../Ssd13xx.csproj" />
</ItemGroup>
<ItemGroup>
......@@ -23,4 +23,4 @@
</None>
</ItemGroup>
</Project>
\ No newline at end of file
</Project>
......@@ -2,10 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class ActivateScrollTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using Xunit;
using static Iot.Device.Ssd1306.Command.ContinuousVerticalAndHorizontalScrollSetup;
using static Iot.Device.Ssd13xx.Commands.Ssd1306Commands.ContinuousVerticalAndHorizontalScrollSetup;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class ContinuousVerticalAndHorizontalScrollSetupTests
{
......
......@@ -2,10 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class DeactivateScrollTests
{
......
......@@ -2,10 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class EntireDisplayOnTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using Xunit;
using static Iot.Device.Ssd1306.Command.HorizontalScrollSetup;
using static Iot.Device.Ssd13xx.Commands.Ssd1306Commands.HorizontalScrollSetup;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class HorizontalScrollSetupTests
{
......
......@@ -2,10 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class NoOperationTests
{
......
......@@ -2,10 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetChargePumpTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using System;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetColumnAddressTests
{
......
......@@ -2,10 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetComOutputScanDirectionTests
{
......
......@@ -2,10 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetComPinsHardwareConfigurationTests
{
......
......@@ -2,10 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetContrastControlForBank0Tests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using System;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetDisplayClockDivideRatioOscillatorFrequencyTests
{
......
......@@ -2,10 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetDisplayOffTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using System;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetDisplayOffsetTests
{
......
......@@ -2,10 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetDisplayOnTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using System;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetDisplayStartLineTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using System;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetHigherColumnStartAddressForPageAddressingModeTests
{
......
......@@ -2,10 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetInverseDisplayTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using System;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetLowerColumnStartAddressForPageAddressingModeTests
{
......
......@@ -2,12 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using System;
using Xunit;
using static Iot.Device.Ssd1306.Command.SetMemoryAddressingMode;
using static Iot.Device.Ssd13xx.Commands.Ssd1306Commands.SetMemoryAddressingMode;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetMemoryAddressingModeTests
{
......
......@@ -2,11 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using System;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetMultiplexRatioTests
{
......
......@@ -2,10 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetNormalDisplayTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using System;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetPageAddressTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using System;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetPageStartAddressForPageAddressingModeTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using System;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetPreChargePeriodTests
{
......
......@@ -2,10 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetSegmentReMapTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using Xunit;
using static Iot.Device.Ssd1306.Command.SetVcomhDeselectLevel;
using static Iot.Device.Ssd13xx.Commands.Ssd1306Commands.SetVcomhDeselectLevel;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetVcomhDeselectLevelTests
{
......
......@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Iot.Device.Ssd1306.Command;
using Iot.Device.Ssd13xx.Commands;
using Iot.Device.Ssd13xx.Commands.Ssd1306Commands;
using System;
using Xunit;
namespace Iot.Device.Mcp23xxx.Tests
namespace Iot.Device.Ssd13xx.Tests
{
public class SetVerticalScrollAreaTests
{
......
......@@ -13,7 +13,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ssd1306.csproj" />
<ProjectReference Include="..\Ssd13xx.csproj" />
</ItemGroup>
</Project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册