Files
2026-04-17 14:55:32 -04:00

13 KiB
Raw Permalink Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/TiltMIF/CRC16.cs
DataPRO/TiltMIF/Tilt_MIF.cs
2026-04-16T03:45:24.803223+00:00 Qwen/Qwen3-Coder-Next-FP8 1 e84d6b3eeba2c51d

Documentation: TiltMIF Module

1. Purpose

This module provides data structures and utilities for reading, writing, and manipulating MIF (Memory Information Format) data files used by the Tilt sensor system. It defines the CRC16 static class for computing CRC-16 checksums using the CCITT polynomial (0xA001), and the Tilt_MIF class which encapsulates the full binary layout of a MIF file—including core sensor calibration data (e.g., temperature, tilt sensor coefficients, offsets, ranges), configuration metadata (e.g., system ID, location, axis labeling, mount offsets), and associated CRC validation fields. The module supports both minimal (128-byte) and extended (256-byte) MIF formats, enabling serialization to and from binary and XML representations.

2. Public Interface

CRC16 Class (Static)

  • public static ushort ComputeChecksum(byte[] bytes)
    Computes the CRC-16 checksum of the input bytes using a precomputed lookup table initialized with polynomial 0xA001. Returns a 16-bit unsigned integer checksum.

Tilt_MIF Class

Properties (Core MIF Fields)

  • public DateTime TimeStamp { get; set; }
    Timestamp of the last operation (e.g., XML write). Set by WriteXML.

  • public string SystemName { get; set; }
    Machine name at time of XML write. Set by WriteXML.

  • public string UserName { get; set; }
    Current user name at time of XML write. Set by WriteXML.

  • public string BuildVersion { get; set; }
    Assembly version string (format major.minor.build) at time of XML write. Set by WriteXML.

  • public uint MIFVersion { get; set; }
    MIF file format version (stored as uint in binary layout).

  • public string SerialNumber { get; set; }
    10-character serial number, padded with nulls and trimmed on read/write.

  • public ushort HardwareConfiguration { get; set; }
    Hardware configuration flags (16-bit unsigned integer).

  • public float TemperatureCF { get; set; }
    Temperature calibration factor.

  • public short TemperatureOffset { get; set; }
    Temperature calibration offset.

  • public float TiltSensorCF1, TiltSensorCF2, TiltSensorCF3 { get; set; }
    Tilt sensor calibration factors for axes 13.

  • public short TiltSensorOffset1, TiltSensorOffset2, TiltSensorOffset3 { get; set; }
    Tilt sensor offsets for axes 13.

  • public float TiltSensorRange1, TiltSensorRange2, TiltSensorRange3 { get; set; }
    Tilt sensor measurement ranges (degrees) for axes 13.

  • public float TiltCalibrationCF1 through TiltCalibrationCF18 { get; set; }
    18 tilt calibration coefficients (stored in _tiltCalibrations[0..17]).

  • public ushort MIF_CRC16 { get; set; }
    CRC-16 value read from or written to bytes 126127 of the MIF file.

  • public ushort ComputedCRC16 { get; set; }
    CRC-16 computed over bytes 0125 of the MIF file.

  • public bool ReadError { get; set; }
    Set to true if MIF CRC validation fails or MIF_CRC16 == 0 during deserialization.

Properties (Config MIF Fields, only present in 256-byte format)

  • public bool _hasConfig { get; set; } (private)
    Indicates whether the instance contains configuration data.

  • public ushort Config_CRC16 { get; set; }
    CRC-16 value read from or written to bytes 130131 of the 256-byte MIF file.

  • public ushort ComputedCRC16_Config { get; set; }
    CRC-16 computed over bytes 132255 of the 256-byte MIF file.

  • public bool ReadError_Config { get; set; }
    Set to true if config CRC validation fails during deserialization.

  • public string SystemID { get; set; }
    16-character system identifier, padded with nulls and trimmed.

  • public string Location { get; set; }
    16-character location string, padded with nulls and trimmed.

  • public float Tolerance { get; set; } = 2
    Default tolerance value (degrees).

  • public bool ArmChecklist { get; set; }
    Bit 0 of _configBits[0].

  • public bool InvertAxis1, InvertAxis2, InvertAxis3 { get; set; }
    Bits 13 of _configBits[0].

  • public byte AxisToIgnore { get; set; }
    Bits 01 of _configBits[1] (02, mapped to Axis enum).

  • public Axis AxisLabel1, AxisLabel2, AxisLabel3 { get; set; }
    Encoded axis labels (X/Y/Z) for each physical axis, stored in _configBits[1] bits 27.

  • public float MountOffsetAxis1, MountOffsetAxis2, MountOffsetAxis3 { get; set; }
    Mounting offsets (degrees) for axes 13.

  • public float TargetAngleAxis1, TargetAngleAxis2, TargetAngleAxis3 { get; set; }
    Target angles (degrees) for axes 13.

  • public short PreEventADCAxis1, PreEventADCAxis2, PreEventADCAxis3 { get; set; }
    Pre-event ADC thresholds for axes 13.

  • public short PostEventADCAxis1, PostEventADCAxis2, PostEventADCAxis3 { get; set; }
    Post-event ADC thresholds for axes 13.

