Skip to content

Commit

Permalink
Merge pull request #13 from bonsai-rx/create-pulsepal
Browse files Browse the repository at this point in the history
Avoid using event callbacks for mono compatibility
  • Loading branch information
glopesdev committed Jan 31, 2024
2 parents a545834 + 7c9f481 commit d03a742
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 14 deletions.
1 change: 1 addition & 0 deletions Bonsai.PulsePal/Bonsai.PulsePal.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<Description>Bonsai Library containing modules for interfacing with the PulsePal pulse train generator.</Description>
<PackageTags>Bonsai Rx PulsePal Pulse Stimulator</PackageTags>
<TargetFramework>net462</TargetFramework>
<LangVersion>9.0</LangVersion>
<Version>0.2.0</Version>
</PropertyGroup>

Expand Down
78 changes: 64 additions & 14 deletions Bonsai.PulsePal/PulsePal.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.IO.Ports;
using System.IO;
using System.Threading.Tasks;
using System.Threading;

namespace Bonsai.PulsePal
{
Expand Down Expand Up @@ -44,7 +46,6 @@ public PulsePal(string portName)
responseBuffer = new byte[4];
commandBuffer = new byte[MaxDataBytes];
readBuffer = new byte[serialPort.ReadBufferSize];
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
}

public int MajorVersion { get; private set; }
Expand All @@ -56,28 +57,79 @@ public bool IsOpen
get { return serialPort.IsOpen; }
}

void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
Task RunAsync(CancellationToken cancellationToken)
{
var bytesToRead = serialPort.BytesToRead;
if (serialPort.IsOpen && bytesToRead > 0)
serialPort.Open();
serialPort.ReadExisting();
Connect();

return Task.Factory.StartNew(() =>
{
bytesToRead = serialPort.Read(readBuffer, 0, bytesToRead);
for (int i = 0; i < bytesToRead; i++)
using var cancellation = cancellationToken.Register(serialPort.Dispose);
while (!cancellationToken.IsCancellationRequested)
{
ProcessInput(readBuffer[i]);
try
{
var bytesToRead = serialPort.BytesToRead;
if (bytesToRead == 0)
{
var nextByte = serialPort.ReadByte();
if (nextByte < 0) break;
ProcessInput((byte)nextByte);
}
else
{
while (bytesToRead > 0)
{
var bytesRead = serialPort.Read(readBuffer, 0, Math.Min(bytesToRead, readBuffer.Length));
for (int i = 0; i < bytesRead; i++)
{
ProcessInput(readBuffer[i]);
}
bytesToRead -= bytesRead;
}
}
}
catch (Exception)
{
if (!cancellationToken.IsCancellationRequested)
{
throw;
}
break;
}
}
}
},
cancellationToken,
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
}

public void Open()
/// <summary>
/// Opens a new serial port connection to the Pulse Pal device.
/// </summary>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the operation.
/// </param>
public void Open(CancellationToken cancellationToken = default)
{
RunAsync(cancellationToken);
}

void Connect()
{
serialPort.Open();
serialPort.ReadExisting();
commandBuffer[0] = OpMenu;
commandBuffer[1] = HandshakeCommand;
serialPort.Write(commandBuffer, 0, 2);
}

void Disconnect()
{
commandBuffer[0] = OpMenu;
commandBuffer[1] = DisconnectCommand;
serialPort.Write(commandBuffer, 0, 2);
}

void WriteInt(BinaryWriter writer, int value)
{
writer.Write((byte)value);
Expand Down Expand Up @@ -270,9 +322,7 @@ private void Dispose(bool disposing)
{
if (disposing)
{
commandBuffer[0] = OpMenu;
commandBuffer[1] = DisconnectCommand;
serialPort.Write(commandBuffer, 0, 2);
Disconnect();
serialPort.Close();
disposed = true;
}
Expand Down

0 comments on commit d03a742

Please sign in to comment.