Skip to content

Commit 918e491

Browse files
MrCSharp22networkfusionEllerbach
authored
[ePaper] Remove default wait timeout (#1183)
Co-authored-by: Robin Jones <[email protected]> Co-authored-by: Laurent Ellerbach <[email protected]>
1 parent 37ca803 commit 918e491

File tree

6 files changed

+85
-57
lines changed

6 files changed

+85
-57
lines changed

devices/ePaper/Drivers/IePaperDisplay.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,19 @@ public interface IEPaperDisplay : IDisposable
9191
/// <param name="data">The frame data to send.</param>
9292
void SendData(params byte[] data);
9393

94+
/// <summary>
95+
/// Send frame data to the display.
96+
/// </summary>
97+
/// <param name="data">The frame data to send.</param>
98+
void SendData(params ushort[] data);
99+
94100
/// <summary>
95101
/// Blocks the current thread until the display is in idle mode again.
96102
/// </summary>
97-
/// <param name="waitingTime">The maximum time to wait in ms before exiting the method. -1 to wait infinitely.</param>
98-
/// <param name="cancellationToken">The <see cref="CancellationTokenSource"/> to be able to cancel the waiting time.</param>
99-
/// <returns>True if it returns before the <see cref="CancellationTokenSource"/> expires, false otherwise.</returns>
100-
/// <remarks>If _waitingTime_ is set to -1, _cancellationToken_ could not be null, and a exception will be throw.</remarks>
101-
bool WaitReady(int waitingTime, CancellationTokenSource cancellationToken);
103+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to be able to cancel the waiting time.</param>
104+
/// <returns>True if it returns before the <see cref="CancellationToken"/> expires, false otherwise.</returns>
105+
/// <remarks>If cancellationToken is null, this method will block until the busy pin is low.</remarks>
106+
bool WaitReady(CancellationToken cancellationToken = default);
102107

103108
/// <summary>
104109
/// Begins a frame draw operation with frame paging support.

devices/ePaper/Drivers/JD796xx/JD79653A.cs

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Threading;
99
using Iot.Device.EPaper.Buffers;
1010
using Iot.Device.EPaper.Enums;
11+
using Iot.Device.EPaper.Utilities;
1112

1213
namespace Iot.Device.EPaper.Drivers.Jd796xx
1314
{
@@ -16,7 +17,6 @@ namespace Iot.Device.EPaper.Drivers.Jd796xx
1617
/// </summary>
1718
public abstract class Jd79653A : IEPaperDisplay
1819
{
19-
private readonly int _maxWaitingTime = 500;
2020
private readonly bool _shouldDispose;
2121
private readonly byte[] _whiteBuffer;
2222
private bool _disposed;
@@ -433,7 +433,7 @@ public virtual void Initialize()
433433

434434
SendCommand((byte)Command.PowerOn);
435435

436-
if (WaitReady(_maxWaitingTime))
436+
if (WaitReady())
437437
{
438438
PowerState = PowerState.PoweredOn;
439439
}
@@ -480,7 +480,7 @@ public virtual bool PerformFullRefresh()
480480
// as per samples from screen manufacturer, refresh wait should be at least 200µs
481481
// using a spin wait of 5ms, any value should be ok
482482
// and use a large waiting time in case of something unexpected happens.
483-
return WaitReady(_maxWaitingTime);
483+
return WaitReady();
484484
}
485485

486486
/// <inheritdoc/>
@@ -499,7 +499,7 @@ public virtual void PowerDown(SleepMode sleepMode = SleepMode.Normal)
499499
SendCommand((byte)Command.IntervalSetting);
500500
SendData(0x07);
501501
SendCommand((byte)Command.PowerOff);
502-
WaitReady(_maxWaitingTime);
502+
WaitReady();
503503

504504
// as per samples from screen manufacturer, power off request a time delay of 1s before continue.
505505
WaitMs(1000);
@@ -531,7 +531,7 @@ public virtual void PowerOn()
531531
SendData(0xd7);
532532
SendCommand((byte)Command.PowerOn);
533533

534-
if (WaitReady(_maxWaitingTime))
534+
if (WaitReady())
535535
{
536536
PowerState = PowerState.PoweredOn;
537537
}
@@ -559,6 +559,18 @@ public virtual void SendData(params byte[] data)
559559
_dataCommandPin.Write(PinValue.Low);
560560
}
561561

562+
/// <inheritdoc/>
563+
public virtual void SendData(params ushort[] data)
564+
{
565+
// set the data/command pin to high to indicate to the display we will be sending data
566+
_dataCommandPin.Write(PinValue.High);
567+
568+
_spiDevice.Write(data);
569+
570+
// go back to low (command mode)
571+
_dataCommandPin.Write(PinValue.Low);
572+
}
573+
562574
/// <summary>
563575
/// Sets the current active frame buffer page to the specified page index.
564576
/// Existing frame buffer is reused by clearing it first and page bounds are recalculated.
@@ -592,7 +604,7 @@ protected virtual void SoftwareReset()
592604
{
593605
SendCommand(0x04);
594606

595-
WaitReady(_maxWaitingTime);
607+
WaitReady();
596608
WaitMs(10);
597609
}
598610

@@ -606,25 +618,8 @@ protected virtual void WaitMs(int milliseconds)
606618
}
607619

