Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureAnalogIO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContex
static class AnalogIO
{
public const int ID = 22;
public const uint MinimumVersion = 2;

// constants
public const int ChannelCount = 12;
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureBno055.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class Bno055
{
public const int ID = 9;
public const uint MinimumVersion = 2;

// constants
public const float EulerAngleScale = 1f / 16; // 1 degree = 16 LSB
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureDigitalIO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class DigitalIO
{
public const int ID = 18;
public const uint MinimumVersion = 2;

// managed registers
public const uint ENABLE = 0x0;
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureHarpSyncInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class HarpSyncInput
{
public const int ID = 30;
public const uint MinimumVersion = 2;

// managed registers
public const uint ENABLE = 0x0; // Enable or disable the data stream
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class Headstage64ElectricalStimulator
{
public const int ID = 4;
public const uint MinimumVersion = 3;

// NB: could be read from REZ but these are constant
public const double DacBitDepth = 16;
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureHeadstage64OpticalStimulator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class Headstage64OpticalStimulator
{
public const int ID = 5;
public const uint MinimumVersion = 3;

// NB: can be read with MINRHEOR and POTRES, but will not change
public const uint MinRheostatResistanceOhms = 590;
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureHeartbeat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class Heartbeat
{
public const int ID = 12;
public const uint MinimumVersion = 1;

public const uint ENABLE = 0; // Enable the heartbeat
public const uint CLK_DIV = 1; // Heartbeat clock divider ratio. Default results in 10 Hz heartbeat. Values less than CLK_HZ / 10e6 Hz will result in 1kHz.
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureLoadTester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class LoadTester
{
public const int ID = 27;
public const uint MinimumVersion = 2;

public const uint ENABLE = 0;
public const uint CLK_DIV = 1;
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureMemoryMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class MemoryMonitor
{
public const int ID = 28;
public const uint MinimumVersion = 2;

public const uint ENABLE = 0; // Enable the monitor
public const uint CLK_DIV = 1; // Sample clock divider ratio. Values less than CLK_HZ / 10e6 Hz will result in 1kHz.
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureNric1384.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class Nric1384
{
public const int ID = 33;
public const uint MinimumVersion = 1;

public const int I2cAddress = 0x70;
public const int ChannelCount = 384;
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureOutputClock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class OutputClock
{
public const int ID = 20;
public const uint MinimumVersion = 1;

public const uint NULL = 0; // No command
public const uint CLOCK_GATE = 1; // Output gate. Bit 0 = 0 is disabled, Bit 0 = 1 is enabled.
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigurePersistentHeartbeat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class PersistentHeartbeat
{
public const int ID = 35;
public const uint MinimumVersion = 1;

public const uint ENABLE = 0; // Heartbeat enable state (read only; always enabled for this device).
public const uint CLK_DIV = 1; // Heartbeat clock divider ratio. Minimum value is CLK_HZ / 10e6.
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigurePortController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
internal static class PortController
{
public const int ID = 23;
public const uint MinimumVersion = 2;

public const uint ENABLE = 0; // The LSB is used to enable or disable the device data stream
public const uint GPOSTATE = 1; // GPO output state (bits 31 downto 3: ignore. bits 2 downto 0: ‘1’ = high, ‘0’ = low)
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureRhd2164.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class Rhd2164
{
public const int ID = 3;
public const uint MinimumVersion = 2;

// constants
public const int AmplifierChannelCount = 64;
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureRhs2116.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class Rhs2116
{
public const int ID = 31;
public const uint MinimumVersion = 3;

// constants
public const int AmplifierChannelCount = 16;
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureRhs2116Trigger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ static void WriteStimulusSequence(DeviceContext device, Rhs2116StimulusSequence
static class Rhs2116Trigger
{
public const int ID = 32;
public const uint MinimumVersion = 2;

// managed registers
public const uint ENABLE = 0; // Enable or disable the trigger event datastream
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/ConfigureTS4231V1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
static class TS4231V1
{
public const int ID = 25;
public const uint MinimumVersion = 2;

// managed registers
public const uint ENABLE = 0x0; // Enable or disable the data output stream
Expand Down
39 changes: 39 additions & 0 deletions OpenEphys.Onix1/ContextHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ public static DeviceContext GetDeviceContext(this ContextTask context, uint addr
ThrowInvalidDeviceException(expectedType, address);
}

var minVersion = GetMinimumFirmwareVersion(expectedType);

if (device.Version < minVersion)
{
ThrowInvalidDeviceVersionException(expectedType, address, device.Version, minVersion);
}

return new DeviceContext(context, device);
}

Expand Down Expand Up @@ -60,6 +67,23 @@ static int GetDeviceID(Type deviceType)
return (int)fieldInfo.GetRawConstantValue();
}

static uint GetMinimumFirmwareVersion(Type deviceType)
{
var fieldInfo = deviceType.GetField(
"MinimumVersion",
BindingFlags.Static |
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.IgnoreCase);
if (fieldInfo == null || !fieldInfo.IsLiteral)
{
throw new ArgumentException($"The specified device type {deviceType} does not have a const MinimumVersion field.", nameof(deviceType));
}

return (uint)fieldInfo.GetRawConstantValue();
}


static void ThrowDeviceNotFoundException(Type expectedType, uint address)
{
throw new InvalidOperationException($"Device '{expectedType.Name}' was not found in the device table at address {address}.");
Expand All @@ -70,6 +94,21 @@ static void ThrowInvalidDeviceException(Type expectedType, uint address)
throw new InvalidOperationException($"Invalid device ID. The device found at address {address} is not a '{expectedType.Name}' device.");
}

static void ThrowInvalidDeviceVersionException(Type expectedType, uint address, uint deviceVersion, uint minimumVersion)
{
var assembly = Assembly.GetExecutingAssembly();
string libraryName = assembly.GetName().Name ?? "Unknown";
string libraryVersion = assembly.GetName().Version.ToString() ?? "Unknown";

Console.Error.WriteLine($"Error: The {expectedType.Name} device at address {address} is v{deviceVersion}, " +
$"but v{minimumVersion} is required by {libraryName} {libraryVersion}.");
Console.Error.WriteLine($"In order to use {libraryName} {libraryVersion} with this device, you will need to update it firmware. " +
$"Firmware update files and instructions can be found at https://open-ephys.github.io/onix-docs/index.html.");

throw new InvalidOperationException($"Invalid device version. The {expectedType.Name} device at address {address} is v{deviceVersion}, " +
$"but v{minimumVersion} is required.");
}

internal static bool CheckDeviceType(Type deviceType, Type targetType)
{
if (deviceType == targetType) return true;
Expand Down
1 change: 1 addition & 0 deletions OpenEphys.Onix1/DS90UB9x.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace OpenEphys.Onix1
static class DS90UB9x
{
public const int ID = 24;
public const uint MinimumVersion = 3;

// managed registers
public const uint ENABLE = 0x8000;
Expand Down
Loading