Nested Types

  • public enum MIFAttributes
    Enum of 30 core MIF attributes (e.g., MIFVersion, SerialNumber, TiltCalibrationCF1, etc.).

  • public class MIFAttribute
    Holds a MIFAttributes key and its string representation (MIFValue).

  • public enum ConfigAttributes
    Enum of 22 configuration attributes (e.g., SystemID, Location, AxisLabel1, etc.).

  • public class ConfigAttribute
    Holds a ConfigAttributes key and its string representation (ConfigValue).

  • public enum Axis
    X = 0, Y = 1, Z = 2.

Public Methods

  • public List<MIFAttribute> GetTiltAttributes()
    Returns a list of all MIFAttributes with their string values (via GetMIFAttribute).

  • public Dictionary<string, object> GetTiltAttributeDictionary()
    Returns a dictionary mapping MIFAttributes.ToString() to their actual values.

  • public void SetMIFAttribute(MIFAttributes attribute, string newValue)
    Parses newValue and assigns it to the corresponding property (e.g., ushort.Parse, float.Parse, short.Parse, or string copy for SerialNumber). Throws on parse failure.

  • public object GetMIFAttribute(MIFAttributes attribute)
    Returns the current value of the specified attribute (boxed), or null if unknown.

  • public List<ConfigAttribute> GetTiltConfigAttributes()
    Returns a list of all ConfigAttributes with string values.

  • public Dictionary<string, object> GetTiltConfigAttributeDictionary()
    Returns a dictionary mapping ConfigAttributes.ToString() to their actual values.

  • public void SetConfigAttribute(ConfigAttributes attribute, string newValue)
    Parses newValue and assigns it to the corresponding config property. Supports bool.Parse, float.Parse, byte.Parse, short.Parse, and Enum.Parse for Axis.

  • public object GetConfigAttribute(ConfigAttributes attribute)
    Returns the current value of the specified config attribute (boxed), or null if unknown.

  • public double[] GetTiltCalibrations()
    Returns the 18 calibration coefficients as double[].

  • public void SetTiltCalibrations(float[] calibrations)
    Sets _tiltCalibrations from a float[]. Throws InvalidDataException if length ≠ 18.

  • public void SetTiltCalibrations(double[] calibrations)
    Overload that converts double[] to float[] before calling the above.

  • public byte[] GetBytes()
    Serializes the instance to a byte array. For 128-byte MIF: writes header, sensor data, reserved, then CRC. For 256-byte MIF: appends config section (system ID, location, tolerance, config bits, offsets, angles, ADC thresholds, reserved bytes) and its CRC. Uses Encoding.UTF8 for strings.

  • public void WriteXML(FileStream file)
    Serializes the instance to XML using XmlSerializer. Sets TimeStamp, SystemName, UserName, and BuildVersion before writing. Closes the FileStream in finally.

  • public string GetVersionString()
    Returns assembly version as "major.minor.build" (e.g., "1.2.0003"), or "N/A" on exception.

Static Fields

  • public static int MIF_BYTE_LENGTH = 128
    Length of minimal MIF file.

  • public static int MIF_CONFIG_BYTE_LENGTH = 256
    Length of extended MIF file (with config section).

Constructors

  • public Tilt_MIF()
    Default constructor; _hasConfig = false.

  • public Tilt_MIF(bool hasConfig)
    Sets _hasConfig to hasConfig.

  • public Tilt_MIF(byte[] mifBytes)
    Deserializes from binary. Validates CRCs for both MIF and config sections (if present). Sets ReadError or ReadError_Config on mismatch. Reads fields in order: MIFVersion, _serialNumber, HardwareConfiguration, TemperatureCF, TemperatureOffset, tilt sensor arrays, calibrations, reserved, CRC16, then config section (if length = 256).