608620
/// <inheritdoc/>
609-
public virtual bool WaitReady(int waitingTime, CancellationTokenSource cancellationToken = default)
610-
{
611-
if (cancellationToken == default)
612-
{
613-
if (waitingTime < 0)
614-
{
615-
throw new ArgumentNullException(nameof(cancellationToken), $"{nameof(cancellationToken)} cannot be null with {nameof(waitingTime)} < 0");
616-
}
617-
618-
cancellationToken = new CancellationTokenSource(waitingTime);
619-
}
620-
621-
while (!cancellationToken.IsCancellationRequested && _busyPin.Read() == PinValue.Low)
622-
{
623-
cancellationToken.Token.WaitHandle.WaitOne(5, true);
624-
}
625-
626-
return !cancellationToken.IsCancellationRequested;
627-
}
621+
public virtual bool WaitReady(CancellationToken cancellationToken = default)
622+
=> _busyPin.WaitUntilPinValueEquals(PinValue.High, cancellationToken);
628623

629624
#region IDisposable
630625

devices/ePaper/Drivers/Ssd168x/Ssd168x.cs

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
using System;
55
using System.Device.Gpio;
66
using System.Device.Spi;
7+
using System.Diagnostics;
78
using System.Drawing;
89
using System.Threading;
910

1011
using Iot.Device.EPaper.Buffers;
1112
using Iot.Device.EPaper.Enums;
13+
using Iot.Device.EPaper.Utilities;
1214

1315
namespace Iot.Device.EPaper.Drivers.Ssd168x
1416
{
@@ -17,7 +19,6 @@ namespace Iot.Device.EPaper.Drivers.Ssd168x
1719
/// </summary>
1820
public abstract class Ssd168x : IEPaperDisplay
1921
{
20-
private readonly int _maxWaitingTime = 500;
2122
private readonly bool _shouldDispose;
2223
private SpiDevice _spiDevice;
2324
private GpioController _gpioController;
@@ -437,7 +438,7 @@ public virtual void Initialize()
437438
SendCommand((byte)Command.DriverOutputControl);
438439

439440
// refer to the datasheet for a description of the parameters
440-
SendData((byte)Height, 0x00, 0x00);
441+
SendData((ushort)Height, 0x00);
441442

442443
// Set data entry sequence
443444
SendCommand((byte)Command.DataEntryModeSetting);
@@ -455,7 +456,7 @@ public virtual void Initialize()
455456
SendCommand((byte)Command.SetRAMAddressYStartEndPosition);
456457

457458
// Param1 & 2: Start at 0 | Param3 & 4: End at display height converted to bytes
458-
SendData(0x00, 0x00, (byte)(Height - 1), 0x00);
459+
SendData(0, (ushort)Height);
459460

460461
// Set Panel Border
461462
SendCommand((byte)Command.BorderWaveformControl);
@@ -507,7 +508,7 @@ public virtual bool PerformFullRefresh()
507508
SendData((byte)RefreshMode.FullRefresh); // Display Mode 1 (Full Refresh)
508509

509510
SendCommand((byte)Command.MasterActivation);
510-
return WaitReady(_maxWaitingTime);
511+
return WaitReady();
511512
}
512513

513514
/// <inheritdoc/>
@@ -520,7 +521,7 @@ public virtual bool PerformPartialRefresh()
520521
SendData((byte)RefreshMode.PartialRefresh); // Display Mode 2 (Partial Refresh)
521522

522523
SendCommand((byte)Command.MasterActivation);
523-
return WaitReady(_maxWaitingTime);
524+
return WaitReady();
524525
}
525526

