Skip to content

Commit 1f4e21b

Browse files
committed
Minor fixes to breakout board clock ouput
- Constrain frequency and duty cycle with exceptions - Remove unsafe designation from BreakoutOutputClockData.Generate() - Lots of XML improvments - Improve public property names
1 parent 9ea405f commit 1f4e21b

File tree

2 files changed

+55
-34
lines changed

2 files changed

+55
-34
lines changed

OpenEphys.Onix1/BreakoutOutputClockData.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class BreakoutOutputClockData : Source<BreakoutOutputClockParameters>
2727
/// Generates a sequence containing a single <see cref="BreakoutOutputClockParameters"/>.
2828
/// </summary>
2929
/// <returns>A sequence containing a single <see cref="BreakoutOutputClockParameters"/></returns>
30-
public unsafe override IObservable<BreakoutOutputClockParameters> Generate()
30+
public override IObservable<BreakoutOutputClockParameters> Generate()
3131
{
3232
return DeviceManager.GetDevice(DeviceName).SelectMany(
3333
deviceInfo =>

OpenEphys.Onix1/ConfigureBreakoutOutputClock.cs

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
namespace OpenEphys.Onix1
99
{
1010
/// <summary>
11-
/// Configures a the breakout board's output clock.
11+
/// Configures the ONIX breakout board's output clock.
1212
/// </summary>
1313
/// <remarks>
1414
/// The output clock provides physical, 3.3V logic level, 50 Ohm output impedance, frequency divided copy
@@ -17,10 +17,12 @@ namespace OpenEphys.Onix1
1717
/// user defined rate, duty cycle, and start delay. It can be used to drive external hardware or can be
1818
/// logged by external recording systems for post-hoc synchronization with ONIX data.
1919
/// </remarks>
20-
[Description("Configures a heartbeat device.")]
20+
[Description("Configures the ONIX breakout board's output clock.")]
2121
public class ConfigureBreakoutOutputClock : SingleDeviceFactory
2222
{
2323
readonly BehaviorSubject<bool> gate = new(false);
24+
double frequencyHz = 1e6;
25+
double dutyCycle = 50;
2426

2527
/// <summary>
2628
/// Initializes a new instance of the <see cref="ConfigureBreakoutOutputClock"/> class.
@@ -32,13 +34,13 @@ public ConfigureBreakoutOutputClock()
3234
}
3335

3436
/// <summary>
35-
/// Gets or sets a value specifying of the output clock is active.
37+
/// Gets or sets a value specifying if the output clock is active.
3638
/// </summary>
3739
/// <remarks>
3840
/// If set to true, the clock output will connected to the clock output line. If set to false, the
39-
/// clock output line will be held low.
41+
/// clock output line will be held low. This value can be toggled in real time to gate acquisition of
42+
/// external hardware.
4043
/// </remarks>
41-
[Range(1, 10e6)]
4244
[Category(AcquisitionCategory)]
4345
[Description("Clock gate control signal.")]
4446
public bool ClockGate
@@ -51,48 +53,63 @@ public bool ClockGate
5153
/// Gets or sets the output clock frequency in Hz.
5254
/// </summary>
5355
/// <remarks>
54-
/// The output clock high and low times must each be an integer multiple of the <see
55-
/// cref="ContextTask.AcquisitionClockHz">Acquisition Clock</see> frequency. Therefore, the true clock
56-
/// frequency will be set to a value that is as close as possible to the requested setting while
57-
/// respecting this constraint. The value as actualized in hardware is available using <see
58-
/// cref="BreakoutOutputClockData"/>.
56+
/// Valid values are between 0.1 Hz and 10 MHz. The output clock high and low times must each be an
57+
/// integer multiple of the <see cref="ContextTask.AcquisitionClockHz">Acquisition Clock</see>
58+
/// frequency. Therefore, the true clock frequency will be set to a value that is as close as possible
59+
/// to the requested setting while respecting this constraint. The value as actualized in hardware is
60+
/// reported by <see cref="BreakoutOutputClockData"/>.
5961
/// </remarks>
60-
[Range(1, 10e6)]
62+
[Range(0.1, 10e6)]
6163
[Category(ConfigurationCategory)]
6264
[Description("Frequency of the output clock (Hz).")]
63-
public double Frequency { get; set; } = 1e6;
65+
public double Frequency
66+
{
67+
get => frequencyHz;
68+
set => frequencyHz = value >= 0.1 && value <= 10e6
69+
? value
70+
: throw new ArgumentOutOfRangeException(nameof(Frequency), value,
71+
$"{nameof(Frequency)} must be between 0.1 Hz and 10 MHz.");
72+
}
6473

6574
/// <summary>
6675
/// Gets or sets the output clock duty cycle in percent.
6776
/// </summary>
6877
/// <remarks>
69-
/// The output clock high and low times must each be an integer multiple of the <see
70-
/// cref="ContextTask.AcquisitionClockHz">Acquisition Clock</see> frequency. Therefore, the true duty
71-
/// cycle will be set to a value that is as close as possible to the requested setting while
72-
/// respecting this constraint. The value as actualized in hardware is available using <see
73-
/// cref="BreakoutOutputClockData"/>.
78+
/// Valid values are between 10% and 90%. The output clock high and low times must each be an integer
79+
/// multiple of the <see cref="ContextTask.AcquisitionClockHz">Acquisition Clock</see> frequency.
80+
/// Therefore, the true duty cycle will be set to a value that is as close as possible to the
81+
/// requested setting while respecting this constraint. The value as actualized in hardware is
82+
/// reported by <see cref="BreakoutOutputClockData"/>.
7483
/// </remarks>
7584
[Range(10, 90)]
7685
[Editor(DesignTypes.SliderEditor, typeof(UITypeEditor))]
7786
[Category(ConfigurationCategory)]
7887
[Precision(1, 1)]
7988
[Description("Duty cycle of output clock (%).")]
80-
public double DutyCycle { get; set; } = 50.0;
89+
public double DutyCycle
90+
{
91+
get => dutyCycle;
92+
set => dutyCycle = value >= 10 && value <= 90
93+
? value
94+
: throw new ArgumentOutOfRangeException(nameof(DutyCycle), value,
95+
$"{nameof(DutyCycle)} must be between 10% and 90%.");
96+
}
8197

8298
/// <summary>
83-
/// Gets or sets the delay following acquisition start before the clock becomes active in seconds.
99+
/// Gets or sets the delay following acquisition commencement before the clock becomes active in
100+
/// seconds.
84101
/// </summary>
85102
/// <remarks>
86103
/// <para>
87-
/// Setting to a value greater than 0 can be useful for ensuring data sources that are driven by the
88-
/// <c>System Clock</c> start significantly after ONIX has begun aquisition for the purposes of
89-
/// ordering acquisition start times.
104+
/// Valid values are between 0 and and 3600 seconds. Setting to a value greater than 0 can be useful
105+
/// for ensuring data sources that are driven by the output clock start significantly after ONIX has
106+
/// begun aquisition for the purposes of ordering acquisition start times.
90107
/// </para>
91108
/// <para>
92109
/// The delay must each be an integer multiple of the <see
93110
/// cref="ContextTask.AcquisitionClockHz">Acquisition Clock</see> frequency. Therefore, the true delay
94111
/// cycle will be set to a value that is as close as possible to the requested setting while
95-
/// respecting this constraint. The value as actualized in hardware is available using <see
112+
/// respecting this constraint. The value as actualized in hardware is reported by <see
96113
/// cref="BreakoutOutputClockData"/>.
97114
/// </para>
98115
/// </remarks>
@@ -134,8 +151,8 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
134151
device.WriteRegister(BreakoutOutputClock.LOW_CYCLES, l);
135152
device.WriteRegister(BreakoutOutputClock.DELAY_CYCLES, delayTicks);
136153

137-
var deviceInfo = new BreakoutOutputClockDeviceInfo(device, DeviceType,
138-
new BreakoutOutputClockParameters(baseFreqHz / (h + l), 100 * h / periodTicks, delaySeconds, h + l, h, delayTicks));
154+
var deviceInfo = new BreakoutOutputClockDeviceInfo(device, DeviceType,
155+
new(baseFreqHz / (h + l), 100 * h / periodTicks, delaySeconds, h + l, h, l, delayTicks));
139156

140157
var shutdown = Disposable.Create(() =>
141158
{
@@ -175,20 +192,24 @@ public NameConverter()
175192
/// <summary>
176193
/// Hardware-verified output clock parameters.
177194
/// </summary>
178-
/// <param name="FrequencyHz">Gets the exact clock frequency as actualized by the clock synthesizer in
195+
/// <param name="Frequency">Gets the exact clock frequency as actualized by the clock synthesizer in
179196
/// Hz.</param>
180-
/// <param name="DutyCyclePercent">Gets the exact clock duty cycle as actualized by the clock synthesizer
197+
/// <param name="DutyCycle">Gets the exact clock duty cycle as actualized by the clock synthesizer
181198
/// in percent.</param>
182-
/// <param name="DelaySeconds">Gets the exact clock delay as actualized by the clock synthesizer in
199+
/// <param name="Delay">Gets the exact clock delay as actualized by the clock synthesizer in
183200
/// seconds.</param>
184201
/// <param name="PeriodTicks">Gets the exact clock period as actualized by the clock synthesizer in units
185202
/// of ticks of the of the <see cref="ContextTask.AcquisitionClockHz">Acquisition Clock</see>.</param>
186-
/// <param name="HighTicks">Gets the exact clock high time as actualized by the clock synthesizer in units
187-
/// of ticks of the of the <see cref="ContextTask.AcquisitionClockHz">Acquisition Clock</see>.</param>
203+
/// <param name="HighTicks">Gets the exact clock high time per period as actualized by the clock
204+
/// synthesizer in units of ticks of the of the <see cref="ContextTask.AcquisitionClockHz">Acquisition
205+
/// Clock</see>.</param>
206+
/// <param name="LowTicks">Gets the exact clock low time per period as actualized by the clock synthesizer
207+
/// in units of ticks of the of the <see cref="ContextTask.AcquisitionClockHz">Acquisition
208+
/// Clock</see>.</param>
188209
/// <param name="DelayTicks">Gets the exact clock delay as actualized by the clock synthesizer in units of
189210
/// ticks of the of the <see cref="ContextTask.AcquisitionClockHz">Acquisition Clock</see>.</param>
190-
public readonly record struct BreakoutOutputClockParameters(double FrequencyHz,
191-
double DutyCyclePercent, double DelaySeconds, uint PeriodTicks, uint HighTicks, uint DelayTicks);
211+
public readonly record struct BreakoutOutputClockParameters(double Frequency,
212+
double DutyCycle, double Delay, uint PeriodTicks, uint HighTicks, uint LowTicks, uint DelayTicks);
192213

193214
class BreakoutOutputClockDeviceInfo : DeviceInfo
194215
{
@@ -198,6 +219,6 @@ public BreakoutOutputClockDeviceInfo(DeviceContext device, Type deviceType, Brea
198219
Parameters = parameters;
199220
}
200221

201-
public BreakoutOutputClockParameters Parameters { get; }
222+
public BreakoutOutputClockParameters Parameters { get; }
202223
}
203224
}

0 commit comments

Comments
 (0)