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