526527
/// <summary>
@@ -574,6 +575,18 @@ public virtual void SendData(params byte[] data)
574575
_dataCommandPin.Write(PinValue.Low);
575576
}
576577

578+
/// <inheritdoc/>
579+
public virtual void SendData(params ushort[] data)
580+
{
581+
// set the data/command pin to high to indicate to the display we will be sending data
582+
_dataCommandPin.Write(PinValue.High);
583+
584+
_spiDevice.Write(data);
585+
586+
// go back to low (command mode)
587+
_dataCommandPin.Write(PinValue.Low);
588+
}
589+
577590
/// <summary>
578591
/// Sets the current active frame buffer page to the specified page index.
579592
/// Existing frame buffer is reused by clearing it first and page bounds are recalculated.
@@ -613,8 +626,7 @@ protected virtual void SoftwareReset()
613626
{
614627
SendCommand((byte)Command.SoftwareReset);
615628

616-
WaitReady(_maxWaitingTime);
617-
WaitMs(10);
629+
WaitReady();
618630
}
619631

620632
/// <summary>
@@ -627,25 +639,8 @@ protected virtual void WaitMs(int milliseconds)
627639
}
628640

629641
/// <inheritdoc/>
630-
public virtual bool WaitReady(int waitingTime, CancellationTokenSource cancellationToken = default)
631-
{
632-
if (cancellationToken == default)
633-
{
634-
if (waitingTime < 0)
635-
{
636-
throw new ArgumentNullException(nameof(cancellationToken), $"{nameof(cancellationToken)} cannot be null with {nameof(waitingTime)} < 0");
637-
}
638-
639-
cancellationToken = new CancellationTokenSource(waitingTime);
640-
}
641-
642-
while (!cancellationToken.IsCancellationRequested && _busyPin.Read() == PinValue.High)
643-
{
644-
cancellationToken.Token.WaitHandle.WaitOne(5, true);
645-
}
646-
647-
return !cancellationToken.IsCancellationRequested;
648-
}
642+
public virtual bool WaitReady(CancellationToken cancellationToken = default)
643+
=> _busyPin.WaitUntilPinValueEquals(PinValue.Low, cancellationToken);
649644

650645
#region IDisposable
651646

devices/ePaper/Samples/SSD1681Sample/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public static void Main()
145145

146146
// at this point, all frame pages have been pushed to the display
147147
// this will execute the refresh sequence and display the frame data
148-
display.PerformFullRefresh();
148+
display.PerformPartialRefresh();
149149

150150
// Done! now put the display to sleep to reduce power consumption
151151
display.PowerDown(SleepMode.DeepSleepModeTwo);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2024 The nanoFramework project contributors
2+
// See LICENSE file in the project root for full license information.
3+
4+
using System.Device.Gpio;
5+
using System.Threading;
6+
7+
namespace Iot.Device.EPaper.Utilities
8+
{
9+
internal static class GpioPinExtensions
10+
{
11+
/// <summary>
12+
/// Blocks the current thread until the pin value equals the desired value.
13+
/// </summary>
14+
/// <param name="pin">The GPIO pin to wait on.</param>
15+
/// <param name="desiredValue">The desired value of the pin to continue thread execution.</param>
16+
/// <param name="cancellationToken">The <see cref="CancellationTokenSource"/> to use to cancel blocking the thread if needed.</param>
17+
/// <returns><see langword="true"/> if the waiting ended with the pin changing to the desired value. <see langword="false"/> if the wait ended due to timeout.</returns>
18+
/// <remarks>Use the <paramref name="cancellationToken"/> as a way to cancel the wait after some time if needed.</remarks>
19+
public static bool WaitUntilPinValueEquals(
20+
this GpioPin pin,
21+
PinValue desiredValue,
22+
CancellationToken cancellationToken = default)
23+
{
24+
while (!cancellationToken.IsCancellationRequested && pin.Read() != desiredValue)
25+
{
26+
cancellationToken.WaitHandle.WaitOne(5, true);
27+
}
28+
29+
return !cancellationToken.IsCancellationRequested;
30+
}
31+
}
32+
}

devices/ePaper/ePaper.nfproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
<Compile Include="Fonts\Font8x12.cs" />
5555
<Compile Include="Graphics.cs" />
5656
<Compile Include="Properties\AssemblyInfo.cs" />
57+
<Compile Include="Utilities\GpioPinExtensions.cs" />
5758
</ItemGroup>
5859
<ItemGroup>
5960
<None Include="packages.config" />

0 commit comments

Comments
 (0)