88namespace 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