未验证 提交 fa0a4f73 编写于 作者: P Patrick Grawehr 提交者: GitHub

Introduce wait states for some commands (#1466)

Otherwise, the display initialization might fail, leaving
the display in an undefined state
上级 34db232b
......@@ -103,18 +103,13 @@ namespace Iot.Device.CharacterLcd
_displayControl |= DisplayControl.DisplayOn;
_displayMode |= DisplayEntryMode.Increment;
ReadOnlySpan<byte> commands = stackalloc byte[]
{
// Function must be set first to ensure that we always have the basic
// instruction set selected. (See PCF2119x datasheet Function_set note
// for one documented example of where this is necessary.)
(byte)_displayFunction,
(byte)_displayControl,
(byte)_displayMode,
ClearDisplayCommand
};
SendCommands(commands);
// Function must be set first to ensure that we always have the basic
// instruction set selected. (See PCF2119x datasheet Function_set note
// for one documented example of where this is necessary.)
SendCommandAndWait((byte)_displayFunction);
SendCommandAndWait((byte)_displayControl);
SendCommandAndWait((byte)_displayMode);
SendCommandAndWait(ClearDisplayCommand);
}
/// <summary>
......@@ -138,6 +133,14 @@ namespace Iot.Device.CharacterLcd
/// <param name="command">Byte representing the command to be sent</param>
protected void SendCommand(byte command) => _lcdInterface.SendCommand(command);
/// <summary>
/// The initialization sequence and some other complex commands should be sent with delays, or the display may
/// behave unexpectedly. It may show random, blinking characters
/// or display text very faintly only.
/// </summary>
/// <param name="command">The command to send</param>
protected void SendCommandAndWait(byte command) => _lcdInterface.SendCommandAndWait(command);
/// <summary>
/// Sends data to the device
/// </summary>
......@@ -259,7 +262,7 @@ namespace Iot.Device.CharacterLcd
public bool DisplayOn
{
get => (_displayControl & DisplayControl.DisplayOn) > 0;
set => SendCommand((byte)(value ? _displayControl |= DisplayControl.DisplayOn
set => SendCommandAndWait((byte)(value ? _displayControl |= DisplayControl.DisplayOn
: _displayControl &= ~DisplayControl.DisplayOn));
}
......@@ -269,7 +272,7 @@ namespace Iot.Device.CharacterLcd
public bool UnderlineCursorVisible
{
get => (_displayControl & DisplayControl.CursorOn) > 0;
set => SendCommand((byte)(value ? _displayControl |= DisplayControl.CursorOn
set => SendCommandAndWait((byte)(value ? _displayControl |= DisplayControl.CursorOn
: _displayControl &= ~DisplayControl.CursorOn));
}
......@@ -279,7 +282,7 @@ namespace Iot.Device.CharacterLcd
public bool BlinkingCursorVisible
{
get => (_displayControl & DisplayControl.BlinkOn) > 0;
set => SendCommand((byte)(value ? _displayControl |= DisplayControl.BlinkOn
set => SendCommandAndWait((byte)(value ? _displayControl |= DisplayControl.BlinkOn
: _displayControl &= ~DisplayControl.BlinkOn));
}
......@@ -289,7 +292,7 @@ namespace Iot.Device.CharacterLcd
public bool AutoShift
{
get => (_displayMode & DisplayEntryMode.DisplayShift) > 0;
set => SendCommand((byte)(value ? _displayMode |= DisplayEntryMode.DisplayShift
set => SendCommandAndWait((byte)(value ? _displayMode |= DisplayEntryMode.DisplayShift
: _displayMode &= ~DisplayEntryMode.DisplayShift));
}
......@@ -299,7 +302,7 @@ namespace Iot.Device.CharacterLcd
public bool Increment
{
get => (_displayMode & DisplayEntryMode.Increment) > 0;
set => SendCommand((byte)(value ? _displayMode |= DisplayEntryMode.Increment
set => SendCommandAndWait((byte)(value ? _displayMode |= DisplayEntryMode.Increment
: _displayMode &= ~DisplayEntryMode.Increment));
}
......@@ -393,14 +396,13 @@ namespace Iot.Device.CharacterLcd
/// </remarks>
public void Write(string text)
{
byte[] buffer = ArrayPool<byte>.Shared.Rent(text.Length);
Span<byte> buffer = stackalloc byte[text.Length];
for (int i = 0; i < text.Length; ++i)
{
buffer[i] = (byte)text[i];
}
SendData(new ReadOnlySpan<byte>(buffer, 0, text.Length));
ArrayPool<byte>.Shared.Return(buffer);
SendData(buffer);
}
/// <summary>
......
......@@ -54,7 +54,7 @@ namespace Iot.Device.CharacterLcd
{
_backlightOn = value;
// Need to send a command to make this happen immediately.
SendCommand(0);
SendCommandAndWait(0);
}
}
......@@ -87,7 +87,7 @@ namespace Iot.Device.CharacterLcd
SendCommandAndWait(LCD_ENTRYMODESET | LCD_ENTRYLEFT);
}
private void SendCommandAndWait(byte command)
public override void SendCommandAndWait(byte command)
{
// Must not run the init sequence to fast or undefined behavior may occur
SendCommand(command);
......
......@@ -5,6 +5,7 @@ using System;
using System.Device;
using System.Device.Gpio;
using System.Device.I2c;
using System.Threading;
namespace Iot.Device.CharacterLcd
{
......@@ -81,6 +82,19 @@ namespace Iot.Device.CharacterLcd
/// <param name="values">Each byte represents command to be send</param>
public abstract void SendCommands(ReadOnlySpan<byte> values);
/// <summary>
/// The initialization sequence and some other complex commands should be sent with delays, or the display may
/// behave unexpectedly. It may show random, blinking characters
/// or display text very faintly only.
/// </summary>
/// <param name="command">The command to send</param>
public virtual void SendCommandAndWait(byte command)
{
// Must not run the init sequence to fast or undefined behavior may occur
SendCommand(command);
Thread.Sleep(1);
}
/// <summary>
/// True if device uses 8-bits for communication, false if device uses 4-bits
/// </summary>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册