333 lines
15 KiB
Markdown
333 lines
15 KiB
Markdown
|
|
---
|
||
|
|
source_files:
|
||
|
|
- DataPRO/IService/Classes/TDAS Service/TDAS Service.cs
|
||
|
|
- DataPRO/IService/Classes/TDAS Service/Public.cs
|
||
|
|
- DataPRO/IService/Classes/TDAS Service/TriggerCheck.cs
|
||
|
|
generated_at: "2026-04-16T03:58:51.683058+00:00"
|
||
|
|
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||
|
|
schema_version: 1
|
||
|
|
sha256: "7b8b4e6a57d3d900"
|
||
|
|
---
|
||
|
|
|
||
|
|
# TDAS Service Module Documentation
|
||
|
|
|
||
|
|
## 1. Purpose
|
||
|
|
|
||
|
|
The `TDAS<T>` class is a core service implementation for the TDAS (Time-Domain Acquisition System) hardware family, providing a unified interface across multiple connection types (Ethernet, Serial) and hardware variants (G5, Rack, SIM, TOM, LabRack). It implements multiple interface contracts (`IDASCommunication`, `IConfigurationActions`, `IDiagnosticsActions`, `ITriggerCheckActions`, `IRealTimeActions`, `IArmActions`, `IDownloadActions`) to manage configuration, diagnostics, arming, triggering, real-time data streaming, and event downloading. The class acts as a bridge between high-level application logic and low-level hardware commands, encapsulating device-specific behavior (e.g., G5 vs. non-G5 modules) and maintaining runtime state (e.g., arming status, recording flags, diagnostic results). It inherits from `Communication<T>` and uses asynchronous workers via `ThreadPool.QueueUserWorkItem` for long-running operations, with callback-based progress and result reporting.
|
||
|
|
|
||
|
|
## 2. Public Interface
|
||
|
|
|
||
|
|
### Core Properties
|
||
|
|
|
||
|
|
- **`bool IsEthernetDistributor()`**
|
||
|
|
Returns `false`. Indicates this instance is not an Ethernet distributor.
|
||
|
|
|
||
|
|
- **`bool IsSlice6Distributor()`**
|
||
|
|
Returns `false`. Indicates this instance is not a Slice6 distributor.
|
||
|
|
|
||
|
|
- **`bool IsBattery()`**
|
||
|
|
Returns `false`. Indicates this instance is not a battery-powered device.
|
||
|
|
|
||
|
|
- **`bool IsTSRAIR()`**
|
||
|
|
Returns `false`. Indicates this instance is not a TSRAIR device.
|
||
|
|
|
||
|
|
- **`bool IsSlice6Air()`**
|
||
|
|
Returns `false`. Indicates this instance is not a Slice6 Air device.
|
||
|
|
|
||
|
|
- **`bool IsSlice6AirTc()`**
|
||
|
|
Returns `false`. Indicates this instance is not a Slice6 Air TC device.
|
||
|
|
|
||
|
|
- **`bool IsScheduleEventCountSupported()`**
|
||
|
|
Returns `false`. Schedule event counting is not supported.
|
||
|
|
|
||
|
|
- **`HardwareTypes GetHardwareType()`**
|
||
|
|
Determines hardware type based on `SerialNumber` prefix:
|
||
|
|
- `"5M"` → `G5INDUMMY` or `G5VDS` (depending on `G5Mode`)
|
||
|
|
- `"DR"` → `TDAS_Pro_Rack`
|
||
|
|
- `"SM"` → `SIM`
|
||
|
|
- `"TOM"` → `TOM`
|
||
|
|
- `"LR"` → `TDAS_LabRack`
|
||
|
|
- Otherwise → `TDAS_Pro_Rack` (fallback)
|
||
|
|
|
||
|
|
- **`string SerialNumber`** *(inherited from `ICommunication`, overridden)*
|
||
|
|
Device serial number used for identification and equality comparison.
|
||
|
|
|
||
|
|
- **`bool StartRecord`**
|
||
|
|
Gets/sets whether recording has been started (protected setter).
|
||
|
|
|
||
|
|
- **`float InputLowVoltage`, `InputMediumVoltage`, `InputHighVoltage`**
|
||
|
|
Input voltage thresholds.
|
||
|
|
|
||
|
|
- **`float BatteryLowVoltage`, `BatteryMediumVoltage`, `BatteryHighVoltage`**
|
||
|
|
Battery voltage thresholds.
|
||
|
|
|
||
|
|
- **`double MinimumValidInputVoltage`, `MaximumValidInputVoltage`**
|
||
|
|
Valid input voltage range.
|
||
|
|
|
||
|
|
- **`double MinimumValidBatteryVoltage`, `MaximumValidBatteryVoltage`**
|
||
|
|
Valid battery voltage range.
|
||
|
|
|
||
|
|
- **`bool CheckAAF(float rate)`**
|
||
|
|
Returns `true`. Anti-aliasing filter validation is not implemented for TDAS.
|
||
|
|
|
||
|
|
- **`ulong GetPhaseShiftSamples(uint ModuleIndex, double ActualSampleRate, uint HardwareAAF, ulong originalT0)`**
|
||
|
|
Returns `0`. Phase shift is not known for TDAS modules.
|
||
|
|
|
||
|
|
### Configuration
|
||
|
|
|
||
|
|
- **`IConfigurationData ConfigData { get; set; }`**
|
||
|
|
Holds configuration data for the device.
|
||
|
|
|
||
|
|
### Diagnostics
|
||
|
|
|
||
|
|
- **`IDiagnosticActions[] ChannelDiagnostics { get; set; }`**
|
||
|
|
Diagnostic actions per channel.
|
||
|
|
|
||
|
|
- **`void SetChannelDiagnosticActions(IDiagnosticActions[] actions, bool setInDb = true)`**
|
||
|
|
Sets channel diagnostic actions.
|
||
|
|
|
||
|
|
- **`IDiagnosticResult[] ChannelDiagnosticsResults { get; set; }`**
|
||
|
|
Diagnostic results per channel.
|
||
|
|
|
||
|
|
- **`void ClearChannelDiagnosticsResults(bool bClearDb = true)`**
|
||
|
|
Clears diagnostic results.
|
||
|
|
|
||
|
|
- **`void SetChannelDiagnosticsResults(IDiagnosticResult[] results, bool setInDb)`**
|
||
|
|
Sets diagnostic results.
|
||
|
|
|
||
|
|
- **`IBaseInputValues BaseInput { get; set; }`**
|
||
|
|
Base input values for diagnostics.
|
||
|
|
|
||
|
|
- **`IOptimizationValues OptimizationValues { get; set; }`**
|
||
|
|
Optimization values for diagnostics.
|
||
|
|
|
||
|
|
- **`IDictionary<InputClockSource, bool> DASClockSyncStatus { get; set; }`**
|
||
|
|
Clock synchronization status per source.
|
||
|
|
|
||
|
|
- **`bool ClockSyncInUTC { get; set; }`**
|
||
|
|
Whether clock sync uses UTC.
|
||
|
|
|
||
|
|
- **`ClockSyncProfile DASClockSyncProfile { get; set; }`**
|
||
|
|
Clock sync profile.
|
||
|
|
|
||
|
|
- **`byte PTPDomainID { get; set; }`**
|
||
|
|
PTP domain ID.
|
||
|
|
|
||
|
|
- **`IArmCheckActions ArmCheckActions { get; set; }`**
|
||
|
|
Arm check actions.
|
||
|
|
|
||
|
|
- **`IArmCheckResults ArmCheckResults { get; set; }`**
|
||
|
|
Arm check results.
|
||
|
|
|
||
|
|
### Trigger Check
|
||
|
|
|
||
|
|
- **`void ITriggerCheckActions.PreStartTriggerCheck(ServiceCallback callback, object userData)`**
|
||
|
|
No-op; immediately calls `callback` with success.
|
||
|
|
|
||
|
|
- **`void ITriggerCheckActions.PostStartTriggerCheck(ServiceCallback callback, object userData)`**
|
||
|
|
No-op; immediately calls `callback` with success.
|
||
|
|
|
||
|
|
- **`void ITriggerCheckActions.StartTriggerCheck(ServiceCallback callback, object userData)`**
|
||
|
|
Initiates trigger check asynchronously via `LaunchAsyncWorker`. Executes `AsyncStartTriggerCheck`.
|
||
|
|
|
||
|
|
- **`void ITriggerCheckActions.DoTriggerCheck(ServiceCallback callback, object userData)`**
|
||
|
|
Performs trigger check asynchronously via `LaunchAsyncWorker`. Executes `AsyncDoTriggerCheck`.
|
||
|
|
|
||
|
|
- **`void ITriggerCheckActions.DoStartCheck(ServiceCallback callback, object userData)`**
|
||
|
|
Performs start check asynchronously via `LaunchAsyncWorker`. Executes `AsyncDoStartCheck`.
|
||
|
|
|
||
|
|
- **`void ITriggerCheckActions.DoTriggerCheckSync()`**
|
||
|
|
Throws `NotImplementedException` with message: `"DoTriggerCheckSync is not implemented for TDAS"`.
|
||
|
|
|
||
|
|
- **`void ITriggerCheckActions.CancelTriggerCheck(ServiceCallback callback, object userData)`**
|
||
|
|
Cancels trigger check asynchronously via `LaunchAsyncWorker`. Executes `AsyncCancelTriggerCheck`.
|
||
|
|
|
||
|
|
### Arming
|
||
|
|
|
||
|
|
- **`bool GetIsInArm()`**
|
||
|
|
Returns `DASArmStatus?.IsArmed ?? false`.
|
||
|
|
|
||
|
|
- **`bool GetIsInRealtime()`**
|
||
|
|
Returns `DASArmStatus?.IsInRealtime ?? false`.
|
||
|
|
|
||
|
|
- **`bool GetIsStreaming()`**
|
||
|
|
Returns `false`. Does not query hardware; only returns a flag.
|
||
|
|
|
||
|
|
- **`void SetInArm(bool WriteToDb)`**
|
||
|
|
Sets `DASArmStatus.IsArmed = true`, optionally writes to DB.
|
||
|
|
|
||
|
|
- **`void SetInRealtime(bool WriteToDb, bool ExitRealtimeIfPossible)`**
|
||
|
|
Sets `DASArmStatus.IsInRealtime = true`, optionally writes to DB.
|
||
|
|
|
||
|
|
- **`IArmStatusData DASArmStatus { get; set; }`**
|
||
|
|
Current arming status.
|
||
|
|
|
||
|
|
- **`void SetDASArmStatus(IArmStatusData status, bool bSetInDb)`**
|
||
|
|
Sets arming status and optionally writes to DB.
|
||
|
|
|
||
|
|
- **`void SetDASArmStatus()`**
|
||
|
|
Sets current `DASArmStatus` to DB.
|
||
|
|
|
||
|
|
- **`DFConstantsAndEnums.CommandStatus AutoArmStatus { get; set; }`**
|
||
|
|
Status of auto-arming.
|
||
|
|
|
||
|
|
### Downloading
|
||
|
|
|
||
|
|
- **`IDownloadRequest WhatToDownload { get; set; }`**
|
||
|
|
Request specifying what to download.
|
||
|
|
|
||
|
|
- **`void SetWhatToDownload(IDownloadRequest request, bool bSetInDb = true)`**
|
||
|
|
Sets download request.
|
||
|
|
|
||
|
|
- **`IDownloadReport EventInfo { get; set; }`**
|
||
|
|
Event download report.
|
||
|
|
|
||
|
|
- **`void SetEventInfo(IDownloadReport eventInfo, bool bSetInDb = true)`**
|
||
|
|
Sets event info.
|
||
|
|
|
||
|
|
- **`bool[] EventDownloadedStatus { get; set; }`**
|
||
|
|
Download status per event.
|
||
|
|
|
||
|
|
- **`void SetEventDownloadStatus(bool[] status, bool storeInDb = true)`**
|
||
|
|
Sets event download status.
|
||
|
|
|
||
|
|
- **`Guid[] EventGuids { get; set; }`**
|
||
|
|
GUIDs for events.
|
||
|
|
|
||
|
|
- **`void SetEventGuids(Guid[] guids, bool storeInDb = true)`**
|
||
|
|
Sets event GUIDs.
|
||
|
|
|
||
|
|
- **`uint[] IDownload.ExtendedFaultFlags1 { get; set; }`**
|
||
|
|
Extended fault flags (explicit interface).
|
||
|
|
|
||
|
|
- **`uint[] IDownload.ExtendedFaultFlags2 { get; set; }`**
|
||
|
|
Extended fault flags (explicit interface).
|
||
|
|
|
||
|
|
- **`uint[] IDownload.ExtendedFaultFlags3 { get; set; }`**
|
||
|
|
Extended fault flags (explicit interface).
|
||
|
|
|
||
|
|
- **`uint[] IDownload.ExtendedFaultFlags4 { get; set; }`**
|
||
|
|
Extended fault flags (explicit interface).
|
||
|
|
|
||
|
|
- **`void IDownload.SetExtendedFaultFlags(uint[][] flags)`**
|
||
|
|
Sets extended fault flags.
|
||
|
|
|
||
|
|
- **`ushort[] FaultFlags { get; set; }`**
|
||
|
|
Fault flags.
|
||
|
|
|
||
|
|
- **`void SetEventFaultFlags(ushort[] flags, bool storeInDb = true)`**
|
||
|
|
Sets event fault flags.
|
||
|
|
|
||
|
|
- **`byte[] ArmAttempts { get; set; }`**
|
||
|
|
Arm attempt counts.
|
||
|
|
|
||
|
|
- **`void SetEventArmAttemps(byte[] armAttempts, bool storeInDb = true)`**
|
||
|
|
Sets event arm attempts.
|
||
|
|
|
||
|
|
### Information
|
||
|
|
|
||
|
|
- **`new IInfoResult DASInfo { get; set; }`**
|
||
|
|
Device information (hides inherited `ICommunication.DASInfo`).
|
||
|
|
|
||
|
|
- **`void SetDASInfo(IInfoResult dasInfo, bool bSetInDb = true)`**
|
||
|
|
Sets device info.
|
||
|
|
|
||
|
|
- **`void SetDASInfo()`**
|
||
|
|
Sets device info (no DB write).
|
||
|
|
|
||
|
|
### Utility
|
||
|
|
|
||
|
|
- **`int NumberOfConfiguredChannels()`**
|
||
|
|
Returns `ConfigData?.NumberOfConfiguredChannels() ?? 0`.
|
||
|
|
|
||
|
|
- **`int NumberOfChannels()`**
|
||
|
|
Returns `ConfigData?.NumberOfChannels() ?? 0`.
|
||
|
|
|
||
|
|
- **`int CompareTo(IDASCommunication das)`**
|
||
|
|
Compares `SerialNumber` lexicographically.
|
||
|
|
|
||
|
|
- **`bool DiagnosticsHasBeenRun { get; set; }`**
|
||
|
|
Whether diagnostics have been run.
|
||
|
|
|
||
|
|
- **`bool ConfigureHasBeenRun { get; set; }`**
|
||
|
|
Whether configuration has been run.
|
||
|
|
|
||
|
|
- **`override string ToString()`**
|
||
|
|
Returns `SerialNumber` or `"Unknown DAS"`.
|
||
|
|
|
||
|
|
- **`override bool Equals(object right)`**
|
||
|
|
Compares `SerialNumber` for equality (null-safe).
|
||
|
|
|
||
|
|
- **`override int GetHashCode()`**
|
||
|
|
Returns hash of `SerialNumber` or `0`.
|
||
|
|
|
||
|
|
### Async Helper Classes
|
||
|
|
|
||
|
|
- **`class TDASDownloadServiceAsyncInfo`**
|
||
|
|
Holds `TDASServiceAsyncInfo info` and `TDASServiceSetupInfo setupInfo`.
|
||
|
|
|
||
|
|
- **`class TDASServiceQueryConfigAsyncInfo : TDASServiceAsyncInfo`**
|
||
|
|
Extends `TDASServiceAsyncInfo` with `bool ReadIds` property.
|
||
|
|
|
||
|
|
- **`class TDASServiceAsyncInfo`**
|
||
|
|
Base async info class with:
|
||
|
|
- `ServiceCallback callback`, `object userData`, `object functionData`
|
||
|
|
- Methods: `Error(string, Exception)`, `Progress(int)`, `NewData(...)`, `Success()`, `Cancel()`
|
||
|
|
|
||
|
|
### Subclasses for Connection Types
|
||
|
|
|
||
|
|
- **`class EthernetTDAS : TDAS<EthernetConnection>`**
|
||
|
|
TDAS using Ethernet connection.
|
||
|
|
|
||
|
|
- **`class SerialTDAS : TDAS<SerialConnection>`**
|
||
|
|
TDAS using serial connection.
|
||
|
|
|
||
|
|
## 3. Invariants
|
||
|
|
|
||
|
|
- **Connection Requirement**: All async operations (`StartTriggerCheck`, `DoTriggerCheck`, etc.) require `Connected == true`; otherwise, `NotConnectedException` is thrown.
|
||
|
|
- **Hardware Type Determination**: `GetHardwareType()` relies solely on `SerialNumber` prefix; invalid prefixes default to `TDAS_Pro_Rack`.
|
||
|
|
- **Arming State**: `DASArmStatus` must be initialized before use in arming/triggering methods; if `null`, a new `ArmStatus` is created and initialized.
|
||
|
|
- **Module Iteration**: Trigger check operations iterate over `DASInfo.Modules`, skipping `EMPTYBANK` modules and applying G5-specific logic when `IsG5()` is true.
|
||
|
|
- **G5 Module Handling**: For G5 devices (`SerialNumber.StartsWith("5M")`), only module index `0` is processed in trigger checks (other modules skipped).
|
||
|
|
- **Phase Shift**: `GetPhaseShiftSamples` always returns `0`; no phase shift is applied.
|
||
|
|
- **Equality**: Two `TDAS<T>` instances are equal if their `SerialNumber` values are equal (null/empty handled).
|
||
|
|
- **Async Callback Safety**: All `TDASServiceAsyncInfo` callback methods (`Error`, `Success`, etc.) wrap callback invocations in `try/catch` to prevent unhandled exceptions from propagating.
|
||
|
|
|
||
|
|
## 4. Dependencies
|
||
|
|
|
||
|
|
### Internal Dependencies (from source):
|
||
|
|
- **`Communication<T>`**: Base class providing core communication functionality.
|
||
|
|
- **`DTS.Common.ICommunication`**: Defines `ICommunication<T>`, `IInfoResult`, `IDownload`, etc.
|
||
|
|
- **`DTS.Common.Interface.Connection`**: Defines `IConnection` (generic type constraint `T : IConnection, new()`).
|
||
|
|
- **`DTS.Common.DASResource`**: Provides `Strings` (localized error messages).
|
||
|
|
- **`DTS.Common.Utilities.Logging`**: Provides `APILogger`.
|
||
|
|
- **`DTS.DASLib.Command.SLICE`**: Used in `TriggerCheck.cs` for `Command.TDAS.*` classes (e.g., `TestTrigger`, `QuerySerialNumber`, `TestAll`).
|
||
|
|
- **`DTS.Common.Interface.DASFactory.*`**: Multiple interfaces (`IDiagnosticsActions`, `IConfigurationActions`, `IArmActions`, `IDownloadActions`, `ITriggerCheckActions`, `IArmStatusData`, `IDownloadRequest`, `IDownloadReport`, `IDiagnosticActions`, `IDiagnosticResult`, `IBaseInputValues`, `IOptimizationValues`, `IArmCheckActions`, `IArmCheckResults`, `IInfoResult`, `IConfigurationData`).
|
||
|
|
- **`DTS.Common.Enums.*`**: Enums `HardwareTypes`, `DFConstantsAndEnums` (including `CommandStatus`, `ModuleType`, `VoltageStatusColor`, `ExcitationStatus`), `InputClockSource`, `ClockSyncProfile`.
|
||
|
|
- **`DTS.DASLib.Service.Classes.Diagnostics`**: Provides `DiagnosticsActions`, `DiagnosticsResultActions`.
|
||
|
|
|
||
|
|
### External Dependencies:
|
||
|
|
- **`System`**: Core types (`System.Collections.Generic`, `System.Threading`, `System.Windows.Forms`).
|
||
|
|
- **`DTS.Common.SerialConnection`**: For `SerialConnection` type.
|
||
|
|
|
||
|
|
### Inferred Usage:
|
||
|
|
- **Consumers**: Likely used by higher-level UI or orchestration layers (e.g., `DataPRO` application) to manage TDAS hardware.
|
||
|
|
- **Dependents**: Classes implementing `IDASCommunication` or consuming `TDAS<T>` instances (e.g., configuration managers, diagnostic tools, download services).
|
||
|
|
|
||
|
|
## 5. Gotchas
|
||
|
|
|
||
|
|
- **`DoTriggerCheckSync` Not Implemented**: The method `ITriggerCheckActions.DoTriggerCheckSync()` throws `NotImplementedException` with a comment indicating it was intentionally left unimplemented for TDAS due to minimal impact of the original issue (ECM event line check). Using this method will crash at runtime.
|
||
|
|
- **`IsG5()` Not Defined**: The method `IsG5()` is used in `TriggerCheck.cs` but is not defined in the provided source. It must be defined elsewhere (e.g., in `Communication<T>` or a partial class).
|
||
|
|
- **`G5Mode` Property**: Used in `GetHardwareType()` but not defined in the provided source. Must be defined elsewhere.
|
||
|
|
- **`Connected` Property**: Used in `LaunchAsyncWorker` and `CallSyncMethod` but not defined in the provided source. Must be defined in `Communication<T>`.
|
||
|
|
- **`ServiceCallback` and `ServiceCallbackData`**: Types used for async callbacks but not defined in the provided source. Their structure (e.g., `CallbackStatus` enum, `AddSampleData` overloads) is inferred from usage.
|
||
|
|
- **`TDASServiceSetupInfo` Type**: Referenced in `TDASDownloadServiceAsyncInfo` but not defined in the provided source.
|
||
|
|
- **`IsG5()` Assumption**: The trigger check logic assumes `IsG5()` returns `true` for `"5M"` serials, but this is not explicitly stated.
|
||
|
|
- **G5 Module Indexing**: In `AsyncStartTriggerCheck` and `AsyncCancelTriggerCheck`, G5 devices only process module index `0` (break after first non-empty module), but this is not documented in comments.
|
||
|
|
- **`GetIsStreaming()` Always Returns `false`**: Despite the comment, it does not track streaming state dynamically.
|
||
|
|
- **`SetInRealtime` Ignores `ExitRealtimeIfPossible`**: The parameter `ExitRealtimeIfPossible` is unused in the implementation.
|
||
|
|
- **`SetEventArmAttemps` Typo**: Method name has typo (`SetEventArmAttemps` instead of `SetEventArmAttempts`).
|
||
|
|
- **`TDASServiceAsyncInfo.NewData` Overloads**: Multiple overloads exist for `NewData`, but the `IList<short[][]>` overload hardcodes `sequenceNumber = 0` for all samples.
|
||
|
|
- **`Equals`/`GetHashCode` on Null `SerialNumber`**: Two devices with `null`/empty `SerialNumber` are considered equal, which may be unintended.
|
||
|
|
- **No-Op Trigger Check Pre/Post**: `PreStartTriggerCheck` and `PostStartTriggerCheck` do nothing—consumers may expect actual logic here.
|
||
|
|
- **`StartRecord` Protected Setter**: Only settable internally; external code must use `SetInArm`/`SetInRealtime` to influence state.
|