/// <summary> /// Returns the max allowed CDM Undershoot as a percentage to be within the JS-002 specification /// </summary> /// <param name="signedCDMVoltage">The sign value of the CDM pulse waveform</param> /// <param name="isLargeTarget">A value indicating whether the CDM target is large or not (if not, then it is small)</param> /// <param name="oscilloscopeIsHighBandwidth">A value indicating whether the oscilloscope is high bandwidth (6GHz+) or not</param> /// <returns>The max allowed CDM Undershoot as a percentage to be within ESDA/JEDEC joint specification</returns> public static double UndershootMaxPercent(double signedCDMVoltage, bool isLargeTarget, bool oscilloscopeIsHighBandwidth) { CDMJS002WaveformCharacteristicsSet set = CDMJS002WaveformCharacteristics.GenerateSetForCDMVoltageAndCharacteristics( signedCDMVoltage, isLargeTarget, oscilloscopeIsHighBandwidth); return(set.UndershootMaxPercent); }
/// <summary> /// Returns the max allowed CDM Rise Time to be within JS-002 specification /// </summary> /// <param name="signedCDMVoltage">The sign value of the CDM pulse waveform</param> /// <param name="isLargeTarget">A value indicating whether the CDM target is large or not (if not, then it is small)</param> /// <param name="oscilloscopeIsHighBandwidth">A value indicating whether the oscilloscope is high bandwidth (6GHz+) or not</param> /// <returns>The max allowed CDM Rise Time to be within JS-002 specification</returns> public static double RiseTimeMax(double signedCDMVoltage, bool isLargeTarget, bool oscilloscopeIsHighBandwidth) { CDMJS002WaveformCharacteristicsSet set = CDMJS002WaveformCharacteristics.GenerateSetForCDMVoltageAndCharacteristics( signedCDMVoltage, isLargeTarget, oscilloscopeIsHighBandwidth); return(set.RiseTimeMax); }
/// <summary> /// Returns the nominal (Item1), min (Item2), and max (Item3) allowed CDM Full Width at Half Maximum to be within the JS-002 specification /// </summary> /// <param name="signedCDMVoltage">The sign value of the CDM pulse waveform</param> /// <param name="isLargeTarget">A value indicating whether the CDM target is large or not (if not, then it is small)</param> /// <param name="oscilloscopeIsHighBandwidth">A value indicating whether the oscilloscope is high bandwidth (6GHz+) or not</param> /// <returns>The nominal (Item1), min (Item2), and max (Item3) allowed CDM Full Width at Half Maximum to be within the JS-002 specification</returns> public static Tuple <double, double, double> FullWidthHalfMaxNominalMinMax(double signedCDMVoltage, bool isLargeTarget, bool oscilloscopeIsHighBandwidth) { CDMJS002WaveformCharacteristicsSet set = CDMJS002WaveformCharacteristics.GenerateSetForCDMVoltageAndCharacteristics( signedCDMVoltage, isLargeTarget, oscilloscopeIsHighBandwidth); return(new Tuple <double, double, double>( DoubleRangeExtensions.CenterOfRange(set.FullWidthAtHalfMaximum.Item1, set.FullWidthAtHalfMaximum.Item2), set.FullWidthAtHalfMaximum.Item1, set.FullWidthAtHalfMaximum.Item2)); }
/// <summary> /// Generates a new set for the CDM voltage, interpolated from the JS-002 specification. /// </summary> /// <param name="cdmVoltage">The voltage of the CDM pulse waveform (polarity is ignored, absolute value will be used)</param> /// <param name="isLargeTarget">A value indicating whether the CDM target is large or not (if not, then it is small)</param> /// <param name="oscilloscopeIsHighBandwidth">A value indicating whether the oscilloscope is high bandwidth (6GHz+) or not</param> /// <returns>A new set for the CDM voltage, interpolated from the JS-002 specification</returns> private static CDMJS002WaveformCharacteristicsSet GenerateSetForCDMVoltageAndCharacteristics(double cdmVoltage, bool isLargeTarget, bool oscilloscopeIsHighBandwidth) { double absCDMVoltage = System.Math.Abs(cdmVoltage); List <CDMJS002WaveformCharacteristicsSet> possibleSets = (from set in CDMJS002WaveformCharacteristics.characteristicSets where set.IsLargeTarget == isLargeTarget && set.IsHighBandwidth == oscilloscopeIsHighBandwidth select set).ToList(); if (possibleSets.Any(set => set.TestCondition == absCDMVoltage)) { // If the voltage is an exact match to a set, use it return(possibleSets.First(set => set.TestCondition == absCDMVoltage).Clone()); } else { // The voltage isn't an exact match to the table, so interpolate it CDMJS002WaveformCharacteristicsSet below = null; CDMJS002WaveformCharacteristicsSet above = null; // Try to find the closest sets that are below and above the Test Condition voltage foreach (CDMJS002WaveformCharacteristicsSet set in possibleSets) { if (set.TestCondition < absCDMVoltage) { if (below == null || below.TestCondition < set.TestCondition) { below = set; } } else { if (above == null || above.TestCondition > set.TestCondition) { above = set; } } } if (below != null && above != null) { // Interpolate between the below and above table entries double percentWithinRange = DoubleRangeExtensions.PercentWithinRange(absCDMVoltage, above.TestCondition, below.TestCondition); // Only the Peak Current varies between different Test Conditions. // All other properties are constant for a given target size and bandwidth. Tuple <double, double> interpolatedPeakCurrent = new Tuple <double, double>( DoubleRangeExtensions.EquivalentValueInNewRange(percentWithinRange, 1, 0, above.PeakCurrent.Item1, below.PeakCurrent.Item1), DoubleRangeExtensions.EquivalentValueInNewRange(percentWithinRange, 1, 0, above.PeakCurrent.Item2, below.PeakCurrent.Item2)); return(new CDMJS002WaveformCharacteristicsSet() { IsHighBandwidth = below.IsHighBandwidth, IsLargeTarget = below.IsLargeTarget, TestCondition = absCDMVoltage, PeakCurrent = interpolatedPeakCurrent, RiseTimeMax = below.RiseTimeMax, FullWidthAtHalfMaximum = new Tuple <double, double>(below.FullWidthAtHalfMaximum.Item1, below.FullWidthAtHalfMaximum.Item2), UndershootMaxPercent = below.UndershootMaxPercent, }); } else if (below != null) { // The CDM voltage is higher than the highest table entry, so scale the largest one double multiplier = absCDMVoltage / below.TestCondition; // Only the Peak Current varies between different Test Conditions. // All other properties are constant for a given target size and bandwidth. Tuple <double, double> scaledPeakCurrent = new Tuple <double, double>( below.PeakCurrent.Item1 * multiplier, below.PeakCurrent.Item2 * multiplier); return(new CDMJS002WaveformCharacteristicsSet() { IsHighBandwidth = below.IsHighBandwidth, IsLargeTarget = below.IsLargeTarget, TestCondition = absCDMVoltage, PeakCurrent = scaledPeakCurrent, RiseTimeMax = below.RiseTimeMax, FullWidthAtHalfMaximum = new Tuple <double, double>(below.FullWidthAtHalfMaximum.Item1, below.FullWidthAtHalfMaximum.Item2), UndershootMaxPercent = below.UndershootMaxPercent, }); } else if (above != null) { // The CDM voltage is lower than the lowest table entry, so scale the smallest one double multiplier = absCDMVoltage / above.TestCondition; // Only the Peak Current varies between different Test Conditions. // All other properties are constant for a given target size and bandwidth. Tuple <double, double> scaledPeakCurrent = new Tuple <double, double>( above.PeakCurrent.Item1 * multiplier, above.PeakCurrent.Item2 * multiplier); return(new CDMJS002WaveformCharacteristicsSet() { IsHighBandwidth = above.IsHighBandwidth, IsLargeTarget = above.IsLargeTarget, TestCondition = absCDMVoltage, PeakCurrent = scaledPeakCurrent, RiseTimeMax = above.RiseTimeMax, FullWidthAtHalfMaximum = new Tuple <double, double>(above.FullWidthAtHalfMaximum.Item1, above.FullWidthAtHalfMaximum.Item2), UndershootMaxPercent = above.UndershootMaxPercent, }); } else { throw new InvalidOperationException("Finding table entries for the CDM voltage " + absCDMVoltage + " failed."); } } }