3. Invariants

  • CRC Validation:

    • For 128-byte MIF: MIF_CRC16 must equal ComputedCRC16 (computed over bytes 0125). If MIF_CRC16 == 0, ReadError is set.
    • For 256-byte MIF: Config_CRC16 must equal ComputedCRC16_Config (computed over bytes 132255). If mismatch, ReadError_Config is set.
  • String Fields:

    • SerialNumber, SystemID, Location are fixed-width (10, 16, 16 chars respectively), padded with nulls and trimmed on read/write.
  • Array Sizes:

    • _tiltSensorCF, _tiltSensorOffset, _tiltSensorRange, _mountOffset, _targetAngle, _preEventADC, _postEventADC each have exactly 3 elements.
    • _tiltCalibrations has exactly 18 elements (TILTCAL_COUNT = 18).
    • _configBits has exactly 2 bytes.
  • Binary Layout:

    • MIF section is always 128 bytes. Config section (if present) is 128 bytes (bytes 128255), with CRC at offset 128+2 = 130.
    • CRCs are stored in little-endian format.
  • CRC Polynomial:

    • Always uses polynomial 0xA001 (reversed from 0x8005) for CCITT CRC-16.

4. Dependencies

Dependencies of this module:

  • System (core runtime)
  • System.Collections.Generic
  • System.IO
  • System.Linq
  • System.Text
  • System.Xml.Serialization (used in WriteXML)

Dependencies on this module:

  • Not specified in source, but Tilt_MIF is likely used by:
    • File I/O components (to read/write .mif files)
    • UI or configuration tools (to inspect/edit attributes)
    • Sensor calibration or validation pipelines

5. Gotchas

  • String Padding Behavior:
    SerialNumber, SystemID, and Location are stored as fixed-length char arrays (char[10], char[16]). On set, value.ToCharArray().CopyTo(...) truncates if value.Length > array.Length. On get, nulls are replaced with spaces and trimmed—so "ABC\0\0" becomes "ABC".

  • Config CRC Validation Logic:
    ComputedCRC16_Config is computed over bytes after the MIF sections CRC (i.e., bytes 132255), not including the config CRC itself. This is correct for CRC-16, but easy to misread.

  • PostEventADCAxis2/3 Bug in SetConfigAttribute:
    In SetConfigAttribute, the cases for PostEventADCAxis2 and PostEventADCAxis3 incorrectly assign to PostEventADCAxis1:

    case ConfigAttributes.PostEventADCAxis2:
        PostEventADCAxis1 = short.Parse(newValue); // ❌ Should be PostEventADCAxis2
    case ConfigAttributes.PostEventADCAxis3:
        PostEventADCAxis1 = short.Parse(newValue); // ❌ Should be PostEventADCAxis3
    

    This is likely a copy-paste error.

  • GetVersionString Fallback:
    Returns "N/A" on any exception (e.g., missing assembly metadata), which may mask issues.

  • No Explicit Endianness Handling:
    Uses BitConverter (assumes little-endian, standard on .NET Core/.NET 5+ on most platforms), but this may break on big-endian systems.

  • MIF_CRC16 == 0 Check:
    ReadError is set if MIF_CRC16 == 0, even if ComputedCRC16 == 0. This may be overly strict if zero is a valid (though unlikely) checksum.

  • GetBytes() Uses UTF-8 for Strings:
    Encoding.UTF8.GetBytes(...) is used for SerialNumber, SystemID, Location. This is safe for ASCII, but non-ASCII characters will expand beyond 1 char = 1 byte, potentially corrupting fixed-length fields.

  • No Bounds Checking in SetTiltCalibrations:
    SetTiltCalibrations(float[]) throws InvalidDataException only on length mismatch, not on null.

  • _reservedU16 and _reservedConfigBytes:
    Reserved fields are read/written but never exposed or validated. Changes to layout may break compatibility.

  • GetTiltCalibrations() Returns double[]:
    Converts float values to double, losing precision unnecessarily if caller expects float.

  • WriteXML Closes Stream:
    WriteXML closes the FileStream in finally, which may be unexpected if the caller intends to reuse the stream.

  • No Thread Safety:
    Static _table in CRC16 is read-only after static constructor, but instance fields in Tilt_MIF are not thread-safe.

  • AxisToIgnore Range Not Validated:
    AxisToIgnore accepts any byte, but only values 02 (or 3 for “none”) are meaningful. No validation is performed.

  • Config_CRC16 Validation Skipped on Mismatch:
    If Config_CRC16 != ComputedCRC16_Config, ReadError_Config is set but parsing continues (fields like _systemID may be uninitialized or stale).