Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update SH1106 to SH110x and add SH1107 display driver #602

Merged
merged 3 commits into from
Apr 10, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,455 changes: 3,455 additions & 0 deletions Meadow.Foundation.sln

Large diffs are not rendered by default.

30 changes: 21 additions & 9 deletions Source/Meadow.Foundation.Core/Communications/I2cPeripheral.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Meadow.Hardware
{
Expand All @@ -10,7 +8,14 @@ namespace Meadow.Hardware
/// </summary>
public class I2cPeripheral : II2cPeripheral
{
/// <summary>
/// The I2C address
/// </summary>
public byte Address { get; protected set; }

/// <summary>
/// The I2C bus
/// </summary>
public II2cBus Bus { get; protected set; }

/// <summary>
Expand Down Expand Up @@ -77,9 +82,12 @@ public ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.Lit
{
WriteBuffer.Span[0] = address;
Bus.Exchange(this.Address, WriteBuffer[0..1].Span, ReadBuffer[0..2].Span);
if (order == ByteOrder.LittleEndian) {
if (order == ByteOrder.LittleEndian)
{
return (ushort)(ReadBuffer.Span[0] | (ReadBuffer.Span[1] << 8));
} else {
}
else
{
return (ushort)(ReadBuffer.Span[0] << 8 | ReadBuffer.Span[1]);
}
}
Expand Down Expand Up @@ -167,7 +175,8 @@ public void WriteRegister(byte address, ulong value, ByteOrder order = ByteOrder
/// <param name="order">Indicate if the data should be written as big or little endian.</param>
public void WriteRegister(byte address, Span<byte> writeBuffer, ByteOrder order = ByteOrder.LittleEndian)
{
if (WriteBuffer.Length < writeBuffer.Length + 1) {
if (WriteBuffer.Length < writeBuffer.Length + 1)
{
throw new ArgumentException("Data to write is too large for the write buffer. " +
"Must be less than WriteBuffer.Length + 1 (to allow for address). " +
"Instantiate this class with a larger WriteBuffer, or send a smaller" +
Expand All @@ -179,21 +188,24 @@ public void WriteRegister(byte address, Span<byte> writeBuffer, ByteOrder order

// stuff the bytes into the write buffer (starting at `1` index,
// because `0` is the register address.
switch (order) {
switch (order)
{
case ByteOrder.LittleEndian:
for (int i = 0; i < writeBuffer.Length; i++) {
for (int i = 0; i < writeBuffer.Length; i++)
{
WriteBuffer.Span[i + 1] = writeBuffer[i];
}
break;
case ByteOrder.BigEndian:
for (int i = 0; i < writeBuffer.Length; i++) {
for (int i = 0; i < writeBuffer.Length; i++)
{
// stuff them backwards
WriteBuffer.Span[i + 1] = writeBuffer[writeBuffer.Length - (i + 1)];
}
break;
}
// write it
this.Bus.Write(this.Address, WriteBuffer.Span[0..(writeBuffer.Length + 1)]);
this.Bus.Write(Address, WriteBuffer.Span[0..(writeBuffer.Length + 1)]);
}

public void Exchange(Span<byte> writeBuffer, Span<byte> readBuffer, DuplexType duplex = DuplexType.Half)
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<Project Sdk="Meadow.Sdk/1.1.0">
<Project Sdk="Meadow.Sdk/1.1.0">
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageIcon>icon.png</PackageIcon>
<Authors>Wilderness Labs, Inc</Authors>
<TargetFramework>netstandard2.1</TargetFramework>
<OutputType>Library</OutputType>
<AssemblyName>Sh1106</AssemblyName>
<AssemblyName>Sh110x</AssemblyName>
<Company>Wilderness Labs, Inc</Company>
<PackageProjectUrl>http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/</PackageProjectUrl>
<PackageId>Meadow.Foundation.Displays.Sh1106</PackageId>
<RepositoryUrl>https://github.com/WildernessLabs/Meadow.Foundation</RepositoryUrl>
<PackageTags>Meadow, Meadow.Foundation, Displays, LCD, Sh1106</PackageTags>
<PackageTags>Meadow,Meadow.Foundation,Displays,LCD,Sh1106,SH1107,oled,monochrome</PackageTags>
<Version>0.1.0</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>Sh1106 SPI monochrome OLED display</Description>
<Description>S1106 and SH1107 SPI and I2C monochrome OLED displays</Description>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\..\icon.png" Pack="true" PackagePath="" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using Meadow.Hardware;
using System.Threading;

namespace Meadow.Foundation.Displays
{
/// <summary>
/// Represents the Sh1106 family of displays
/// </summary>
public class Sh1106 : Sh110x
{
/// <summary>
/// Create a new Sh1106 object
/// </summary>
/// <param name="i2cBus">I2C bus connected to display</param>
/// <param name="address">I2C address</param>
/// <param name="width">Display width in pixels</param>
/// <param name="height">Display height in pixels</param>
public Sh1106(II2cBus i2cBus, byte address, int width, int height)
: base(i2cBus, address, width, height)
{ }

/// <summary>
/// Create a new Sh1106 object
/// </summary>
/// <param name="spiBus">SPI bus connected to display</param>
/// <param name="chipSelectPin">Chip select pin</param>
/// <param name="dcPin">Data command pin</param>
/// <param name="resetPin">Reset pin</param>
/// <param name="width">Display width in pixels</param>
/// <param name="height">Display height in pixels</param>
public Sh1106(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin, int width = 128, int height = 64)
: base(spiBus, chipSelectPin, dcPin, resetPin, width, height)
{ }

/// <summary>
/// Create a new Sh1106 display object
/// </summary>
/// <param name="spiBus">SPI bus connected to display</param>
/// <param name="chipSelectPort">Chip select output port</param>
/// <param name="dataCommandPort">Data command output port</param>
/// <param name="resetPort">Reset output port</param>
/// <param name="width">Display width in pixels</param>
/// <param name="height">Display height in pixels</param>
public Sh1106(ISpiBus spiBus,
IDigitalOutputPort chipSelectPort,
IDigitalOutputPort dataCommandPort,
IDigitalOutputPort resetPort,
int width = 128, int height = 64)
: base(spiBus, chipSelectPort, dataCommandPort, resetPort, width, height)
{ }

/// <summary>
/// Initialize the Sh1106
/// </summary>
protected override void Initialize()
{
Reset();

SendCommand(DisplayCommand.DisplayOff);
SendCommand(DisplayCommand.SetDisplayClockDiv);
SendCommand(0x80);

SendCommand(DisplayCommand.MultiplexModeSet);
SendCommand(DisplayCommand.MultiplexDataSet);

SendCommand(DisplayCommand.SetDisplayOffset);
SendCommand((byte)0);

SendCommand(DisplayCommand.DisplayStartLine);

SendCommand(DisplayCommand.SegInvNormal);
SendCommand(0xC0);

SendCommand(DisplayCommand.SetComPins);
SendCommand(0x12);

SendCommand(DisplayCommand.SetContrast);
SendCommand(0x0F);

SendCommand(0x30);
SendCommand(DisplayCommand.DisplayOnResume);

SendCommand(DisplayCommand.SetDisplayClockDiv);
SendCommand(0xF0);

SendCommand(DisplayCommand.DisplayVideoNormal);

Thread.Sleep(100);
SendCommand(DisplayCommand.DisplayOn);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using Meadow.Hardware;
using System.Threading;

namespace Meadow.Foundation.Displays
{
/// <summary>
/// Represents the Sh1107 family of displays
/// </summary>
public class Sh1107 : Sh110x
{
/// <summary>
/// Create a new Sh1107 object
/// </summary>
/// <param name="i2cBus">I2C bus connected to display</param>
/// <param name="address">I2C address</param>
/// <param name="width">Display width in pixels</param>
/// <param name="height">Display height in pixels</param>
public Sh1107(II2cBus i2cBus, byte address, int width = 128, int height = 128)
: base(i2cBus, address, width, height)
{ }

/// <summary>
/// Create a new Sh1107 object
/// </summary>
/// <param name="spiBus">SPI bus connected to display</param>
/// <param name="chipSelectPin">Chip select pin</param>
/// <param name="dcPin">Data command pin</param>
/// <param name="resetPin">Reset pin</param>
/// <param name="width">Display width in pixels</param>
/// <param name="height">Display height in pixels</param>
public Sh1107(ISpiBus spiBus, IPin chipSelectPin, IPin dcPin, IPin resetPin, int width = 128, int height = 128)
: base(spiBus, chipSelectPin, dcPin, resetPin, width, height)
{ }

/// <summary>
/// Create a new Sh1107 display object
/// </summary>
/// <param name="spiBus">SPI bus connected to display</param>
/// <param name="chipSelectPort">Chip select output port</param>
/// <param name="dataCommandPort">Data command output port</param>
/// <param name="resetPort">Reset output port</param>
/// <param name="width">Display width in pixels</param>
/// <param name="height">Display height in pixels</param>
public Sh1107(ISpiBus spiBus,
IDigitalOutputPort chipSelectPort,
IDigitalOutputPort dataCommandPort,
IDigitalOutputPort resetPort,
int width = 128, int height = 128)
: base(spiBus, chipSelectPort, dataCommandPort, resetPort, width, height)
{ }

/// <summary>
/// Initialize the Sh1107
/// </summary>
protected override void Initialize()
{
SendCommand(DisplayCommand.DisplayOff);
SendCommand(DisplayCommand.SetDisplayClockDiv);
SendCommand(0x51);

SendCommand(DisplayCommand.SetContrast);
SendCommand(0x4F);

SendCommand(DisplayCommand.DCDC);
SendCommand(0x8A);

SendCommand(DisplayCommand.SetSegmentRemap);
SendCommand(DisplayCommand.ComScanInc);

SendCommand(DisplayCommand.DisplayStartLine);
SendCommand((byte)0);

SendCommand(DisplayCommand.SegInvNormal);
SendCommand(0xC0);

SendCommand(DisplayCommand.SetPrecharge);
SendCommand(0x22);

SendCommand(DisplayCommand.SetVComDetect);
SendCommand(0x35);

SendCommand(DisplayCommand.DisplayOnResume);
SendCommand(DisplayCommand.DisplayVideoNormal);

if (Width == 128 && Height == 128)
{
SendCommand(DisplayCommand.SetDisplayOffset);
SendCommand((byte)0x00);
SendCommand(DisplayCommand.MultiplexModeSet);
SendCommand(0x07F);
}
else
{
SendCommand(DisplayCommand.SetDisplayOffset);
SendCommand(0x60);
SendCommand(DisplayCommand.MultiplexModeSet);
SendCommand(DisplayCommand.MultiplexDataSet);
}

Thread.Sleep(100);

SendCommand(DisplayCommand.DisplayOn);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
namespace Meadow.Foundation.Displays
{
/// <summary>
/// Provide an interface to the Sh1106 family of displays
/// </summary>
public partial class Sh1106
public partial class Sh110x
{
/// <summary>
/// Allow the programmer to set the scroll direction
Expand All @@ -28,17 +25,17 @@ public enum ScrollDirection
LeftAndVertical
}

enum DisplayCommand : byte
internal enum DisplayCommand : byte
{
DCDC = 0xAD,
DisplayOff = 0xAE,
DisplayOn = 0xAF,
DisplayOnResume = 0xA4,
DisplayStartLine = 0x40,
PageAddress = 0xB0,
SetPageAddress = 0xB0,
ColumnAddressHigh = 0x10,
ColumnAddressLow = 0x02,
SetPageAddress = 0xB0,
ColumnAddress = 0x21,

DisplayVideoNormal = 0xA6,
DisplayVideoReverse = 0xA7,
AllPixelsOn = 0xA5,
Expand All @@ -47,14 +44,16 @@ enum DisplayCommand : byte
SetDisplayOffset = 0xD3,
OutputFollowsRam = 0xA4,
MemoryMode = 0x20,
ColumnAddress = 0x21,
PageAddress = 0x22,

MultiplexModeSet = 0xA8,
MultiplexDataSet = 0x3F,

SetChargePump = 0x8D,
SetPrecharge = 0xD9,
SetComPins = 0xDA,
SetComDetect = 0xDB,
SetVComDetect = 0xDB,
ComScanInc = 0xC0,
ComScanDec = 0xC8,

Expand All @@ -63,5 +62,40 @@ enum DisplayCommand : byte

SetSegmentRemap = 0xA1,
}

/// <summary>
/// Valid I2C addresses for the display
/// </summary>
public enum Addresses : byte
{
/// <summary>
/// Bus address 0x3C
/// Commonly used with 128x32 displays
/// </summary>
Address_0x3C = 0x3C,
/// <summary>
/// Bus address 0x3D
/// </summary>
Address_0x3D = 0x3D,
/// <summary>
/// Default bus address
/// </summary>
Default = Address_0x3D
}

/// <summary>
/// The display connection type
/// </summary>
public enum ConnectionType
{
/// <summary>
/// SPI
/// </summary>
SPI,
/// <summary>
/// I2C
/// </summary>
I2C,
}
}
}
Loading