using ExternalCalibration; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using Testrong.Core.Common; using Testrong.Core.Model.ACTiming; using Testrong.Core.Model.ChannelMap; using Testrong.Core.Model.Dps; using Testrong.Core.Model.Enums; using Testrong.Core.Model.Pattern; using Testrong.Core.Model.Ppmu; using Testrong.Core.Model.Relay; using Testrong.Core.Primitives; using Testrong.Core.Primitives.Extend; using Testrong.Core.Primitives.TestrongSystem; namespace Testrong.User.Program { /// /// ALL BOARDS /// public enum TestVersion { Board_1K_FT, Board_1K_CP, Board_2K_FT, Board_2K_CP, Board_Ppmu_CP, Board_Ppmu_FT, KM_2 } /// /// Test Parameters /// public class TestParaSet { public int delayMs; public int avgTimes; public double samDelay; } public class TestInfoSet { public string chType; public string Mode; public List Range; public List Channel; } public class Json { public int Version { get; set; } public bool Default { get; set; } public List PMU_FVMV { get; set; } public List PMU_FVMI { get; set; } public List PMU_FIMV { get; set; } public List PMU_FZMV { get; set; } public List DPS_FVMV { get; set; } public List DPS_FVMI { get; set; } public List DPS_FIMV { get; set; } } public class UserProgram : TestrongCode { //-----global Parameters----- #region 路径定义 const string EXT_CAL_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\ExtCal\\"; const string EXT_CAL_MV_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\ExtCal_bak\\"; const string EXT_CAL_HISTORY_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\ExtCal_History\\"; const string EXT_CAL_INIT_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\Init_Files\\"; const string EXT_CAL_FREQ_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\Ext_Freq\\"; const string EXT_CAL_FREQ_HISTORY_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\Ext_FreqHistory\\"; const string EXT_CAL_INITVALUE_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\DPSPPMUParam\\"; const string DOWN_INITVALUE_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\DownInitValue\\"; const string EXT_CAL_BOARDINFO_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\DeliverInspection\\BoardInfo\\"; const string CAL_COMPFILE_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\ExtInstrumentCalRecord\\CalResult\\"; const string CAL_PRECHECK_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\ExtInstrumentCalRecord\\PreCheck\\"; const string CAL_POSTCHECK_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\ExtInstrumentCalRecord\\PostCheck\\"; const string RINT_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\RintCal\\"; const string RINT_COMPFILE_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\RintCal\\CalResult\\"; const string RINT_FILE_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\RintCal\\PMUR\\"; const string RINT_PRECHECK_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\RintCal\\PreCheck\\"; const string RINT_POSTCHECK_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\RintCal\\PostCheck\\"; const string RINT_FAILLOG_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\RintCal\\FailResult\\"; const string RETEST_LOG_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\ExtInstrumentCalRecord\\FailLog.csv"; const string CONFIG_JSON_PATH = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\Init_Files\\config.json"; const string METADATA_PATH = EXT_CAL_PATH + "metadata" + ".csv"; #endregion #region FVMV readonly Dictionary avgDelays_fvmv_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 40, avgTimes = 64, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, }; readonly Dictionary avgDelays_fvmv_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 40, avgTimes = 64, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"1A", new TestParaSet{delayMs = 30, avgTimes = 128, samDelay = 100 } }, }; #endregion #region FZMV readonly Dictionary avgDelays_fzmv_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 30, avgTimes = 64, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 10, avgTimes = 64, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 10, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 10, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 10, avgTimes = 64, samDelay = 100 } }, }; #endregion #region FIMV PMU readonly Dictionary avgDelays_1kft_fimv_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 60, avgTimes = 128, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 100 } }, }; readonly Dictionary avgDelays_1kcp_fimv_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 60, avgTimes = 128, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 100 } }, }; readonly Dictionary avgDelays_2kft_fimv_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 60, avgTimes = 128, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 30, avgTimes = 128, samDelay = 100 } }, }; readonly Dictionary avgDelays_ppmucp_fimv_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 60, avgTimes = 255, samDelay = 300 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 128, samDelay = 300 } }, {"200uA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 300 } }, {"2mA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 100 } }, }; readonly Dictionary avgDelays_ppmuft_fimv_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 60, avgTimes = 255, samDelay = 300 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 128, samDelay = 300 } }, {"200uA", new TestParaSet{delayMs = 30, avgTimes = 64, samDelay = 300 } }, {"2mA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 100 } }, }; readonly Dictionary avgDelays_2km_fimv_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 60, avgTimes = 255, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 128, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 15, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 100 } }, }; #endregion #region FIMV DPS readonly Dictionary avgDelays_1kft_fimv_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 250, avgTimes = 64, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 70, avgTimes = 64, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, }; readonly Dictionary avgDelays_1kcp_fimv_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 250, avgTimes = 64, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 70, avgTimes = 64, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, }; readonly Dictionary avgDelays_2kft_fimv_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 250, avgTimes = 64, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 70, avgTimes = 32, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 15, avgTimes = 32, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 15, avgTimes = 32, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 15, avgTimes = 32, samDelay = 100 } }, }; readonly Dictionary avgDelays_ppmucp_fimv_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 250, avgTimes = 64, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 70, avgTimes = 64, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, }; readonly Dictionary avgDelays_ppmuft_fimv_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 250, avgTimes = 64, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 70, avgTimes = 64, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, }; readonly Dictionary avgDelays_2km_fimv_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 250, avgTimes = 64, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 70, avgTimes = 64, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 20, avgTimes = 64, samDelay = 100 } }, }; #endregion #region FVMI PMU readonly Dictionary avgDelays_1kft_fvmi_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 128, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 10, avgTimes = 64, samDelay = 100} }, {"2mA", new TestParaSet{delayMs = 10, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 10, avgTimes = 255, samDelay = 100 } }, }; readonly Dictionary avgDelays_1kcp_fvmi_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 200 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 128, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 10, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 10, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 10, avgTimes = 128, samDelay = 100 } }, }; readonly Dictionary avgDelays_2kft_fvmi_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 500 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 128, samDelay = 300 } }, {"200uA", new TestParaSet{delayMs = 10, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 10, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 10, avgTimes = 255, samDelay = 100 } }, }; readonly Dictionary avgDelays_ppmucp_fvmi_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 500 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 255, samDelay = 300 } }, {"200uA", new TestParaSet{delayMs = 10, avgTimes = 128, samDelay = 200 } }, {"2mA", new TestParaSet{delayMs = 30, avgTimes = 128, samDelay = 200 } }, {"60mA", new TestParaSet{delayMs = 10, avgTimes = 255, samDelay = 100 } }, }; readonly Dictionary avgDelays_ppmuft_fvmi_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 300 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 255, samDelay = 300 } }, {"200uA", new TestParaSet{delayMs = 10, avgTimes = 128, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 10, avgTimes = 128, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 10, avgTimes = 255, samDelay = 100 } }, }; readonly Dictionary avgDelays_2km_fvmi_pmu = new Dictionary() { {"5uA", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 500 } }, {"20uA", new TestParaSet{delayMs = 20, avgTimes = 255, samDelay = 500 } }, {"200uA", new TestParaSet{delayMs = 10, avgTimes = 128, samDelay = 500 } }, {"2mA", new TestParaSet{delayMs = 10, avgTimes = 128, samDelay = 500 } }, {"60mA", new TestParaSet{delayMs = 10, avgTimes = 255, samDelay = 500 } }, }; #endregion #region FVMI DPS readonly Dictionary avgDelays_1kft_fvmi_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 70, avgTimes = 255, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 30, avgTimes = 64, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 30, avgTimes = 64, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 100 } }, {"1A", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 100 } }, }; readonly Dictionary avgDelays_1kcp_fvmi_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 70, avgTimes = 255, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 70, avgTimes = 255, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 30, avgTimes = 64, samDelay = 100 } }, {"1A", new TestParaSet{delayMs = 30, avgTimes = 64, samDelay = 100 } }, }; readonly Dictionary avgDelays_2kft_fvmi_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 70, avgTimes = 255, samDelay = 200 } }, {"20uA", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 15, avgTimes = 128, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 15, avgTimes = 128, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 20, avgTimes = 128, samDelay = 100 } }, {"1A", new TestParaSet{delayMs = 20, avgTimes = 128, samDelay = 100 } }, }; readonly Dictionary avgDelays_ppmucp_fvmi_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 70, avgTimes = 255, samDelay = 100 } }, {"20uA", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 300 } }, {"200uA", new TestParaSet{delayMs = 50, avgTimes = 128, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 50, avgTimes = 128, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 200 } }, {"1A", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 200 } }, }; readonly Dictionary avgDelays_ppmuft_fvmi_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 70, avgTimes = 255, samDelay = 500 } }, {"20uA", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 500 } }, {"200uA", new TestParaSet{delayMs = 50, avgTimes = 128, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 50, avgTimes = 128, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 100 } }, {"1A", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 100 } }, }; readonly Dictionary avgDelays_2km_fvmi_dps = new Dictionary() { {"5uA", new TestParaSet{delayMs = 70, avgTimes = 255, samDelay = 500 } }, {"20uA", new TestParaSet{delayMs = 50, avgTimes = 255, samDelay = 100 } }, {"200uA", new TestParaSet{delayMs = 50, avgTimes = 128, samDelay = 100 } }, {"2mA", new TestParaSet{delayMs = 50, avgTimes = 128, samDelay = 100 } }, {"60mA", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 100 } }, {"1A", new TestParaSet{delayMs = 30, avgTimes = 255, samDelay = 500 } }, }; #endregion #region Variables Definition readonly List testRangesPmu = new List { "5uA", "20uA", "200uA", "2mA", "60mA" }; readonly List testRangesDps = new List { "5uA", "20uA", "200uA", "2mA", "60mA", "1A" }; readonly string[] FreqStr_Test = { "1M", "2M", "2.5M", "5M", "10M" }; readonly double[] FreqForce_Test = { 1000000, 2000000, 2500000, 5000000, 10000000 }; readonly Dictionary FreqInfo = new Dictionary() { {"0.625M", "NOR_Pattern_1" }, {"1M", "NOR_Pattern_1" }, {"2M", "NOR_Pattern_2"}, {"2.5M", "NOR_Pattern_2"}, {"5M", "NOR_Pattern_3"}, {"10M","NOR_Pattern_4"}, {"20M","NOR_Pattern_5"} }; readonly List testChannelDps_1K = new List() { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, }; readonly List testChannelDps_2K = new List() { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48, 49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64 }; public static class DpsPinConfig { public static readonly string[] allDpsPinNames_1K = { "DPS1","DPS2","DPS3","DPS4","DPS5","DPS6","DPS7","DPS8","DPS9","DPS10", "DPS11","DPS12","DPS13","DPS14","DPS15","DPS16","DPS17","DPS18","DPS19","DPS20", "DPS21","DPS22","DPS23","DPS24","DPS25","DPS26","DPS27","DPS28","DPS29","DPS30", "DPS31","DPS32" }; public static readonly string[] allDpsPinNames_2K = { "DPS1","DPS2","DPS3","DPS4","DPS5","DPS6","DPS7","DPS8","DPS9","DPS10", "DPS11","DPS12","DPS13","DPS14","DPS15","DPS16","DPS17","DPS18","DPS19","DPS20", "DPS21","DPS22","DPS23","DPS24","DPS25","DPS26","DPS27","DPS28","DPS29","DPS30", "DPS31","DPS32","DPS33","DPS34","DPS35","DPS36","DPS37","DPS38","DPS39","DPS40", "DPS41","DPS42","DPS43","DPS44","DPS45","DPS46","DPS47","DPS48","DPS49","DPS50", "DPS51","DPS52","DPS53","DPS54","DPS55","DPS56","DPS57","DPS58","DPS59","DPS60", "DPS61","DPS62","DPS63","DPS64" }; public static readonly Dictionary Select_DpsPin = new Dictionary() { { TestVersion.Board_1K_FT, allDpsPinNames_1K }, { TestVersion.Board_1K_CP, allDpsPinNames_1K }, { TestVersion.Board_2K_FT, allDpsPinNames_2K }, { TestVersion.Board_2K_CP, allDpsPinNames_2K }, { TestVersion.Board_Ppmu_CP, allDpsPinNames_1K }, { TestVersion.Board_Ppmu_FT, allDpsPinNames_1K }, { TestVersion.KM_2, allDpsPinNames_2K} }; } readonly Dictionary Select_IP = new Dictionary() { { TestVersion.Board_1K_FT, "192.168.100.110" }, { TestVersion.Board_1K_CP, "192.168.100.110" }, { TestVersion.Board_2K_FT, "192.168.100.10" }, { TestVersion.Board_2K_CP, "192.168.100.10" }, { TestVersion.Board_Ppmu_CP, "192.168.100.10" }, { TestVersion.Board_Ppmu_FT, "192.168.100.10" }, { TestVersion.KM_2, "192.168.100.10"} }; readonly Dictionary Select_Temp = new Dictionary() { { TestVersion.Board_1K_FT, 4 }, { TestVersion.Board_1K_CP, 4 }, { TestVersion.Board_Ppmu_CP, 4 }, { TestVersion.Board_Ppmu_FT, 4 }, { TestVersion.Board_2K_CP, 8 }, { TestVersion.Board_2K_FT, 8 }, { TestVersion.KM_2, 8} }; public static Dictionary Select_Version = new Dictionary() { {1, TestVersion.Board_1K_FT}, {2, TestVersion.Board_1K_CP}, {3, TestVersion.Board_2K_FT}, {4, TestVersion.Board_2K_CP}, {5, TestVersion.Board_Ppmu_FT}, {6, TestVersion.Board_Ppmu_CP}, {7, TestVersion.KM_2 } }; readonly Dictionary ModesPmu = new Dictionary() { {"FVMV",PpmuMode.FVMV},{"FVMI",PpmuMode.FVMI},{"FIMV",PpmuMode.FIMV}, {"FZMV",PpmuMode.FZMV} }; readonly Dictionary ModesDps = new Dictionary() { {"FVMV",DpsMode.FVMV},{"FVMI",DpsMode.FVMI},{"FIMV",DpsMode.FIMV} }; readonly Dictionary RangesPmu = new Dictionary() { {"5uA", PpmuIRange._5uA}, {"20uA", PpmuIRange._20uA}, {"200uA", PpmuIRange._200uA}, {"2mA", PpmuIRange._2mA}, {"60mA", PpmuIRange._60mA}, }; readonly Dictionary RangesDps = new Dictionary() { {"5uA", DpsIRange._5uA}, {"20uA", DpsIRange._20uA}, {"200uA", DpsIRange._200uA}, {"2mA", DpsIRange._2mA}, {"60mA", DpsIRange._60mA}, {"1A", DpsIRange._1A} }; readonly Dictionary DmmCurrRanges = new Dictionary() { {"5uA",0.000005},{"20uA",0.00002},{"200uA",0.0002},{"2mA",0.002},{"60mA",0.06},{"1A",1 } }; readonly Dictionary Rname = new Dictionary() { {"R1","5uA"},{"R2","20uA"},{"R3","200uA"},{"R4","2mA"},{"R5","60mA"},{"R6","1A"} }; readonly Dictionary FiRanges = new Dictionary() { {"5uA",0.000005},{"20uA",0.000015},{"200uA",0.0001},{"2mA",0.001},{"60mA",0.03} }; readonly double[] rLimit = { 50, 120, 110, 1, 1, 1 }; readonly double[] CurrScale = { -0.8, -0.5, 0, 0.5, 0.8 }; readonly Dictionary strRloadFvmi = new Dictionary() { {"5uA", "1M"}, {"20uA", "402K"}, {"200uA", "49.9K"}, {"2mA", "4.99K"}, {"60mA", "150"}, {"1A", "10"}, }; readonly Dictionary Rcut_MIFI = new Dictionary() { {"5uA", ExtCaliLoad.RC_RL13}, {"20uA", ExtCaliLoad.RC_RL12}, {"200uA", ExtCaliLoad.RC_RL10}, {"2mA", ExtCaliLoad.RC_RL8}, {"60mA", ExtCaliLoad.RC_RL5}, {"1A", ExtCaliLoad.RC_RL3}, }; readonly double VoltageInitialDefault = -7.5; readonly double VoltageStepDefault = 3.75; readonly double VoltageInitialDps1A = 1.5; readonly double VoltageStepDps1A = 0.75; readonly double VoltageInitialSet = -5; readonly double VoltageStepSet = 2.5; readonly double[] VoltageStep20uA = { 2.5, 2.5, 3.75, 3.75, 3.75 }; readonly int SampliCount = 5; readonly List TestInfo = new List(); readonly int port = 200; readonly string ksightConnStr = "GPIB1::22::INSTR"; readonly TestVersion SelectTestVersion = Select_Version[Readjson(CONFIG_JSON_PATH).Version]; const int ChannelCount = 256; readonly double[] rInt = new double[ChannelCount]; #endregion #region 函数定义 /// /// Read JSON From json_path /// /// The Path of JSON /// Json TYPE public static Json Readjson(string json_path) { Json get = new Json(); using (StreamReader sr = new StreamReader(json_path)) { string json = sr.ReadToEnd(); get = JsonConvert.DeserializeObject(json); } return get; } /// /// Metadata_handler, Write metadata.csv /// Also Prevents thread conflict /// /// File Handler, Should be Initialized ahead, /// Current Slot Number, /// Slot List, /// DNA Data from Zynq, /// info from ATE Software, /// choose from Header to Body| True=Header/False=Body, /// [OPTIONAL] Only need if init_Flag == False, Channel Type, Possible Value="PMU","DPS", "NULL"(Default), /// [OPTIONAL] Only need if init_Flag == False, Channel Number, Default = -1, /// [OPTIONAL] Only need if init_Flag == False, Test Mode, Possible Value="FVMV","FVMI","FIMV","FIMI","FZMV"(PMU Only), "NULL"(Default), /// [OPTIONAL] Only need if init_Flag == False,Resistance Load, Default = "NaN", /// [OPTIONAL] Only need if init_Flag == False,Range, Possible Value="5uA", "20uA", "200uA", "2mA", "60mA", "1A"(DPS Only), Default = "N/A", /// [OPTIONAL] Only need if init_Flag == False, CSV File Path, Default = "N/A", /// [OPTIONAL] Only need if init_Flag == False, CSV File Creation Time, Default = "N/A" public void Metadata_handler(StreamWriter swdata, int SlotNum, List slotList, string arm_dna, IFlowRunnerContext context, bool init_Flag, string Type = "NULL", int Channel = -1, string Mode = "NULL", string Rload = "NaN", string Range = "N/A", string filepath = "N/A", string filetime = "N/A") { //Are We Writing the header of MetaData? if (init_Flag == true) { //Each Slot has its own Thread //But We DON'T want to run in parallel in this case(Cali&Write file) //So We Should Check Which Slot We Are Running... if (SlotNum == slotList[0]) { swdata.WriteLine("Tester_Name,Board_Id,Slot_Ip,Stil_Version"); for (int w = 0; w < 12; w++)//修改为12SLOT { if (w == (slotList[0] - 1)) { swdata.WriteLine($"Slot{SlotNum},{arm_dna},{context.Communicator.ServerIP},V1.0.0"); } else { swdata.WriteLine($"Slot{(w + 1)}"); } } for (int i = 0; i < 1; i++) { swdata.WriteLine(); } swdata.Write("Slot_Dna,Channel_Type,Channel_No,Mode,R_Load,I_Range,V_Range,Meas_Range,File_Path,File_Time\n"); } else { int Cried = slotList.FindIndex(x => x.Equals(SlotNum)); while (true) { Thread.Sleep(1000); if (File.Exists(EXT_CAL_PATH + slotList[Cried - 1] + ".flag")) //Wait until previous thread flags completion { File.Delete(EXT_CAL_PATH + slotList[Cried - 1] + ".flag"); break; } } File.Move(METADATA_PATH, EXT_CAL_PATH + "metadata_temp" + ".csv"); StreamReader sr = new StreamReader(EXT_CAL_PATH + "metadata_temp" + ".csv", Encoding.UTF8); int line = 0; while (!sr.EndOfStream) { string tmp = sr.ReadLine(); if (line == slotList[Cried]) { swdata.WriteLine("Slot" + SlotNum + "," + arm_dna + "," + context.Communicator.ServerIP + "," + "V1.0.0"); } else { swdata.WriteLine(tmp); } line++; } sr.Close(); File.Delete(EXT_CAL_PATH + "metadata_temp" + ".csv"); } } //Now We Are Writing the body of the file else { swdata.Write($"{arm_dna},"); swdata.Write($"{Type},"); if (Type == "PMU") { swdata.Write($"{Channel},"); } else { swdata.Write($"PS{Channel},"); } swdata.Write($"{Mode},"); swdata.Write($"{Rload},"); swdata.Write($"{Range},"); swdata.Write("20V,"); swdata.Write("13V,"); swdata.Write($"{filepath},"); swdata.Write($"{filetime}\n"); swdata.Flush(); } } /// /// Move Folder to Bak/History /// /// Current Slot Number, /// Slot List, /// Path Selector, Possible Value="Freq","CAL_Single"(No Pre/Post),"CAL_Normal", /// [OPTIONAL] Only need if pathFlag =="CAL_Normal",PreCheck Flag, Default = false public void File_Mover(int SlotNum, List slotList, string pathFlag, bool isPreCheck = false) { string DateCode = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"); string WritePath; string BakPath; string HistoryPath; switch (pathFlag) { case "Freq": WritePath = EXT_CAL_FREQ_PATH; HistoryPath = EXT_CAL_FREQ_HISTORY_PATH; BakPath = "C:\\ProgramData\\Testrong\\ATE_Tester"; break; default: WritePath = EXT_CAL_PATH; HistoryPath = EXT_CAL_HISTORY_PATH; BakPath = EXT_CAL_MV_PATH; break; } try { if (SlotNum == slotList[0]) { if (pathFlag == "CAL_Normal") { if (isPreCheck == true) { EmptyDir(CAL_COMPFILE_PATH); ClearPrePostFile(CAL_PRECHECK_PATH); ClearPrePostFile(CAL_POSTCHECK_PATH); } else if (isPreCheck == false) { Thread.Sleep(1); } } if (Directory.Exists(BakPath)) { if (!Directory.Exists(HistoryPath)) { Directory.CreateDirectory(HistoryPath); } Directory.Move(BakPath, HistoryPath + DateCode); } if (Directory.Exists(WritePath)) { Directory.Move(WritePath, BakPath); } Directory.CreateDirectory(WritePath); } } catch (Exception ex) { LogRawText(ex.StackTrace); throw ex; } } /// /// Prevent thread run at the same time /// /// Current Slot Number, /// Slot List, /// Path Selector, Possible Value="Freq","CAL_Init","CAL","RINT","CAL_COM", public void SlotThreadLocker(int SlotNum, List slotList, string pathFlag) { string WritePath; switch (pathFlag) { case "Freq": WritePath = EXT_CAL_FREQ_PATH; break; case "CAL_Init": WritePath = EXT_CAL_INIT_PATH; break; case "RINT": WritePath = RINT_COMPFILE_PATH; break; case "CAL_COM": WritePath = CAL_COMPFILE_PATH; break; default: WritePath = EXT_CAL_PATH; break; } if (SlotNum < slotList[slotList.Count - 1]) { StreamWriter swSignal = new StreamWriter(WritePath + SlotNum + ".flag"); //Create file flagging end of current thread swSignal.WriteLine(); swSignal.Flush(); swSignal.Close(); } } private int GetPMUTempSensorIndex(int channel) { if ((channel >= 65 && channel <= 80) || (channel >= 97 && channel <= 112) || (channel >= 193 && channel <= 208) || (channel >= 241 && channel <= 256)) { return 0; } else if ((channel >= 1 && channel <= 16) || (channel >= 49 && channel <= 64) || (channel >= 129 && channel <= 144) || (channel >= 161 && channel <= 176)) { return 1; } else if ((channel >= 17 && channel <= 32) || (channel >= 33 && channel <= 48) || (channel >= 145 && channel <= 160) || (channel >= 177 && channel <= 192)) { return 2; } else if ((channel >= 81 && channel <= 96) || (channel >= 113 && channel <= 128) || (channel >= 209 && channel <= 224) || (channel >= 225 && channel <= 240)) { return 3; } else return -1; } private int GetDPSTempSensorIndex(int channel) { return ((channel - 1) / 4); } public int GetFileSize(string path) { System.IO.FileInfo fileInfo = null; try { fileInfo = new System.IO.FileInfo(path); } catch { return 0; } if (fileInfo != null && fileInfo.Exists) { return (int)System.Math.Ceiling(fileInfo.Length / 1024.0); } else { return 0; } } public void ClearPrePostFile(string DirPath) { System.IO.DirectoryInfo di = new DirectoryInfo(DirPath); foreach (FileInfo file in di.GetFiles()) { if (file.Name.EndsWith(".csv") && file.Name.IndexOf("FlowLog") == -1) { file.Delete(); } } } /// /// Delete Anything inside Folder /// /// public void EmptyDir(string DirPath) { System.IO.DirectoryInfo di = new DirectoryInfo(DirPath); foreach (FileInfo file in di.EnumerateFiles()) { file.Delete(); } ; } private string[] GetAllPmuPins() { string[] ans = new string[256]; for (int i = 0; i < ans.Length; i++) { ans[i] = "A" + (i < 9 ? "0" : "") + (i + 1); } return ans; } /// /// Get ATE Measure Result /// /// SiteInfo /// PinName /// double Measured Value private double GetATEChannelMeasure(List InfoList, string[] PinName) { double result = 0; foreach (SiteInfo si in InfoList) { bool flag = false; foreach (ChannelInfo ci in si.Channels) { if (ci.Name == PinName[0]) { flag = true; result = ci.Result; break; } } if (flag) break; } return result; } /// /// Get Rload /// Will Loop Measure 100 times,do average /// And measure 101th /// Then Compare the difference between them /// if Out-Of-Limit /// Will Try Again /// For INIFINATE Times /// /// DMM Handler /// DMM Measure Range /// Resistance Diff limit /// private double GetRloadValue(KeysightDMM3458A rdmm, double range, double limit) { double value = 0; while (true) { double sum = 0; for (int i = 0; i < 100; i++) { double r1 = rdmm.GetDmmMeasureData(KeysightDMM3458A.KeysightMeasMode.RES, 1, range); sum = sum + r1; } sum = sum / 100; double r2 = rdmm.GetDmmMeasureData(KeysightDMM3458A.KeysightMeasMode.RES, 1, range); if (Math.Abs(sum - r2) < limit) { value = r2; break; } } return value; } private void SortAsFileCreationTime(ref FileInfo[] arrFi) { Array.Sort(arrFi, delegate (FileInfo x, FileInfo y) { return x.CreationTime.CompareTo(y.CreationTime); } ); } public List> ReadRload(string ResFilePath) { Dictionary RlPmuFv = new Dictionary(); Dictionary RlPmuFi = new Dictionary(); Dictionary RlDpsFv = new Dictionary(); Dictionary RlDpsFi = new Dictionary(); List> RloadTuple = new List>(); int cnt1 = 0; StreamReader ResReader = new StreamReader(ResFilePath, Encoding.UTF8); while (!ResReader.EndOfStream) { string rtemp = ResReader.ReadLine(); string rname = rtemp.Split(',')[0]; string rvalue = rtemp.Split(',')[1]; rname = rname.Split('_')[1]; if (cnt1 < 5) { RlPmuFv.Add(Rname[rname], rvalue); RlPmuFi.Add(Rname[rname], rvalue); } else if (cnt1 < 11) { RlDpsFv.Add(Rname[rname], rvalue); if (cnt1 < 10) { RlDpsFi.Add(Rname[rname], rvalue); } } cnt1 = cnt1 + 1; } RloadTuple.Add(RlPmuFv); RloadTuple.Add(RlPmuFi); RloadTuple.Add(RlDpsFv); RloadTuple.Add(RlDpsFi); ResReader.Close(); return RloadTuple; } public double[,] ReadRext(string RextFilePath) { double[,] ExtBoard_Res = new double[256, 12]; int cnt2 = 0; StreamReader ExtResReader = new StreamReader(RextFilePath, Encoding.UTF8); while (!ExtResReader.EndOfStream) { string rstr = ExtResReader.ReadLine(); ExtBoard_Res[cnt2, 0] = Convert.ToDouble(rstr.Split(',')[0]); ExtBoard_Res[cnt2, 1] = Convert.ToDouble(rstr.Split(',')[1]); ExtBoard_Res[cnt2, 2] = Convert.ToDouble(rstr.Split(',')[2]); ExtBoard_Res[cnt2, 3] = Convert.ToDouble(rstr.Split(',')[3]); ExtBoard_Res[cnt2, 4] = Convert.ToDouble(rstr.Split(',')[4]); ExtBoard_Res[cnt2, 5] = Convert.ToDouble(rstr.Split(',')[5]); ExtBoard_Res[cnt2, 6] = Convert.ToDouble(rstr.Split(',')[6]); ExtBoard_Res[cnt2, 7] = Convert.ToDouble(rstr.Split(',')[7]); ExtBoard_Res[cnt2, 8] = Convert.ToDouble(rstr.Split(',')[8]); ExtBoard_Res[cnt2, 9] = Convert.ToDouble(rstr.Split(',')[9]); ExtBoard_Res[cnt2, 10] = Convert.ToDouble(rstr.Split(',')[10]); ExtBoard_Res[cnt2, 11] = Convert.ToDouble(rstr.Split(',')[11]); cnt2 = cnt2 + 1; } ExtResReader.Close(); return ExtBoard_Res; } public double[] ReadRint(string RintFilePath) { double[] IntBoard_Res = new double[256]; int cnt3 = 0; try { // 提前检查文件是否存在,避免深层构造器异常 if (!File.Exists(RintFilePath)) { throw new FileNotFoundException($"File not found: {RintFilePath}"); } using (var IntResReader = new StreamReader(RintFilePath, Encoding.UTF8)) { while (!IntResReader.EndOfStream) { string[] A = IntResReader.ReadLine().Split(' ', ':'); IntBoard_Res[cnt3] = Convert.ToDouble(A[4]); cnt3 = cnt3 + 1; } IntResReader.Close(); return IntBoard_Res; } } catch (Exception ex) { LogRawText(ex.StackTrace); // 调用日志记录方法 throw; // 重新抛出保留原始堆栈追踪 } } public List RangeTrans(List range) { Dictionary RangeMap = new Dictionary { {1,"5uA"}, {2,"20uA" }, {3,"200uA" }, {4,"2mA" }, {5,"60mA" }, {6,"1A" } }; List list = new List(); for (int i = 0; i < range.Count; i++) { list.Add(RangeMap[range[i]]); } return list; } public Dictionary ReadBackDmm(double[] data, List listCh) { Dictionary DmmDic = new Dictionary(); int dmmFlag = 0; while (dmmFlag < data.Length) { int number = dmmFlag / 5; int group = listCh[number]; double[] DmmMeasure = new double[5]; for (int readNum = dmmFlag; readNum < (number + 1) * 5; readNum++) { DmmMeasure[dmmFlag % 5] = data[readNum]; dmmFlag += 1; } DmmDic.Add(group, DmmMeasure); } return DmmDic; } /// /// Write Data To File, Need import StreamWriter and close FileHandler after using this func /// !!! If you want to Do CUSTOM format, add new case for contextFormat /// /// StreamWriter, Need to be initialized first /// Slot Number /// DNA Number /// DPS/PMU /// Channel Number(PMU:1-256, DPS:1-32/64) /// FVMV/FVMI/FIMV/FZMV(PMU Only) /// External Resistance Load /// Internal Resistance On the External Calibration Board /// Board Measurment Range(5uA; 20uA; 200uA; 2mA; 60mA; 1A(DPS Only)) /// ForceValue /// ATE Measure Value /// DMM Measure Value /// Temperature Value(May Not Available) /// [OPTIONAL] For custom CSV content /// [OPTIONAL] /// [OPTIONAL] public void WriteSingleFile(StreamWriter sw, int slot, string dna, string type, int channel, string mode, string rload, double[,] extR, string range, double[] ForceValue, double[] AteMeasure, double[] DmmMeasure, double[] TempValue, string contextFormat = "Normal", double[] customData = null, int SampliCount = 5) { switch (contextFormat) { case "Freq": sw.Write("Channel_No,Freq_Force,Freq_Measure\n"); for (int fCount = 0; fCount < SampliCount; fCount++) // 625K - 32M { for(int ch=0; ch fileset = new List(); for (int x = 0; x < arrFi.Length; x++) { if (arrFi[x].Name.Contains("Slot" + slot) == true) { fileset.Add(arrFi[x].Name); } } //get acc_min and acc_max double acc_min = 0; double acc_max = 0; for (int i = 0; i < fileset.Count; i++) { int count = 0; int line = 0; List data = new List(); List data_empty = new List(); StreamReader sr = new StreamReader(filepath + fileset[i], Encoding.UTF8); while (!sr.EndOfStream) { string rtemp = sr.ReadLine(); if (line > 0) { double rvalue = Convert.ToDouble(rtemp.Split(',')[2]); if (rvalue != -1) { data.Add(rvalue); count = count + 1; } else { data_empty.Add(rvalue); } } line = line + 1; } sr.Close(); string item = fileset[i]; string Drived = item.Split('_')[2]; Drived = Drived.Substring(0, Drived.Length - 5); if (data_empty.Count == 256) { sw.WriteLine($"{item.Substring(0, item.Length - 4)},{item[4]},{Drived},IO,{0},FALSE,"); } else { double max = data.Max(); double min = data.Min(); double value = Convert.ToDouble(Drived) * 1000000; acc_min = min / value; acc_max = max / value; string acc_flag = "FALSE"; double diff = Math.Abs(Math.Max(acc_min, acc_max) - 1); if ((diff < 0.005) && (count > failcount)) { acc_flag = "TRUE"; } sw.WriteLine($"{item.Substring(0, item.Length - 4)},{item[4]},{Drived},IO,{acc_max},{acc_flag},"); } data.Clear(); data_empty.Clear(); sw.Flush(); } } void ExternalCalibrationFreqCollect(IFlowRunnerContext context, TestVersion testVersion) { //config DMM53220A Keysight53220A FreqCounter53220A = new Keysight53220A(); ExternalCalibrationHandle extCaliHandle = new ExternalCalibrationHandle(); string addressFreq = "USB0::0x0957::0x1807::MY63100296::INSTR"; //config ExtCalibration Board string ExtConnStr = Select_IP[testVersion]; int ExtPort = 200; string DateCode = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"); //config Board var slotInfos = context.FlowCatalog.GetAll(); List slotList = new List(); for (int slotLen = 0; slotLen < slotInfos.Count; slotLen++) { if (slotInfos[slotLen].FirmwareVersion == "") { continue; } slotList.Add(slotInfos[slotLen].No); } byte[] armDnaPortCmd = new byte[2] { 14, 57 }; // command to read arm dna byte[] armDnaRaw = context.Communicator.Send(armDnaPortCmd); //send command armDnaRaw = armDnaRaw.Reverse().ToArray(); string arm_dna = BitConverter.ToUInt64(armDnaRaw, 0).ToString(); //convert hex dna to decimal int SlotNum = context.Communicator.SlotNo; //set channel number int[] ChannelPmu = new int[256]; for (int n = 0; n < 256; n++) { ChannelPmu[n] = n + 1; } int PmuChannelCount = 256; string[] FreqStr = FreqStr_Test; double[] FreqForce = FreqForce_Test; double[] Period = new double[50]; for (int i = 0; i < FreqStr.Length; i++) { string actimeing = $"{(1000000000 / FreqForce[i]):F2}"; Period[i] = Convert.ToDouble(actimeing); } //creat dir File_Mover(SlotNum: SlotNum, slotList: slotList, pathFlag: "Freq"); StreamWriter swResult; if (SlotNum == slotList[0]) { swResult = new StreamWriter(EXT_CAL_FREQ_PATH + "f_Result.csv", true, Encoding.UTF8); swResult.WriteLine("Test_Item,Slot_No,Drived_Frequency(MHz),Channel_Type,Accuracy_Measure,Validation_Result"); FreqCounter53220A.InitDMM53220A(addressFreq, Keysight53220A.KeysightMeasMode.FREQ); FreqCounter53220A.InitMeasure(); Thread.Sleep(100); FreqCounter53220A.GetDmm53220AMeasureData(); swResult.Close(); } else { int Cried = slotList.FindIndex(x => x.Equals(SlotNum)); while (true) { Thread.Sleep(1000); if (File.Exists(EXT_CAL_FREQ_PATH + slotList[Cried - 1] + ".flag")) //Wait until previous thread flags completion { File.Delete(EXT_CAL_FREQ_PATH + slotList[Cried - 1] + ".flag"); break; } } FreqCounter53220A.InitDMM53220A(addressFreq, Keysight53220A.KeysightMeasMode.FREQ); } Thread.Sleep(100); double[] customData = new double[2 * (FreqStr.Length + 1)]; for (int fCount = 0; fCount < FreqStr.Length; fCount++) // 625K - 32M { string FreqFileNmae = EXT_CAL_FREQ_PATH + "Slot" + SlotNum + "_" + "Freq" + "_" + FreqStr[fCount] + ".csv"; StreamWriter sw = new StreamWriter(FreqFileNmae, true, Encoding.UTF8); Thread.Sleep(10); string strPattern = FreqInfo[FreqStr[fCount]]; PATTERN.DCLevel.Set("level_5V"); ACTimingSetting aCTimingInfo = new ACTimingSetting { Period = Period[fCount], PinName = GetAllPmuPins(), FmtMode = FmtMode.RL, EdgeInfo = new EdgeInfo() { DriverOn = 0, DriverData = 0.3, DriverReturn = 0.8, Open = 0, Close = 0, CompareMode = CompareMode.Edge, } }; aCTimingInfo.Name = "TEST"; PATTERN.ACTiming.Execute(aCTimingInfo); ; int read_count = 3; for (int loopk = 0; loopk < PmuChannelCount; loopk++) { int ch = ChannelPmu[loopk]; extCaliHandle.SetPpmuExternalCalibration(ExtConnStr, ExtPort, SlotNum, ExternalCalibrationMode.Channel, ch, ExtCaliVI.V, ExtCaliLoad.no_load, 1); //@@rita,20240307 Thread.Sleep(500); string[] PmuPinName = { ("A" + (loopk < 9 ? "0" : "") + (loopk + 1)) }; RELAY.SwitchToDigitalCard(PmuPinName); Thread.Sleep(1); PATTERN.Burst(strPattern, PmuPinName, 10, false, true); Thread.Sleep(15); double[] readValues = new double[read_count];//read 3 times for (int j = 0; j < read_count; j++) { FreqCounter53220A.InitMeasure(); Thread.Sleep(50); readValues[j] = FreqCounter53220A.GetDmm53220AMeasureData(); } double freqValue = -1; for (int j = 0; j < read_count; j++) { if (Math.Abs(FreqForce[fCount] - readValues[j]) < 10000) { freqValue = readValues[j]; break; } } customData[2 * (fCount)] = FreqForce[fCount]; customData[2 * (fCount + 1)] = freqValue; sw.Flush(); } double[,] ZeroExtR = { { 0.0 , 0.0 , 0.0} }; double[] Zero=new double[1]; Zero[0] = 0; WriteSingleFile( sw:sw, slot:SlotNum, dna:arm_dna, type:"K7", channel: PmuChannelCount, mode:"Freq", rload:"0", extR: ZeroExtR, range:"NULL", ForceValue: Zero, AteMeasure: Zero, DmmMeasure: Zero, TempValue: Zero, contextFormat:"Freq", customData:customData, SampliCount: FreqStr.Length ); sw.Close(); } FreqCounter53220A.CloseDMM53220A(); swResult = new StreamWriter(EXT_CAL_FREQ_PATH + "f_Result.csv", true, Encoding.UTF8); FrequencyProcess(SlotNum, swResult, EXT_CAL_FREQ_PATH, 25); swResult.Close(); SlotThreadLocker(SlotNum: SlotNum, slotList: slotList, pathFlag: "Freq"); if (SlotNum == slotList[slotList.Count - 1]) { swResult.Close(); } } /// /// Reset Rint /// Empty Local Rint Folder and Files /// Put Initial Files into Zynq (Not only Rint,but also others) /// /// info from ATE Software void Rint_Reset(IFlowRunnerContext context) { var slotInfos = context.FlowCatalog.GetAll(); List slotList = new List(); for (int slotLen = 0; slotLen < slotInfos.Count; slotLen++) { if (slotInfos[slotLen].FirmwareVersion == "") { continue; } slotList.Add(slotInfos[slotLen].No); } byte[] armDnaPortCmd = new byte[2] { 14, 57 }; // command to read arm dna byte[] armDnaRaw = context.Communicator.Send(armDnaPortCmd); //send command armDnaRaw = armDnaRaw.Reverse().ToArray(); string arm_dna = BitConverter.ToUInt64(armDnaRaw, 0).ToString(); //convert hex dna to decimal int SlotNum = context.Communicator.SlotNo; if (SlotNum == slotList[0]) { if (Directory.Exists(RINT_PATH)) { EmptyDir(RINT_COMPFILE_PATH); EmptyDir(RINT_FILE_PATH); EmptyDir(RINT_PRECHECK_PATH); EmptyDir(RINT_POSTCHECK_PATH); EmptyDir(RINT_FAILLOG_PATH); } if (Directory.Exists(DOWN_INITVALUE_PATH)) { EmptyDir(DOWN_INITVALUE_PATH); } DelayHelper.Sleep(1); } else { int Cried = slotList.FindIndex(x => x.Equals(SlotNum)); while (true) { Thread.Sleep(1000); if (File.Exists(EXT_CAL_INIT_PATH + slotList[Cried - 1] + ".flag")) { File.Delete(EXT_CAL_INIT_PATH + slotList[Cried - 1] + ".flag"); break; } } } ExternalCalibrationHandle extCaliHandle = new ExternalCalibrationHandle(); int FileKb = 0; string initValueFile = EXT_CAL_INITVALUE_PATH + context.Communicator.ServerIP + "_" + context.Communicator.ServerPort + "_InitValue.csv"; string BoardInfoFile = EXT_CAL_BOARDINFO_PATH + context.Communicator.ServerIP + "_boardinfo.txt"; ReadTftp DownFile = new ReadTftp(); DownFile.DownloadFile(context.Communicator.ServerIP, DOWN_INITVALUE_PATH + context.Communicator.ServerIP + "_" + context.Communicator.ServerPort + "_InitValue.csv", ReadType.InitValue); FileKb = GetFileSize(DOWN_INITVALUE_PATH + context.Communicator.ServerIP + "_" + context.Communicator.ServerPort + "_InitValue.csv"); if (FileKb > 10) { Thread.Sleep(1); } else { if (File.Exists(EXT_CAL_INITVALUE_PATH + context.Communicator.ServerIP + "_" + context.Communicator.ServerPort + "_InitValue.csv")) { var isInitValueOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, initValueFile, FileType.InitValue); LogRawText($"InitValue Status: {isInitValueOK}"); } } if (File.Exists(BoardInfoFile)) { var isBoardInfoOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, BoardInfoFile, FileType.boardinfo); LogRawText($"BoardInfo Status: {isBoardInfoOK}"); } var isDnaUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, EXT_CAL_INIT_PATH + "Dna_init.csv", FileType.dna); LogRawText($"Dna Status: {isDnaUploadOK}"); Thread.Sleep(10); var isMVUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, EXT_CAL_INIT_PATH + "MV_init.csv", FileType.mv); LogRawText($"MV Status: {isMVUploadOK}"); Thread.Sleep(10); var isMIUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, EXT_CAL_INIT_PATH + "MI_init.csv", FileType.mi); LogRawText($"MI Status: {isMIUploadOK}"); Thread.Sleep(10); var isPmurUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, EXT_CAL_INIT_PATH + "Pmur_init.csv", FileType.pmu_r); LogRawText($"Pmu_r Status: {isPmurUploadOK}"); SlotThreadLocker(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL_Init"); } /// /// To Pre-Test Rint with External Calibration Board /// Mainly get FVMV data to Calibrate ForceV /// /// info from ATE Software /// void Rint_FVMV_2mA_Pre(IFlowRunnerContext context, TestVersion testVersion) { #region Init Config & Variables List ChannelDps = new List(); List ChannelPmu = new List(); for (int m = 0; m < 256; m++) { ChannelPmu.Add(m + 1); } var slotInfos = context.FlowCatalog.GetAll(); List slotList = new List(); for (int slotLen = 0; slotLen < slotInfos.Count; slotLen++) { if (slotInfos[slotLen].FirmwareVersion == "") { continue; } slotList.Add(slotInfos[slotLen].No); } //-----config Board----- byte[] armDnaPortCmd = new byte[2] { 14, 57 }; byte[] armDnaRaw = context.Communicator.Send(armDnaPortCmd); armDnaRaw = armDnaRaw.Reverse().ToArray(); string arm_dna = BitConverter.ToUInt64(armDnaRaw, 0).ToString(); int SlotNum = context.Communicator.SlotNo; double[,] ExtBoard_Res = ReadRext(EXT_CAL_INIT_PATH + "ExtBoardRes.csv"); //Folder Related File_Mover(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL_Single"); //-----Start Slot Number----- StreamWriter swdata; swdata = new StreamWriter(METADATA_PATH, true, Encoding.UTF8) { AutoFlush = true }; Metadata_handler( swdata: swdata, SlotNum: SlotNum, slotList: slotList, arm_dna: arm_dna, context: context, init_Flag: true ); #endregion #region Config DMM //-----config dmm3458A and ExtCalibrationBoard----- KeysightDMM3458A dmm = new KeysightDMM3458A(); ExternalCalibrationHandle extCaliHandle = new ExternalCalibrationHandle(); string extConnStr = Select_IP[testVersion]; int extPort = port; dmm.InitDMM(ksightConnStr); #endregion string filetime = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"); #region The Test for (int loopk = 0; loopk < 256; loopk++) { #region Test Config string[] PmuPinName = { ("A" + (ChannelPmu[loopk] < 10 ? "0" : "") + ChannelPmu[loopk]) }; RELAY.SwitchMode(RelayMode.Open); RELAY.SwitchToPPMU(PmuPinName); double ForceVoltage = VoltageInitialDefault; double VoltageStep = VoltageStepDefault; string filepath = "Slot" + SlotNum + "_PMU_" + "ch" + ChannelPmu[loopk] + "_" + "FVMV" + "_" + "Hi-Z" + "_" + "2mA" + ".csv"; string filename = EXT_CAL_PATH + filepath; int ch = ChannelPmu[loopk]; double[] AteMeasure = new double[SampliCount]; double[] ForceValue = new double[SampliCount]; double[] DMMValue = new double[SampliCount]; double[] TempValue = new double[SampliCount]; #endregion extCaliHandle.SetPpmuExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.Channel, ch, ExtCaliVI.V, ExtCaliLoad.no_load, 0);//change channel if (loopk == 0) { DelayHelper.Sleep(20); } #region Actual Test for (int p = 0; p < SampliCount; p++) { PPMU.Force(PmuPinName, ForceVoltage, PpmuMode.FVMV, PpmuIRange._2mA, VRange.Normal); Thread.Sleep(20); List siList = PPMU.Measure(PmuPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMV"), 128, 100); double chResult = GetATEChannelMeasure(siList, PmuPinName); double dmmRead = dmm.GetDmmMeasureData(KeysightDMM3458A.KeysightMeasMode.VOLT, 1, 7.5);//dmm 3458A read double[] readTemp = PPMU.ReadTemperature(); double chTemp = readTemp[GetPMUTempSensorIndex(ch)]; ForceValue[p] = ForceVoltage; AteMeasure[p] = chResult; DMMValue[p] = dmmRead; TempValue[p] = chTemp; ForceVoltage += VoltageStep; } #endregion PPMU.Force(PmuPinName, 0, PpmuMode.FVMV, PpmuIRange._2mA, VRange.Normal); #region File Writing StreamWriter sw = new StreamWriter(filename, true, Encoding.UTF8) { AutoFlush = true }; WriteSingleFile(sw: sw, slot: SlotNum, dna: arm_dna, type: "PMU", channel: ch, mode: "FVMV", rload: "Hi-Z", extR: ExtBoard_Res, range: "2mA", ForceValue: ForceValue, AteMeasure: AteMeasure, DmmMeasure: DMMValue, TempValue: TempValue); sw.Flush(); sw.Close(); Metadata_handler(swdata: swdata, SlotNum: SlotNum, slotList: slotList, arm_dna: arm_dna, context: context, init_Flag: false, Type: "PMU", Channel: ch, Mode: "FVMV", Rload: "Hi-Z", Range: "2mA", filepath: filepath, filetime: filetime); #endregion } #endregion SlotThreadLocker(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL"); swdata.Flush(); swdata.Close(); } /// /// Post-Test Rint with External Calibration Board /// Do FVMV Second time with MV Compensate /// Calculate Rint value and generate Pmu_r file /// /// info from ATE Software /// void Rint_FVMV_2mA_Post(IFlowRunnerContext context, TestVersion testVersion) { #region Init Config & Variables List ChannelDps = new List(); List ChannelPmu = new List(); //-----Select PreTest or ReTest----- for (int m = 0; m < 256; m++) { ChannelPmu.Add(m + 1); } //-----get all connect slot number----- var slotInfos = context.FlowCatalog.GetAll(); List slotList = new List(); for (int slotLen = 0; slotLen < slotInfos.Count; slotLen++) { if (slotInfos[slotLen].FirmwareVersion == "") { continue; } slotList.Add(slotInfos[slotLen].No); } //-----config Board----- byte[] armDnaPortCmd = new byte[2] { 14, 57 }; byte[] armDnaRaw = context.Communicator.Send(armDnaPortCmd); armDnaRaw = armDnaRaw.Reverse().ToArray(); string arm_dna = BitConverter.ToUInt64(armDnaRaw, 0).ToString(); int SlotNum = context.Communicator.SlotNo; //-----Move File To History----- File_Mover(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL_Single"); //-----Start Write MetaData----- StreamWriter swdata; swdata = new StreamWriter(METADATA_PATH, true, Encoding.UTF8) { AutoFlush = true }; Metadata_handler( swdata: swdata, SlotNum: SlotNum, slotList: slotList, arm_dna: arm_dna, context: context, init_Flag: true ); #endregion #region Config DMM //-----config dmm3458A and ExtCalibrationBoard----- KeysightDMM3458A dmm = new KeysightDMM3458A(); ExternalCalibrationHandle extCaliHandle = new ExternalCalibrationHandle(); string extConnStr = Select_IP[testVersion]; int extPort = port; dmm.InitDMM(ksightConnStr); #endregion //-----Read R File----- double[,] ExtBoard_Res = ReadRext(EXT_CAL_INIT_PATH + "ExtBoardRes.csv"); extCaliHandle.SetPpmuExternalCalibration(extConnStr, extPort, 1, ExternalCalibrationMode.Channel, 1, ExtCaliVI.V, ExtCaliLoad.RC_RL7, 0); //1kΩ double rload = GetRloadValue(dmm, 2000, 5); string filetime = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"); #region The Test for (int loopk = 0; loopk < 256; loopk++) { #region Test Config double ForceVoltage = -2; double VoltageStep = 1; string[] PmuPinName = { ("A" + (ChannelPmu[loopk] < 10 ? "0" : "") + ChannelPmu[loopk]) }; int ch = ChannelPmu[loopk]; double[] AteMeasure = new double[SampliCount]; double[] ForceValue = new double[SampliCount]; double[] DMMValue = new double[SampliCount]; double[] TempValue = new double[SampliCount]; RELAY.SwitchMode(RelayMode.Open); RELAY.SwitchToPPMU(PmuPinName); string filepath = "Slot" + SlotNum + "_PMU_" + "ch" + ChannelPmu[loopk] + "_" + "FVMV" + "_" + "Hi-Z" + "_" + "2mA" + ".csv"; string filename = EXT_CAL_PATH + filepath; #endregion extCaliHandle.SetPpmuExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.Channel, ch, ExtCaliVI.V, ExtCaliLoad.RC_RL7, 0);//change channel if (loopk == 0) { DelayHelper.Sleep(20); } #region Actual Test for (int p = 0; p < SampliCount; p++) { PPMU.Force(PmuPinName, ForceVoltage, PpmuMode.FVMV, PpmuIRange._2mA, VRange.Normal); Thread.Sleep(20); List siList = PPMU.Measure(PmuPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMV"), 128, 100); double chResult = GetATEChannelMeasure(siList, PmuPinName); double dmmRead = dmm.GetDmmMeasureData(KeysightDMM3458A.KeysightMeasMode.VOLT, 1, 7.5); double[] readTemp = PPMU.ReadTemperature(); double chTemp = readTemp[GetPMUTempSensorIndex(ch)]; ForceValue[p] = ForceVoltage; AteMeasure[p] = chResult; DMMValue[p] = dmmRead; TempValue[p] = chTemp; ForceVoltage += VoltageStep; } #endregion PPMU.Force(PmuPinName, 0, PpmuMode.FVMV, PpmuIRange._2mA, VRange.Normal); #region File Writing StreamWriter sw = new StreamWriter(filename, true, Encoding.UTF8) { AutoFlush = true }; WriteSingleFile(sw: sw, slot: SlotNum, dna: arm_dna, type: "PMU", channel: ch, mode: "FVMV", rload: rload.ToString(), extR: ExtBoard_Res, range: "2mA", ForceValue: ForceValue, AteMeasure: AteMeasure, DmmMeasure: DMMValue, TempValue: TempValue); sw.Flush(); sw.Close(); Metadata_handler(swdata: swdata, SlotNum: SlotNum, slotList: slotList, arm_dna: arm_dna, context: context, init_Flag: false, Type: "PMU", Channel: ch, Mode: "FVMV", Rload: rload.ToString(), Range: "2mA", filepath: filepath, filetime: filetime); #endregion } #endregion swdata.Flush(); swdata.Close(); Thread.Sleep(1000); #region Post Process #region File Process StreamReader metareader = new StreamReader(METADATA_PATH, Encoding.UTF8); List dnaip = new List(); List path = new List(); List datassingle = new List(); int cnnt = 0; while (!metareader.EndOfStream) { string str = metareader.ReadLine(); if (cnnt > 6) { if (str.Split(',')[0] == arm_dna) { path.Add(str); } } cnnt = cnnt + 1; } metareader.Close(); string pmurapth = EXT_CAL_PATH + context.Communicator.ServerIP + "_" + "Pmur" + ".txt"; StreamWriter Pmur = new StreamWriter(pmurapth, true); Pmur.AutoFlush = true; #endregion #region Rint Calculation for (int p = 0; p < path.Count; p++) { string dna = path[p].Split(',')[0]; string file = path[p].Split(',')[8]; StreamReader singlefile = new StreamReader(EXT_CAL_PATH + file, Encoding.UTF8); while (!singlefile.EndOfStream) { datassingle.Add(singlefile.ReadLine()); } double RL = Convert.ToDouble(datassingle[6].Split(',')[1]);//150 double rext = Convert.ToDouble(datassingle[8].Split(',')[1]); int ChannelNum = Convert.ToInt32(datassingle[4].Split(',')[1]); double res = 0; for (int linefile = 14; linefile < 19; linefile++) { if (linefile == 16) { continue; } double ateV = Convert.ToDouble(datassingle[linefile].Split(',')[1]); double voltage = Convert.ToDouble(datassingle[linefile].Split(',')[2]); double iii = voltage / RL; //??? double diff = ateV - voltage; double rrr = diff / iii; //??? res = res + (rrr - rext); //Rint? } res = res / 4; //Average string ChannelFormat; if (ChannelNum < 10) { ChannelFormat = "00" + Convert.ToString(ChannelNum); } else if ((ChannelNum >= 10) && (ChannelNum < 100)) { ChannelFormat = "0" + Convert.ToString(ChannelNum); } else { ChannelFormat = Convert.ToString(ChannelNum); } Pmur.WriteLine($"ch {ChannelFormat} : {res:F3}"); rInt[ChannelNum - 1] = res; //Put R_Int into array datassingle.Clear(); singlefile.Close(); } #endregion Pmur.Close(); #endregion #region Thread Lock SlotThreadLocker(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL"); #endregion } /// /// Use TFTP to upload DNA/MV file into Zynq /// /// info from ATE Software void Rint_DataUpload(IFlowRunnerContext context) { var slotInfos = context.FlowCatalog.GetAll(); List slotList = new List(); for (int slotLen = 0; slotLen < slotInfos.Count; slotLen++) { if (slotInfos[slotLen].FirmwareVersion == "") { continue; } slotList.Add(slotInfos[slotLen].No); } byte[] armDnaPortCmd = new byte[2] { 14, 57 }; // command to read arm dna byte[] armDnaRaw = context.Communicator.Send(armDnaPortCmd); //send command armDnaRaw = armDnaRaw.Reverse().ToArray(); string arm_dna = BitConverter.ToUInt64(armDnaRaw, 0).ToString(); //convert hex dna to decimal int SlotNum = context.Communicator.SlotNo; ExternalCalibrationHandle extCaliHandle = new ExternalCalibrationHandle(); if (SlotNum == slotList[0]) { DelayHelper.Sleep(1); } else { int Cried = slotList.FindIndex(x => x.Equals(SlotNum)); while (true) { Thread.Sleep(1000); if (File.Exists(RINT_COMPFILE_PATH + slotList[Cried - 1] + ".flag")) { File.Delete(RINT_COMPFILE_PATH + slotList[Cried - 1] + ".flag"); break; } } } Thread.Sleep(10); var isDnaUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, RINT_COMPFILE_PATH + "DNA_" + context.Communicator.ServerIP + ".csv", FileType.dna); LogRawText($"Dna Status: {isDnaUploadOK}"); Thread.Sleep(10); var isMVUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, RINT_COMPFILE_PATH + context.Communicator.ServerIP + "_MV.csv", FileType.mv); LogRawText($"MV Status: {isMVUploadOK}"); SlotThreadLocker(SlotNum: SlotNum, slotList: slotList, pathFlag: "RINT"); } /// /// Use TFTP to upload PMU_R(Rint) file into Zynq /// /// info from ATE Software void Pmur_Upload(IFlowRunnerContext context) { var slotInfos = context.FlowCatalog.GetAll(); List slotList = new List(); for (int slotLen = 0; slotLen < slotInfos.Count; slotLen++) { if (slotInfos[slotLen].FirmwareVersion == "") { continue; } slotList.Add(slotInfos[slotLen].No); } byte[] armDnaPortCmd = new byte[2] { 14, 57 }; // command to read arm dna byte[] armDnaRaw = context.Communicator.Send(armDnaPortCmd); //send command armDnaRaw = armDnaRaw.Reverse().ToArray(); string arm_dna = BitConverter.ToUInt64(armDnaRaw, 0).ToString(); //convert hex dna to decimal int SlotNum = context.Communicator.SlotNo; ExternalCalibrationHandle extCaliHandle = new ExternalCalibrationHandle(); if (SlotNum == slotList[0]) { DelayHelper.Sleep(1); } else { int Cried = slotList.FindIndex(x => x.Equals(SlotNum)); while (true) { Thread.Sleep(1000); if (File.Exists(RINT_FILE_PATH + slotList[Cried - 1] + ".flag")) { File.Delete(RINT_FILE_PATH + slotList[Cried - 1] + ".flag"); break; } } } Thread.Sleep(10); var isPmurUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, RINT_FILE_PATH + context.Communicator.ServerIP + "_Pmur.txt", FileType.pmu_r); LogRawText($"Pmur Status: {isPmurUploadOK}"); if (SlotNum < slotList[slotList.Count - 1]) { StreamWriter swSignal = new StreamWriter(RINT_FILE_PATH + SlotNum + ".flag"); swSignal.Flush(); swSignal.Close(); } } /// /// Put Initial Files into Zynq (MV MI DNA) /// /// info from ATE Software void ExternalCalibrationReset(IFlowRunnerContext context) { var slotInfos = context.FlowCatalog.GetAll(); List slotList = new List(); for (int slotLen = 0; slotLen < slotInfos.Count; slotLen++) { if (slotInfos[slotLen].FirmwareVersion == "") { continue; } slotList.Add(slotInfos[slotLen].No); } byte[] armDnaPortCmd = new byte[2] { 14, 57 }; // command to read arm dna byte[] armDnaRaw = context.Communicator.Send(armDnaPortCmd); //send command armDnaRaw = armDnaRaw.Reverse().ToArray(); string arm_dna = BitConverter.ToUInt64(armDnaRaw, 0).ToString(); //convert hex dna to decimal int SlotNum = context.Communicator.SlotNo; //download file to local if (SlotNum == slotList[0]) { DelayHelper.Sleep(1); } else { int Cried = slotList.FindIndex(x => x.Equals(SlotNum)); while (true) { Thread.Sleep(1000); if (File.Exists(EXT_CAL_INIT_PATH + slotList[Cried - 1] + ".flag")) { File.Delete(EXT_CAL_INIT_PATH + slotList[Cried - 1] + ".flag"); break; } } } ExternalCalibrationHandle extCaliHandle = new ExternalCalibrationHandle(); var isDnaUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, EXT_CAL_INIT_PATH + "Dna_init.csv", FileType.dna); LogRawText($"Dna Status: {isDnaUploadOK}"); Thread.Sleep(10); var isMVUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, EXT_CAL_INIT_PATH + "MV_init.csv", FileType.mv); LogRawText($"MV Status: {isMVUploadOK}"); Thread.Sleep(10); var isMIUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, EXT_CAL_INIT_PATH + "MI_init.csv", FileType.mi); LogRawText($"MI Status: {isMIUploadOK}"); SlotThreadLocker(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL_Init"); } /// /// Get External Calibration Board's Resistance Value /// Will Call GetRloadValue(), /// Will get R Value for each different Type and Mode /// /// info from ATE Software /// void DmmGetResValue(IFlowRunnerContext context, TestVersion testVersion) { //config DMM3458A KeysightDMM3458A dmm = new KeysightDMM3458A(); ExternalCalibrationHandle extCaliHandle = new ExternalCalibrationHandle(); string extConnStr = Select_IP[testVersion]; int extPort = 200; string res_path = EXT_CAL_INIT_PATH + "res.csv"; var slotInfos = context.FlowCatalog.GetAll(); List slotList = new List(); for (int slotLen = 0; slotLen < slotInfos.Count; slotLen++) { if (slotInfos[slotLen].FirmwareVersion == "") { continue; } slotList.Add(slotInfos[slotLen].No); } byte[] armDnaPortCmd = new byte[2] { 14, 57 }; // command to read arm dna byte[] armDnaRaw = context.Communicator.Send(armDnaPortCmd); //send command armDnaRaw = armDnaRaw.Reverse().ToArray(); string arm_dna = BitConverter.ToUInt64(armDnaRaw, 0).ToString(); int SlotNum = context.Communicator.SlotNo; ExtCaliLoad[] RLoad_Pmu_FV = { ExtCaliLoad.RC_RL13, ExtCaliLoad.RC_RL12, ExtCaliLoad.RC_RL10, ExtCaliLoad.RC_RL8, ExtCaliLoad.RC_RL5 }; ExtCaliLoad[] RLoad_Dps_FV = { ExtCaliLoad.RC_RL13, ExtCaliLoad.RC_RL12, ExtCaliLoad.RC_RL10, ExtCaliLoad.RC_RL8, ExtCaliLoad.RC_RL5, ExtCaliLoad.RC_RL3 }; int PmuResChannel = 1; int DpsResChannel = 1; double[] RRange_Pmu_FV = { 10000000, 1000000, 100000, 100000, 1000 }; double[] RRange_Dps_FV = { 1000000, 1000000, 100000, 10000, 1000, 10 }; //Creat Directory if (SlotNum == slotList[0]) { if (File.Exists(res_path)) { File.Delete(res_path); } DelayHelper.Sleep(1); dmm.InitDMM(ksightConnStr); } else { int Cried = slotList.FindIndex(x => x.Equals(SlotNum)); while (true) { Thread.Sleep(1000); if (File.Exists(EXT_CAL_INIT_PATH + slotList[Cried - 1] + ".flag")) { File.Delete(EXT_CAL_INIT_PATH + slotList[Cried - 1] + ".flag"); break; } } } Thread.Sleep(50); if (SlotNum == slotList[0]) { double ResValue = 0; StreamWriter ResWriter = new StreamWriter(res_path, true, Encoding.UTF8); ResWriter.AutoFlush = true; string[] alldpsPinName = DpsPinConfig.Select_DpsPin[testVersion]; string[] allpmuPinName = GetAllPmuPins(); DPS.Force(alldpsPinName, 0, DpsMode.FZMV, DpsIRange._2mA, VRange.Normal); //We Shall Force ALL DPS channel to Hi-Z PPMU.Force(allpmuPinName, 0, PpmuMode.FZMV, PpmuIRange._2mA, VRange.Normal); //Just in case, Let's force ALL PMU Hi-Z for (int i = 0; i < RLoad_Pmu_FV.Length; i++) { extCaliHandle.SetPpmuExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.Channel, PmuResChannel, ExtCaliVI.V, RLoad_Pmu_FV[i], 0); if (i == 0) { Thread.Sleep(50000); } else { Thread.Sleep(10000); } ResValue = GetRloadValue(dmm, RRange_Pmu_FV[i], rLimit[i]); ResWriter.Write($"Pmu_R{i + 1},{ResValue:F5}\n"); ResWriter.Flush(); } for (int j = 0; j < RLoad_Dps_FV.Length; j++) { extCaliHandle.SetDpsExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.DPS_FS, DpsResChannel, ExtCaliVI.V, RLoad_Dps_FV[j], 0); if (j == 0) { Thread.Sleep(50000); } else { Thread.Sleep(10000); } ResValue = GetRloadValue(dmm, RRange_Dps_FV[j], rLimit[j]); ResWriter.Write($"Dps_R{j + 1},{ResValue:F5}\n"); ResWriter.Flush(); } ResWriter.Flush(); ResWriter.Close(); dmm.GetDmmMeasureData(KeysightDMM3458A.KeysightMeasMode.VOLT, 1, 7.5); } else { Thread.Sleep(1); } SlotThreadLocker(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL_Init"); } /// /// Main Function to Do External Instrument Calibration /// /// info from ATE Software /// /// Flag for first test or retest /// Flag for Precheck/Postcheck void ExternalCalibrationCollect(IFlowRunnerContext context, TestVersion testVersion, bool isFirstTest, bool isPreCheck) { #region Read JSON bool isDefault = Readjson(CONFIG_JSON_PATH).Default; List Range_pmu_fvmv = Readjson(CONFIG_JSON_PATH).PMU_FVMV; List Range_pmu_fvmi = Readjson(CONFIG_JSON_PATH).PMU_FVMI; List Range_pmu_fimv = Readjson(CONFIG_JSON_PATH).PMU_FIMV; List Range_pmu_fzmv = Readjson(CONFIG_JSON_PATH).PMU_FZMV; List Range_dps_fvmv = Readjson(CONFIG_JSON_PATH).DPS_FVMV; List Range_dps_fvmi = Readjson(CONFIG_JSON_PATH).DPS_FVMI; List Range_dps_fimv = Readjson(CONFIG_JSON_PATH).DPS_FIMV; Dictionary> Select_Dps = new Dictionary>() { { TestVersion.Board_1K_FT, testChannelDps_1K }, { TestVersion.Board_1K_CP, testChannelDps_1K }, { TestVersion.Board_2K_FT, testChannelDps_2K }, { TestVersion.Board_2K_CP, testChannelDps_2K }, { TestVersion.Board_Ppmu_CP, testChannelDps_1K }, { TestVersion.Board_Ppmu_FT, testChannelDps_1K }, { TestVersion.KM_2, testChannelDps_2K } }; List ChannelDps = new List(); List ChannelPmu = new List(); Dictionary> slotTestInfo = new Dictionary>(); Dictionary testParaSet_pmu_fvmv = new Dictionary(); Dictionary testParaSet_pmu_fvmi = new Dictionary(); Dictionary testParaSet_pmu_fimv = new Dictionary(); Dictionary testParaSet_pmu_fzmv = new Dictionary(); Dictionary testParaSet_dps_fvmv = new Dictionary(); Dictionary testParaSet_dps_fvmi = new Dictionary(); Dictionary testParaSet_dps_fimv = new Dictionary(); #endregion #region 配置延时,采样次数,采样间隔 switch (testVersion) { case TestVersion.Board_1K_FT: { testParaSet_pmu_fvmi = avgDelays_1kft_fvmi_pmu; testParaSet_dps_fvmi = avgDelays_1kft_fvmi_dps; testParaSet_pmu_fimv = avgDelays_1kft_fimv_pmu; testParaSet_dps_fimv = avgDelays_1kft_fimv_dps; } break; case TestVersion.Board_1K_CP: { testParaSet_pmu_fvmi = avgDelays_1kcp_fvmi_pmu; testParaSet_dps_fvmi = avgDelays_1kcp_fvmi_dps; testParaSet_pmu_fimv = avgDelays_1kcp_fimv_pmu; testParaSet_dps_fimv = avgDelays_1kcp_fimv_dps; } break; case TestVersion.Board_2K_FT: { testParaSet_pmu_fvmi = avgDelays_2kft_fvmi_pmu; testParaSet_dps_fvmi = avgDelays_2kft_fvmi_dps; testParaSet_pmu_fimv = avgDelays_2kft_fimv_pmu; testParaSet_dps_fimv = avgDelays_2kft_fimv_dps; } break; case TestVersion.Board_Ppmu_CP: { testParaSet_pmu_fvmi = avgDelays_ppmucp_fvmi_pmu; testParaSet_dps_fvmi = avgDelays_ppmucp_fvmi_dps; testParaSet_pmu_fimv = avgDelays_ppmucp_fimv_pmu; testParaSet_dps_fimv = avgDelays_ppmucp_fimv_dps; } break; case TestVersion.Board_Ppmu_FT: { testParaSet_pmu_fvmi = avgDelays_ppmuft_fvmi_pmu; testParaSet_dps_fvmi = avgDelays_ppmuft_fvmi_dps; testParaSet_pmu_fimv = avgDelays_ppmuft_fimv_pmu; testParaSet_dps_fimv = avgDelays_ppmuft_fimv_dps; } break; case TestVersion.KM_2: { testParaSet_pmu_fvmi = avgDelays_2km_fvmi_pmu; testParaSet_dps_fvmi = avgDelays_2km_fvmi_dps; testParaSet_pmu_fimv = avgDelays_2km_fimv_pmu; testParaSet_dps_fimv = avgDelays_2km_fimv_dps; } break; default: break; } testParaSet_pmu_fvmv = avgDelays_fvmv_pmu; testParaSet_pmu_fzmv = avgDelays_fzmv_pmu; testParaSet_dps_fvmv = avgDelays_fvmv_dps; #endregion #region Do Configuration //-----get all connect slot number----- var slotInfos = context.FlowCatalog.GetAll(); List slotList = new List(); for (int slotLen = 0; slotLen < slotInfos.Count; slotLen++) { if (slotInfos[slotLen].FirmwareVersion == "") { continue; } slotList.Add(slotInfos[slotLen].No); } //-----config dmm3458A and ExtCalibrationBoard----- //KeysightDMM3458A dmm = new KeysightDMM3458A(); NiVisaComms dmm = new NiVisaComms(); ExternalCalibrationHandle extCaliHandle = new ExternalCalibrationHandle(); string extConnStr = Select_IP[testVersion]; int extPort = port; int temp = Select_Temp[testVersion]; //-----config Board----- byte[] armDnaPortCmd = new byte[2] { 14, 57 }; byte[] armDnaRaw = context.Communicator.Send(armDnaPortCmd); armDnaRaw = armDnaRaw.Reverse().ToArray(); string arm_dna = BitConverter.ToUInt64(armDnaRaw, 0).ToString(); int SlotNum = context.Communicator.SlotNo; //Get PMU_R string Currnet_IP_NUM = context.Communicator.ServerIP; string PMUR_FileName = "C:\\ProgramData\\Testrong\\ATE_Tester\\CalibrationLog\\RintCal\\PMUR\\" + Currnet_IP_NUM + "_Pmur.txt"; double[] current_ip_pmuRint = ReadRint(PMUR_FileName); #endregion //-----Select PreTest or ReTest----- #region 选择第一次测试还是复测 if (isFirstTest == true) { ChannelDps = Select_Dps[testVersion]; for (int m = 0; m < 256; m++) { ChannelPmu.Add(m + 1); } /*模式选择*/ TestInfo.Clear(); if (isDefault == true)//默认测试所有挡位和模式 { TestInfo.Add(new TestInfoSet { chType = "PMU", Mode = "FVMV", Range = testRangesPmu, Channel = ChannelPmu }); TestInfo.Add(new TestInfoSet { chType = "PMU", Mode = "FVMI", Range = testRangesPmu, Channel = ChannelPmu }); TestInfo.Add(new TestInfoSet { chType = "PMU", Mode = "FIMV", Range = testRangesPmu, Channel = ChannelPmu }); TestInfo.Add(new TestInfoSet { chType = "PMU", Mode = "FZMV", Range = testRangesPmu, Channel = ChannelPmu }); TestInfo.Add(new TestInfoSet { chType = "DPS", Mode = "FVMV", Range = testRangesDps, Channel = ChannelDps }); TestInfo.Add(new TestInfoSet { chType = "DPS", Mode = "FVMI", Range = testRangesDps, Channel = ChannelDps }); TestInfo.Add(new TestInfoSet { chType = "DPS", Mode = "FIMV", Range = testRangesDps, Channel = ChannelDps }); for (int slot = 0; slot < 12; slot++) { slotTestInfo.Add(slot + 1, TestInfo); } } else if (isDefault == false)//测试json文件中选择的挡位和模式 { if (Range_pmu_fvmv[0] != 0) { TestInfo.Add(new TestInfoSet { chType = "PMU", Mode = "FVMV", Range = RangeTrans(Range_pmu_fvmv), Channel = ChannelPmu }); } if (Range_pmu_fvmi[0] != 0) { TestInfo.Add(new TestInfoSet { chType = "PMU", Mode = "FVMI", Range = RangeTrans(Range_pmu_fvmi), Channel = ChannelPmu }); } if (Range_pmu_fimv[0] != 0) { TestInfo.Add(new TestInfoSet { chType = "PMU", Mode = "FIMV", Range = RangeTrans(Range_pmu_fimv), Channel = ChannelPmu }); } if (Range_pmu_fzmv[0] != 0) { TestInfo.Add(new TestInfoSet { chType = "PMU", Mode = "FZMV", Range = RangeTrans(Range_pmu_fzmv), Channel = ChannelPmu }); } if (Range_dps_fvmv[0] != 0) { TestInfo.Add(new TestInfoSet { chType = "DPS", Mode = "FVMV", Range = RangeTrans(Range_dps_fvmv), Channel = ChannelDps }); } if (Range_dps_fvmi[0] != 0) { TestInfo.Add(new TestInfoSet { chType = "DPS", Mode = "FVMI", Range = RangeTrans(Range_dps_fvmi), Channel = ChannelDps }); } if (Range_dps_fimv[0] != 0) { TestInfo.Add(new TestInfoSet { chType = "DPS", Mode = "FIMV", Range = RangeTrans(Range_dps_fimv), Channel = ChannelDps }); } for (int slot = 0; slot < 12; slot++) { slotTestInfo.Add(slot + 1, TestInfo); } } } //-----read fail log to start second test----- if (isFirstTest == false) { for (int slot = 0; slot < 12; slot++) { slotTestInfo.Add(slot + 1, new List()); } TestInfo.Clear(); ChannelDps.Clear(); ChannelPmu.Clear(); if (File.Exists(RETEST_LOG_PATH)) { StreamReader FailInfo = new StreamReader(RETEST_LOG_PATH, Encoding.UTF8); int failLine = 0; while (!FailInfo.EndOfStream) { string tmp = FailInfo.ReadLine(); if (failLine > 0) { int failSlot = Convert.ToInt16(tmp.Split(',')[0]); string failType = tmp.Split(',')[1]; string failMode = tmp.Split(',')[2]; List failRange = new List(); failRange.Add(tmp.Split(',')[3]); List failChannel = new List(); string failSet = tmp.Split(',')[4]; string[] failChSet = failSet.Split('_'); for (int failCount = 0; failCount < failChSet.Length; failCount++) { failChannel.Add(Convert.ToInt32(failChSet[failCount])); } slotTestInfo[failSlot].Add(new TestInfoSet { chType = failType, Mode = failMode, Range = failRange, Channel = failChannel }); } failLine++; } FailInfo.Close(); } } #endregion //-----Read R File----- Dictionary RlPmuFv = ReadRload(EXT_CAL_INIT_PATH + "res.csv")[0]; Dictionary RlPmuFi = ReadRload(EXT_CAL_INIT_PATH + "res.csv")[1]; Dictionary RlDpsFv = ReadRload(EXT_CAL_INIT_PATH + "res.csv")[2]; Dictionary RlDpsFi = ReadRload(EXT_CAL_INIT_PATH + "res.csv")[3]; double[,] ExtBoard_Res = ReadRext(EXT_CAL_INIT_PATH + "ExtBoardRes.csv"); #region File/Folder Prepartion //-----Move File To History----- File_Mover(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL_Normal", isPreCheck: isPreCheck); //-----Start Slot Number----- // Write MetaData.csv Header StreamWriter swdata; swdata = new StreamWriter(METADATA_PATH, true, Encoding.UTF8) { AutoFlush = true }; Metadata_handler( swdata: swdata, SlotNum: SlotNum, slotList: slotList, arm_dna: arm_dna, context: context, init_Flag: true ); #endregion #region Data Collection //-----Start Data Collection----- dmm.Init(ksightConnStr); List Info = slotTestInfo[SlotNum]; //{0:PMU_FVMV; 1:PMU_FVMI; 2:PMU_FIMV; 3:PMU_FZMV; 4:DPS_FVMV; 5:DPS_FVMI; 6:DPS_FIMV} for (int loopi = 0; loopi < Info.Count/*Info.Count*/; loopi++)//-----Loop Mode and Type----- { string Type = Info[loopi].chType; string Mode = Info[loopi].Mode; List ListRanges = Info[loopi].Range; List ListChannels = Info[loopi].Channel; //{0:5uA; 1:20uA; 2:200uA; 3:2mA; 4:60mA; 5:1A} for (int loopj = 0; loopj < ListRanges.Count/*ListRanges.Count*/; loopj++)//-----Loop Range----- { dmm.ClearReadingMemory();//Reset Dmm dmm.ResetInstrument(); string Range = ListRanges[loopj]; if (Range == "1A" && Mode == "FIMV") { continue; } Dictionary AteMeasureDir = new Dictionary(); Dictionary ForceValueDir = new Dictionary(); Dictionary DmmMeasureDir = new Dictionary(); Dictionary TempValueDir = new Dictionary(); List testCh = new List(); ExtCaliLoad Rcut = (Mode == "FVMV") ? ExtCaliLoad.no_load : Rcut_MIFI[Range]; string Rload = (Mode == "FVMV" || Mode == "FZMV") ? "Hi-Z" : strRloadFvmi[Range]; string rl = ""; if (Mode == "FVMV" || Mode == "FZMV") { rl = "Hi-Z"; } else { if (Type == "PMU") { rl = (Mode == "FVMI") ? RlPmuFv[Range] : RlPmuFi[Range]; } else if (Type == "DPS") { rl = (Mode == "FVMI") ? RlDpsFv[Range] : RlDpsFi[Range]; } } switch (Mode) { case "FVMV": { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 7.5, 0.04); } break; case "FVMI": { if (Type == "PMU") { if (Range == "60mA") { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.CURR, DmmCurrRanges[Range], 1); } else { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 7.5, 0.04); } } else { if (Range == "60mA" || Range == "1A") { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.CURR, DmmCurrRanges[Range], 1); } else { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 7.5, 0.04); } } } break; case "FZMV": { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 7.5, 0.04); } break; case "FIMV": { if (Type == "PMU") { if (Range == "60mA") { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 5, 0.04); } else if (Range == "5uA") { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 5, 1); } else if (Range == "20uA") { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 5, 1); } else if (Range == "200uA") { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 5, 1); } else { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 5, 0.04); } } else { if (Range == "60mA") { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 5, 0.04); } else if (Range == "5uA") { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 5, 1); } else if (Range == "20uA") { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 5, 2); } else if (Range == "200uA") { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 5, 1); } else { dmm.Setup(NiVisaComms.Dmm3458AMeasureMode.VOLT, 5, 0.04); } } } break; default: break; } string[] PmuPinName_FZ = new string[1]; string[] PmuPinName_FV = new string[1]; string[] PmuPinName_FZFV = new string[2]; #region Do Force/Measure/DMM for (int loopk = 0; loopk < ListChannels.Count/*ListChannels.Count*/; loopk++)//-----Loop Channel----- { //Note: Must put them here as Dictionary `Add` do reference NOT clone double[] AteMeasure = new double[SampliCount]; double[] ForceValue = new double[SampliCount]; double[] TempValue = new double[SampliCount]; if (Type == "PMU") { int ch = ListChannels[loopk]; string[] PmuPinName = { ("A" + (ListChannels[loopk] < 10 ? "0" : "") + ListChannels[loopk]) }; PmuPinName_FZ[0] = ("A" + (ListChannels[loopk] < 10 ? "0" : "") + ListChannels[loopk]); if ((ListChannels[loopk] % 8 >= 1) && (ListChannels[loopk] % 8 <= 4)) { PmuPinName_FV[0] = ("A" + ((ListChannels[loopk] + 4) < 10 ? "0" : "") + (ListChannels[loopk] + 4)); } else if ((ListChannels[loopk] % 8 > 4) || (ListChannels[loopk] % 8 == 0))//kChannel == 4, 12 { PmuPinName_FV[0] = ("A" + ((ListChannels[loopk] - 4) < 10 ? "0" : "") + (ListChannels[loopk] - 4)); } //PmuPinName_FV[0] = FZMV_PMU[PmuPinName_FZ[0]]; PmuPinName_FZFV[0] = PmuPinName_FZ[0]; PmuPinName_FZFV[1] = PmuPinName_FV[0]; RELAY.SwitchMode(RelayMode.Open); if (ModesPmu[Mode] == PpmuMode.FZMV) { RELAY.SwitchToPPMU(PmuPinName_FZFV); } else { RELAY.SwitchToPPMU(PmuPinName); } double ForceVoltage = VoltageInitialDefault; double VoltageStep = VoltageStepDefault; if (ModesPmu[Mode] == PpmuMode.FVMI) { if (RangesPmu[Range] == PpmuIRange._60mA || RangesPmu[Range] == PpmuIRange._5uA) { ForceVoltage = VoltageInitialSet; VoltageStep = VoltageStepSet; } if (RangesPmu[Range] == PpmuIRange._20uA) { ForceVoltage = VoltageInitialSet; } } switch (Info[loopi].Mode) { case "FVMV": { extCaliHandle.SetPpmuExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.Channel, ch, ExtCaliVI.V, Rcut, 0);//change channel Thread.Sleep(5); for (int p = 0; p < SampliCount; p++) { PPMU.Force(PmuPinName, ForceVoltage, ModesPmu[Mode], RangesPmu[Range], VRange.Normal); Thread.Sleep(1); PPMU.Force(PmuPinName, ForceVoltage, ModesPmu[Mode], RangesPmu[Range], VRange.Normal); Thread.Sleep(testParaSet_pmu_fvmv[Range].delayMs); dmm.TriggerSingleMeasure(); List siList = PPMU.Measure(PmuPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMV"), testParaSet_pmu_fvmv[Range].avgTimes, testParaSet_pmu_fvmv[Range].samDelay); double chResult = GetATEChannelMeasure(siList, PmuPinName); double[] readTemp = PPMU.ReadTemperature(); double chTemp = readTemp[GetPMUTempSensorIndex(ch)]; TempValue[p] = chTemp; AteMeasure[p] = chResult; ForceValue[p] = ForceVoltage; ForceVoltage += VoltageStep; } PPMU.Force(PmuPinName, 0, PpmuMode.FVMV, RangesPmu[Range], VRange.Normal); Thread.Sleep(5); } break; case "FVMI": { if (RangesPmu[Range] == PpmuIRange._60mA) { extCaliHandle.SetPpmuExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.Channel, ch, ExtCaliVI.I, Rcut, 0); Thread.Sleep(15); for (int p = 0; p < SampliCount; p++) { PPMU.Force(PmuPinName, ForceVoltage, ModesPmu[Mode], RangesPmu[Range], VRange.Normal); Thread.Sleep(testParaSet_pmu_fvmi[Range].delayMs); dmm.TriggerSingleMeasure(); Thread.Sleep(50); List siList = PPMU.Measure(PmuPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMI"), testParaSet_pmu_fvmi[Range].avgTimes, testParaSet_pmu_fvmi[Range].samDelay); double chResult = GetATEChannelMeasure(siList, PmuPinName); double[] readTemp = PPMU.ReadTemperature(); double chTemp = readTemp[GetPMUTempSensorIndex(ch)]; TempValue[p] = chTemp; AteMeasure[p] = chResult; ForceValue[p] = ForceVoltage / (Convert.ToDouble(RlPmuFv[Range]) + ExtBoard_Res[ch - 1, SlotNum - 1]); ForceVoltage += VoltageStep; } } else { extCaliHandle.SetPpmuExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.Channel, ch, ExtCaliVI.V, Rcut, 0); Thread.Sleep(5); if (loopk == 0) { Thread.Sleep(5); } for (int p = 0; p < SampliCount; p++) { PPMU.Force(PmuPinName, ForceVoltage, ModesPmu[Mode], RangesPmu[Range], VRange.Normal); Thread.Sleep(testParaSet_pmu_fvmi[Range].delayMs); dmm.TriggerSingleMeasure(); List siList = PPMU.Measure(PmuPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMI"), testParaSet_pmu_fvmi[Range].avgTimes, testParaSet_pmu_fvmi[Range].samDelay); double chResult = GetATEChannelMeasure(siList, PmuPinName); double[] readTemp = PPMU.ReadTemperature(); double chTemp = readTemp[GetPMUTempSensorIndex(ch)]; TempValue[p] = chTemp; AteMeasure[p] = chResult; ForceValue[p] = ForceVoltage / (Convert.ToDouble(RlPmuFv[Range]) + ExtBoard_Res[ch - 1, SlotNum - 1]); if (RangesPmu[Range] == PpmuIRange._20uA) { ForceVoltage += VoltageStep20uA[p]; } else { ForceVoltage += VoltageStep; } } } PPMU.Force(PmuPinName, 0, PpmuMode.FVMV, RangesPmu[Range], VRange.Normal); Thread.Sleep(10); } break; case "FIMV": { extCaliHandle.SetPpmuExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.Channel, ch, ExtCaliVI.V, Rcut, 0); Thread.Sleep(5); for (int p = 0; p < SampliCount; p++) { double ForceCurrent = FiRanges[Range] * CurrScale[p];//Force Current PPMU.Force(PmuPinName, ForceCurrent, ModesPmu[Mode], RangesPmu[Range], VRange.Normal); Thread.Sleep(testParaSet_pmu_fimv[Range].delayMs); dmm.TriggerSingleMeasure(); if (Range == "5uA" || Range == "20uA") { if (loopk == 0 && p == 0) { Thread.Sleep(50); } Thread.Sleep(20); } if (Range == "200uA") { Thread.Sleep(50); } List siList = PPMU.Measure(PmuPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FIMV"), testParaSet_pmu_fimv[Range].avgTimes, testParaSet_pmu_fimv[Range].samDelay); double chResult = GetATEChannelMeasure(siList, PmuPinName); double Real_V = 0; double ExtRload = Convert.ToDouble(RlPmuFi[Range]); Real_V = chResult + ForceCurrent * current_ip_pmuRint[ListChannels[loopk] - 1]; double Total_Rint = current_ip_pmuRint[ListChannels[loopk] - 1] + ExtBoard_Res[ListChannels[loopk] - 1, SlotNum - 1]; double Real_I = Real_V / (Total_Rint + ExtRload); AteMeasure[p] = (Real_V - (Total_Rint * Real_I)) / ExtRload; //AteMeasure[p] = chResult / (Convert.ToDouble(RlPmuFi[Range]) + ExtBoard_Res[ch - 1, SlotNum - 1]); ForceValue[p] = ForceCurrent; double[] readTemp = PPMU.ReadTemperature(); double chTemp = readTemp[GetPMUTempSensorIndex(ch)]; TempValue[p] = chTemp; } PPMU.Force(PmuPinName, 0, PpmuMode.FVMV, RangesPmu[Range], VRange.Normal); Thread.Sleep(10); } break; case "FZMV": { extCaliHandle.SetPpmuExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.Channel, ch, ExtCaliVI.V, ExtCaliLoad.no_load, 0); Thread.Sleep(5); for (int p = 0; p < SampliCount; p++) { PPMU.Force(PmuPinName_FV, ForceVoltage, PpmuMode.FVMV, RangesPmu[Range], VRange.Normal); Thread.Sleep(1); PPMU.Force(PmuPinName_FV, ForceVoltage, PpmuMode.FVMV, RangesPmu[Range], VRange.Normal); PPMU.Force(PmuPinName_FZ, ForceVoltage, PpmuMode.FZMV, RangesPmu[Range], VRange.Normal); Thread.Sleep(testParaSet_pmu_fzmv[Range].delayMs); dmm.TriggerSingleMeasure(); List siList = PPMU.Measure(PmuPinName_FZ, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMV"), testParaSet_pmu_fzmv[Range].avgTimes, testParaSet_pmu_fzmv[Range].samDelay); double chResult = GetATEChannelMeasure(siList, PmuPinName_FZ); double[] readTemp = PPMU.ReadTemperature(); double chTemp = readTemp[GetPMUTempSensorIndex(ch)]; TempValue[p] = chTemp; AteMeasure[p] = chResult; ForceValue[p] = ForceVoltage; ForceVoltage += VoltageStep; } PPMU.Force(PmuPinName_FV, 0, PpmuMode.FVMV, RangesPmu[Range], VRange.Normal); PPMU.Force(PmuPinName_FZ, 0, PpmuMode.FVMV, RangesPmu[Range], VRange.Normal); Thread.Sleep(5); PPMU.Force(PmuPinName_FV, 0, PpmuMode.FZMV, RangesPmu[Range], VRange.Normal); PPMU.Force(PmuPinName_FZ, 0, PpmuMode.FZMV, RangesPmu[Range], VRange.Normal); Thread.Sleep(5); } break; default: break; } AteMeasureDir.Add(ch, AteMeasure); ForceValueDir.Add(ch, ForceValue); TempValueDir.Add(ch, TempValue); testCh.Add(ch); } else if (Type == "DPS") { string[] DpsPinName = { ("DPS" + ListChannels[loopk]) }; string[] allDpsPinNames = DpsPinConfig.Select_DpsPin[testVersion]; double ForceVoltage = (RangesDps[Range] == DpsIRange._1A) ? VoltageInitialDps1A : VoltageInitialDefault;//1A for range double VoltageStep = (RangesDps[Range] == DpsIRange._1A) ? VoltageStepDps1A : VoltageStepDefault; if (ModesDps[Mode] == DpsMode.FVMI) { if (RangesDps[Range] != DpsIRange._1A) { ForceVoltage = VoltageInitialSet; VoltageStep = VoltageStepSet; } } int ch = ListChannels[loopk]; DpsRangeRelay.SetDpsRangeRelayBySignals(allDpsPinNames, DpsRelayState.OPEN, context); switch (RangesDps[Range]) { case DpsIRange._60mA: { DpsRangeRelay.SetDpsRangeRelayBySignals(DpsPinName, DpsRelayState._60MA, context); } break; case DpsIRange._1A: { DpsRangeRelay.SetDpsRangeRelayBySignals(DpsPinName, DpsRelayState.EXT, context); } break; default: { DpsRangeRelay.SetDpsRangeRelayBySignals(DpsPinName, DpsRelayState.INT, context); } break; } switch (Info[loopi].Mode) { case "FVMV": { extCaliHandle.SetDpsExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.DPS_FS, ch, ExtCaliVI.V, Rcut, 0);//change channel Thread.Sleep(10); for (int p = 0; p < SampliCount; p++) { DPS.Force(DpsPinName, ForceVoltage, ModesDps[Mode], RangesDps[Range], VRange.Normal); Thread.Sleep(testParaSet_dps_fvmv[Range].delayMs); if ((ListChannels[loopk] == 2 || ListChannels[loopk] == 3) && testVersion == TestVersion.Board_2K_FT) { Thread.Sleep(50); } dmm.TriggerSingleMeasure(); List siList = DPS.Measure(DpsPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMV"), testParaSet_dps_fvmv[Range].avgTimes, testParaSet_dps_fvmv[Range].samDelay); double chResult = GetATEChannelMeasure(siList, DpsPinName); double[] readTemp = DPS.ReadTemperature(); int TempIndex = GetDPSTempSensorIndex(ch); double chTemp; if (TempIndex > readTemp.Length + 1) { chTemp = -65535; } else { chTemp = readTemp[TempIndex]; } TempValue[p] = chTemp; ForceValue[p] = ForceVoltage; AteMeasure[p] = chResult; ForceVoltage += VoltageStep; } DPS.Force(DpsPinName, 0, DpsMode.FVMV, RangesDps[Range], VRange.Normal); Thread.Sleep(5); } break; case "FVMI": { if ((RangesDps[Range] == DpsIRange._60mA) || (RangesDps[Range] == DpsIRange._1A)) { extCaliHandle.SetDpsExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.DPS_FS, ch, ExtCaliVI.I, Rcut, 0); Thread.Sleep(20); for (int p = 0; p < SampliCount; p++) { DPS.Force(DpsPinName, ForceVoltage, ModesDps[Mode], RangesDps[Range], VRange.Normal); double CurrValue = ForceVoltage / Convert.ToDouble(RlDpsFv[Range]); Thread.Sleep(testParaSet_dps_fvmi[Range].delayMs); if (loopk == 0 || p == 0) { Thread.Sleep(100); } dmm.TriggerSingleMeasure(); Thread.Sleep(50); List siList = DPS.Measure(DpsPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMI"), testParaSet_dps_fvmi[Range].avgTimes, testParaSet_dps_fvmi[Range].samDelay); double chResult = GetATEChannelMeasure(siList, DpsPinName); double[] readTemp = DPS.ReadTemperature(); int TempIndex = GetDPSTempSensorIndex(ch); double chTemp; if (TempIndex > readTemp.Length + 1) { chTemp = -65535; } else { chTemp = readTemp[TempIndex]; } TempValue[p] = chTemp; ForceValue[p] = CurrValue; AteMeasure[p] = chResult; ForceVoltage += VoltageStep; } } else { extCaliHandle.SetDpsExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.DPS_FS, ch, ExtCaliVI.V, Rcut, 0); Thread.Sleep(20); for (int p = 0; p < SampliCount; p++) { DPS.Force(DpsPinName, ForceVoltage, ModesDps[Mode], RangesDps[Range], VRange.Normal); double CurrValue = ForceVoltage / Convert.ToDouble(RlDpsFv[Range]); Thread.Sleep(testParaSet_dps_fvmi[Range].delayMs); dmm.TriggerSingleMeasure(); if (p == 0) { if (Range == "5uA") { Thread.Sleep(10); } else if (Range == "20uA") { Thread.Sleep(50); } else if (Range == "200uA") { Thread.Sleep(100); } else { Thread.Sleep(10); } } List siList = DPS.Measure(DpsPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMI"), testParaSet_dps_fvmi[Range].avgTimes, testParaSet_dps_fvmi[Range].samDelay); double chResult = GetATEChannelMeasure(siList, DpsPinName); double[] readTemp = DPS.ReadTemperature(); int TempIndex = GetDPSTempSensorIndex(ch); double chTemp; if (TempIndex > readTemp.Length + 1) { chTemp = -65535; } else { chTemp = readTemp[TempIndex]; } TempValue[p] = chTemp; ForceValue[p] = CurrValue; AteMeasure[p] = chResult; ForceVoltage += VoltageStep; } } DPS.Force(DpsPinName, 0, DpsMode.FVMV, RangesDps[Range], VRange.Normal); Thread.Sleep(10); } break; case "FIMV": { extCaliHandle.SetDpsExternalCalibration(extConnStr, extPort, SlotNum, ExternalCalibrationMode.DPS_FS, ch, ExtCaliVI.V, Rcut, 0); Thread.Sleep(10); for (int p = 0; p < SampliCount; p++) { double ForceCurrent = FiRanges[Range] * CurrScale[p];//Force Current DPS.Force(DpsPinName, ForceCurrent, ModesDps[Mode], RangesDps[Range], VRange.Normal); Thread.Sleep(testParaSet_dps_fimv[Range].delayMs); if (Range == "5uA" || Range == "20uA") { if (ListChannels[loopk] == 33 || ListChannels[loopk] == 1) { if (Range == "20uA") { Thread.Sleep(30); } if (Range == "5uA") { Thread.Sleep(50); } } } dmm.TriggerSingleMeasure(); if (Range == "5uA" || Range == "20uA" || Range == "200uA") { if (p == 0) { Thread.Sleep(50); } if (Range == "5uA") { Thread.Sleep(25); } else if (Range == "20uA") { Thread.Sleep(50); } else if (Range == "200uA") { Thread.Sleep(50); } } List siList = DPS.Measure(DpsPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FIMV"), testParaSet_dps_fimv[Range].avgTimes, testParaSet_dps_fimv[Range].samDelay); double chResult = GetATEChannelMeasure(siList, DpsPinName); double[] readTemp = DPS.ReadTemperature(); int TempIndex = GetDPSTempSensorIndex(ch); double chTemp; if (TempIndex > readTemp.Length + 1) { chTemp = -65535; } else { chTemp = readTemp[TempIndex]; } TempValue[p] = chTemp; ForceValue[p] = ForceCurrent; AteMeasure[p] = chResult / Convert.ToDouble(RlDpsFi[Range]); } DPS.Force(DpsPinName, 0, DpsMode.FZMV, RangesDps[Range], VRange.Normal); Thread.Sleep(10); } break; default: break; } AteMeasureDir.Add(ch, AteMeasure); ForceValueDir.Add(ch, ForceValue); TempValueDir.Add(ch, TempValue); testCh.Add(ch); } } //Read Back Value From DMM int DataCount = testCh.Count * SampliCount; double[] dmmRead = dmm.MultiRead(DataCount); dmm.ClearReadingMemory(); DmmMeasureDir = ReadBackDmm(dmmRead, testCh); #endregion #region WriteToFile //Write Data to File if (Type == "PMU") { for (int writeNum = 0; writeNum < testCh.Count; writeNum++) { int ch = testCh[writeNum]; string filepath = "Slot" + SlotNum + "_PMU_" + "ch" + ch + "_" + Mode + "_" + Rload + "_" + Range + ".csv"; string filename = EXT_CAL_PATH + filepath; string filetime = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"); StreamWriter sw = new StreamWriter(filename, true, Encoding.UTF8) { AutoFlush = true }; WriteSingleFile(sw: sw, slot: SlotNum, dna: arm_dna, type: Type, channel: ch, mode: Mode, rload: rl, extR: ExtBoard_Res, range: Range, ForceValue: ForceValueDir[ch], AteMeasure: AteMeasureDir[ch], DmmMeasure: DmmMeasureDir[ch], TempValue: TempValueDir[ch]); sw.Flush(); sw.Close(); Metadata_handler(swdata: swdata, SlotNum: SlotNum, slotList: slotList, arm_dna: arm_dna, context: context, init_Flag: false, Type: Type, Channel: ch, Mode: Mode, Rload: rl, Range: Range, filepath: filepath, filetime: filetime); } } else if (Type == "DPS") { for (int writeNum = 0; writeNum < testCh.Count; writeNum++) { int ch = testCh[writeNum]; string filepath = "Slot" + SlotNum + "_DPS_" + "ch" + ch + "_" + Mode + "_" + Rload + "_" + Range + ".csv"; string filename = EXT_CAL_PATH + filepath; string filetime = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"); double[,] ZeroExtR = { { 0.0 , 0.0 , 0.0} }; StreamWriter sw = new StreamWriter(filename, true, Encoding.UTF8) { AutoFlush = true }; WriteSingleFile(sw: sw, slot: SlotNum, dna: arm_dna, type: Info[loopi].chType, channel: ch, mode: Mode, rload: rl, extR: ZeroExtR, range: Range, ForceValue: ForceValueDir[ch], AteMeasure: AteMeasureDir[ch], DmmMeasure: DmmMeasureDir[ch], TempValue: TempValueDir[ch]); sw.Flush(); sw.Close(); Metadata_handler(swdata: swdata, SlotNum: SlotNum, slotList: slotList, arm_dna: arm_dna, context: context, init_Flag: false, Type: Type, Channel: ch, Mode: Mode, Rload: rl, Range: Range, filepath: filepath, filetime: filetime); } } #endregion } } #endregion #region Thread Lock SlotThreadLocker(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL"); #endregion dmm.ResetInstrument(); swdata.Flush(); swdata.Close(); } /// /// Use TFTP to upload DNA/MV/MI file into Zynq /// /// info from ATE Software void ExternalCalibrationWriteCalFiles(IFlowRunnerContext context) { //read dna and ip var slotInfos = context.FlowCatalog.GetAll(); List slotList = new List(); for (int slotLen = 0; slotLen < slotInfos.Count; slotLen++) { if (slotInfos[slotLen].FirmwareVersion == "") { continue; } slotList.Add(slotInfos[slotLen].No); } byte[] armDnaPortCmd = new byte[2] { 14, 57 }; // command to read arm dna byte[] armDnaRaw = context.Communicator.Send(armDnaPortCmd); //send command armDnaRaw = armDnaRaw.Reverse().ToArray(); string arm_dna = BitConverter.ToUInt64(armDnaRaw, 0).ToString(); //convert hex dna to decimal int SlotNum = context.Communicator.SlotNo; ExternalCalibrationHandle extCaliHandle = new ExternalCalibrationHandle(); if (SlotNum == slotList[0]) { DelayHelper.Sleep(1); } else { int Cried = slotList.FindIndex(x => x.Equals(SlotNum)); while (true) { Thread.Sleep(1000); if (File.Exists(CAL_COMPFILE_PATH + slotList[Cried - 1] + ".flag")) //Wait until previous thread flags completion { File.Delete(CAL_COMPFILE_PATH + slotList[Cried - 1] + ".flag"); break; } } } //Write files Thread.Sleep(10); var isDnaUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, CAL_COMPFILE_PATH + "DNA_" + context.Communicator.ServerIP + ".csv", FileType.dna); LogRawText($"Dna Status: {isDnaUploadOK}"); Thread.Sleep(10); var isMVUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, CAL_COMPFILE_PATH + context.Communicator.ServerIP + "_MV.csv", FileType.mv); LogRawText($"MV Status: {isMVUploadOK}"); Thread.Sleep(10); var isMIUploadOK = extCaliHandle.UploadFile(context.Communicator.ServerIP, CAL_COMPFILE_PATH + context.Communicator.ServerIP + "_MI.csv", FileType.mi); LogRawText($"MI Status: {isMIUploadOK}"); SlotThreadLocker(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL_COM"); } /// /// Get Measurments For Rint w/ GND Board /// Only Use FVMI 2mA Range /// /// info from ATE Software void Rint_GND_FVMI_2mA(IFlowRunnerContext context) { List ChannelPmu = new List(); for (int m = 0; m < 256; m++) { ChannelPmu.Add(m + 1); } var slotInfos = context.FlowCatalog.GetAll(); List slotList = new List(); for (int slotLen = 0; slotLen < slotInfos.Count; slotLen++) { if (slotInfos[slotLen].FirmwareVersion == "") { continue; } slotList.Add(slotInfos[slotLen].No); } //-----config Board----- byte[] armDnaPortCmd = new byte[2] { 14, 57 }; byte[] armDnaRaw = context.Communicator.Send(armDnaPortCmd); armDnaRaw = armDnaRaw.Reverse().ToArray(); string arm_dna = BitConverter.ToUInt64(armDnaRaw, 0).ToString(); int SlotNum = context.Communicator.SlotNo; double[,] ExtBoard_Res = ReadRext(EXT_CAL_INIT_PATH + "ExtBoardRes.csv"); //Folder Related File_Mover(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL_Single"); //-----Start Slot Number----- StreamWriter swdata; swdata = new StreamWriter(METADATA_PATH, true, Encoding.UTF8) { AutoFlush = true }; Metadata_handler( swdata: swdata, SlotNum: SlotNum, slotList: slotList, arm_dna: arm_dna, context: context, init_Flag: true ); string filetime = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"); for (int loopk = 0; loopk < 256; loopk++) { string[] PmuPinName = { ("A" + (ChannelPmu[loopk] < 10 ? "0" : "") + ChannelPmu[loopk]) }; RELAY.SwitchMode(RelayMode.Open); RELAY.SwitchToPPMU(PmuPinName); double ForceCurrent = -0.001;//1mA double CurrentStep = 0.0005; double ForceV = -0.008; double Vstep = 0.0004; string filepath = "Slot" + SlotNum + "_PMU_" + "ch" + ChannelPmu[loopk] + "_" + "FVMI" + "_" + "Hi-Z" + "_" + "2mA" + ".csv"; string filename = EXT_CAL_PATH + filepath; int ch = ChannelPmu[loopk]; double[] AteMeasure = new double[SampliCount]; double[] ForceValue = new double[SampliCount]; double[] DMMValue = new double[SampliCount]; double[] TempValue = new double[SampliCount]; StreamWriter sw = new StreamWriter(filename, true, Encoding.UTF8) { AutoFlush = true }; if (loopk == 0) { DelayHelper.Sleep(20); } //Force 0V Measure Voltage PPMU.Force(PmuPinName, 0, PpmuMode.FVMV, PpmuIRange._2mA, VRange.Normal); List zero_V_List = PPMU.Measure(PmuPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMV"), 128, 100); double zeroVResult = GetATEChannelMeasure(zero_V_List, PmuPinName); sw.Write($"Force_0V_MV={zeroVResult * 1000:F8}mV\n"); //Force 0V Measure Current PPMU.Force(PmuPinName, 0, PpmuMode.FVMI, PpmuIRange._2mA, VRange.Normal); List zero_I_List = PPMU.Measure(PmuPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMI"), 128, 100); double zeroIResult = GetATEChannelMeasure(zero_I_List, PmuPinName); sw.Write($"Force_0V_MI={zeroIResult * 1000:F8}mA\n"); sw.Write("Force Voltage(mV),Measure Voltage(mV),Measure Current(mA),Diff_Voltage(mV),Resistance(FV/MI),Resistance(Caled)\n"); for (int p = 0; p < 50; p++) { PPMU.Force(PmuPinName, ForceV, PpmuMode.FVMI, PpmuIRange._2mA, VRange.Normal); sw.Write($"{ForceV * 1000:F8},"); Thread.Sleep(20); List siList = PPMU.Measure(PmuPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMI"), 128, 100); double chResult = GetATEChannelMeasure(siList, PmuPinName); PPMU.Force(PmuPinName, ForceV, PpmuMode.FVMV, PpmuIRange._2mA, VRange.Normal); List svList = PPMU.Measure(PmuPinName, true, context.BinHandler.GetBinningByTestSuite("ExtCalibration_FVMV"), 128, 100); double chVResult = GetATEChannelMeasure(svList, PmuPinName); sw.Write($"{chVResult * 1000:F8},"); sw.Write($"{chResult * 1000:F8},"); sw.Write($"{(chVResult - ForceV) * 1000:F8},"); sw.Write($"{ForceV / chResult:F8},"); sw.Write($"{(ForceV - zeroVResult) / (chResult - zeroIResult):F8}\n"); //ForceCurrent += CurrentStep; ForceV += Vstep; } PPMU.Force(PmuPinName, 0, PpmuMode.FVMI, PpmuIRange._2mA, VRange.Normal); WriteSingleFile(sw: sw, slot: SlotNum, dna: arm_dna, type: "PMU", channel: ch, mode: "FVMI", rload: "Hi-Z", extR: ExtBoard_Res, range: "2mA", ForceValue: ForceValue, AteMeasure: AteMeasure, DmmMeasure: DMMValue, TempValue: TempValue, contextFormat: "RintGND"); sw.Flush(); sw.Close(); Metadata_handler(swdata: swdata, SlotNum: SlotNum, slotList: slotList, arm_dna: arm_dna, context: context, init_Flag: false, Type: "PMU", Channel: ch, Mode: "FVMI", Rload: "Hi-Z", Range: "2mA", filepath: filepath, filetime: filetime); } swdata.Flush(); swdata.Close(); Thread.Sleep(100); SlotThreadLocker(SlotNum: SlotNum, slotList: slotList, pathFlag: "CAL"); } #endregion [TestrongTestCase] public void Reset(IFlowRunnerContext context) { ExternalCalibrationReset(context); } [TestrongTestCase] public void DmmGetRes(IFlowRunnerContext context) { DmmGetResValue(context, SelectTestVersion); } [TestrongTestCase] public void Ext_Calibration_Pre(IFlowRunnerContext context) { ExternalCalibrationCollect(context, SelectTestVersion, true, true); } [TestrongTestCase] public void Write_CalFiles(IFlowRunnerContext context) { ExternalCalibrationWriteCalFiles(context); } [TestrongTestCase] public void Ext_Calibration_Post(IFlowRunnerContext context) { ExternalCalibrationCollect(context, SelectTestVersion, true, false); } [TestrongTestCase] public void RintReset(IFlowRunnerContext context) { Rint_Reset(context); } [TestrongTestCase] public void Rint_Pre(IFlowRunnerContext context) { Rint_FVMV_2mA_Pre(context, SelectTestVersion); } [TestrongTestCase] public void RintDataUpload(IFlowRunnerContext context) { Rint_DataUpload(context); } [TestrongTestCase] public void Rint_Post(IFlowRunnerContext context) { Rint_FVMV_2mA_Post(context, SelectTestVersion); } [TestrongTestCase] public void PmurUpload(IFlowRunnerContext context) { Pmur_Upload(context); } [TestrongTestCase] public void ReTest(IFlowRunnerContext context) { ExternalCalibrationCollect(context, SelectTestVersion, false, false); } [TestrongTestCase] public void Freq_Test(IFlowRunnerContext context) { ExternalCalibrationFreqCollect(context, SelectTestVersion); } [TestrongTestCase] public void Rint_FVMI_Gnd(IFlowRunnerContext context) { Rint_GND_FVMI_2mA(context); } } }