using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Uestc.Auto6.Dso.ComModel; namespace Uestc.Auto6.Dso.Hardware.Driver { internal record PerChannelAcqParams { public UInt64 AcqBdExtractNum; public UInt32 AcqBdInterpolationNum; public UInt32 ProcBdInterpolationNum; public ulong DdrPointPerDataByfs; public ulong DmaPointPerDataByfs; } internal class AcquireAttribute { #region 通道带宽模式切换 /// /// bit8 :Full BandWidth=0,Other BandWidth=1;bit7~bit0:channel 1~channel8 的激活状态 /// public Int32 CurrChBWModeAndActiveState = 0; /// /// bit8 :Full BandWidth=0,Other BandWidth=1;bit7~bit0:channel 1~channel8 的激活状态 /// public Int32 OldChBWModeAndActiveState = -1; #endregion //public List ChannelAcqParams = new List(); /// /// 存储模式:长存储,普通存储 /// public AnaChnlStorageMode AcqStorageMode { get; set; } public bool bIsLongStorageMode { get => AcqStorageMode == AnaChnlStorageMode.Long; } public UInt64 StorageLengthOfDots { get; set; } /// /// 只对长存储有用 /// public UInt32 StorageStartAddress { get; set; } /// /// 最高采样率(合并后的)下,单一抽取器来计算的。 /// public UInt64 HardwareExtractNum { get; set; } public UInt64 Dpx_HardwareExtractNum { get; set; } public UInt64 Dpx_PerDataByfs_AtStorage { get; set; } /// /// 在硬件端存储数据的采样率 /// public double PerDataByfs_AtStorage { get; set; } /// /// 读取回来的数据的采样率。对长存储来说,是读回来的数据。因为在读取的过程中好,可能存在二次抽取。 /// public double PerDataByfs_Readback { get; set; } /// /// 送给对外接口时的采样率。可能存在软件端的插值处理。如果没有软件端的插值,就是PerDataByfs /// public double PerDataByfs_AfterPostProcess { get; set; } public UInt32 InterpolationNum { get; set; } /// /// 设置的触发时间 /// public Int64 SettingTrigPositionByfs { get; set; } public UInt32 SoftwareFifoLength { get; set; } public UInt32 AnaWaveDMALength { get; set; } /// /// 多少个10GADC拼合的,10G=1,20G=2; /// public UInt32 AcqBoardAdcMegerCount { get; set; } = 2; /// /// 处理板拼合采集几个板的数据形成一个通道的数据。目前只有HB8G项目在40G模式下是2,在20G模式下是1. /// 其与PerDataByfs_AtStorage、HardwareExtractNum的计算有关。HB8G项目在40G模式下,PerDataByfs_AtStorage与HardwareExtractNum存在2倍关系 /// public UInt32 ProcBoardMergeAcqBoardRoadCount { get; set; } = 1; public UInt32 AcqAdcMergeRoadCount { get; set; } = 80; public UInt32 LS_SegmentCount { get; set; } public UInt32 LS_SegmentDots { get; set; } public UInt32 LS_SegmentAddrCount { get; set; } public UInt32 LS_ChannelMode { get; set; } public UInt32 LS_Addr_TrigTable { get; set; } public UInt32 LS_Addr_FirstSegment { get; set; } public UInt32 LS_Addr_PreTrig { get; set; } public UInt32 LS_CurrSegmentIndex { get; set; } public UInt32 LS_AcqTimeStamp { get; set; } public void CloneTo(AcquireAttribute dest) { dest.AcqStorageMode = this.AcqStorageMode; dest.AnaWaveDMALength = this.AnaWaveDMALength; dest.HardwareExtractNum = this.HardwareExtractNum; dest.InterpolationNum = this.InterpolationNum; dest.PerDataByfs_AfterPostProcess = this.PerDataByfs_AfterPostProcess; dest.PerDataByfs_AtStorage = this.PerDataByfs_AtStorage; dest.PerDataByfs_Readback = this.PerDataByfs_Readback; dest.SettingTrigPositionByfs = this.SettingTrigPositionByfs; dest.SoftwareFifoLength = this.SoftwareFifoLength; dest.StorageLengthOfDots = this.StorageLengthOfDots; dest.StorageStartAddress = this.StorageStartAddress; dest.CurrChBWModeAndActiveState = this.CurrChBWModeAndActiveState; dest.OldChBWModeAndActiveState = this.OldChBWModeAndActiveState; dest.LS_SegmentCount = this.LS_SegmentCount; dest.LS_SegmentDots = this.LS_SegmentDots; dest.LS_ChannelMode = this.LS_ChannelMode; dest.LS_Addr_FirstSegment = this.LS_Addr_FirstSegment; dest.LS_Addr_PreTrig = this.LS_Addr_PreTrig; dest.LS_SegmentAddrCount = this.LS_SegmentAddrCount; dest.LS_CurrSegmentIndex = this.LS_CurrSegmentIndex; dest.LS_AcqTimeStamp = this.LS_AcqTimeStamp; dest.LS_Addr_TrigTable = this.LS_Addr_TrigTable; dest.Dpx_HardwareExtractNum = this.Dpx_HardwareExtractNum; dest.Dpx_PerDataByfs_AtStorage = this.Dpx_PerDataByfs_AtStorage; //dest.ChannelAcqParams.Clear(); //foreach(var v in ChannelAcqParams) // dest.ChannelAcqParams.Add(v); } } internal enum ChannelBandWidthMode { /// /// 全带宽模式 /// Full, /// /// 对一般的情况,是降带宽模式,对多域项目来讲,是4G带宽 /// Mode2, /// /// 目前仅仅对多域有效,指射频通道 /// Mode3 } internal class Acquisition { internal static void CreateAcquirer(AbstractAcquirer?[] usedAcquirerList) { allAcquirer.AddRange(usedAcquirerList); Stopwatch_AmplitudeTemperatureCompensate.Start(); } private static List allAcquirer = new List(); internal static void Init() { foreach (AbstractAcquirer? acquirer in allAcquirer) acquirer?.Init(); } private static void StartingGunPang() { #region 通路选择 HdIO.WriteReg(PcieBdReg.W.RST_CTRL_PcieReset, 0x1); HdIO.WriteReg(PcieBdReg.W.RST_CTRL_PcieReset, 0x0); //HdIO.WriteReg(ProcBdReg.W.debug_pro_debug_mode, 0x1); //HdIO.WriteReg(ProcBdReg.W.LA_SoftReset, 1); // HdIO.WriteReg(ProcBdReg.W.LA_SoftReset, 0); Hd.currProduct?.AcqBd?.WriteToAllFpga(AcqBdReg.W.Dpo_ParallelReset, 1); Hd.currProduct?.AcqBd?.WriteToAllFpga(AcqBdReg.W.Dpo_ParallelReset, 0); HdIO.WriteReg(PcieBdReg.W.RST_CTRL_SysResetFromPcie, 0x0); #endregion HdIO.WriteReg(ProcBdReg.W.FifoCtrl_AcqWriteEnable, 1); if (Hd.CurrHdMessage!.Timebase!.IsScan) { int channelCount = ChannelIdExt.AnaChnlNum; if (Hd.currProduct!.ProductType == ProductType.B21_DBI16G) channelCount = 4; while (AcqedDataPool.AnalogChData.AllChannelData.Count < channelCount) AcqedDataPool.AnalogChData.AllChannelData.Add(new List()); for (int iChannelID = 0; iChannelID < channelCount; iChannelID++) AcqedDataPool.AnalogChData.AllChannelData[iChannelID].Clear(); } //HdIO.WriteReg(PcieBdReg.W.DataPath_pcie_linkdemux_select, (UInt32)DMAReadSourceMuxType.AnalogChanneData); // DDR要求必须在触发使能之后才能下发DDRde写使能,且触发源采集板必须最后发写使能,这样才能保证600W的触发频率 ////FPGA 的严重Bug 导致 此 垃圾代码,很危险!!!!!!!!!!! UInt32 trigSource = Hd.currProduct!.Ctrl_Trigger!.CurrentTrigSource(); if (trigSource >= (ChannelIdExt.AnaChnlNum)) trigSource = (UInt32)ChannelIdExt.AnaChnlNum-1; ChannelBdAdcInputDefine? v = Hd.AnalogChannel?.GetChannelAcqBdAdcInputCorresponding((Int32)trigSource); if (v != null) { Hd.currProduct?.AcqBd?.WriteToAllFpga(AcqBdReg.W.LSCtrl_WriteEnable, v.BdNo, 0);//写使能 Hd.currProduct?.AcqBd?.WriteToAllFpga(AcqBdReg.W.LSCtrl_WriteEnable, v.BdNo, 1); } } internal const Int32 PhyAnalogChAmplitudeTemperaturesCompensationIntervalByMs = 2 * 60 * 1000; static Stopwatch Stopwatch_AmplitudeTemperatureCompensate = new Stopwatch(); private static void DoAmplitudeTemperatureCompensate() { if (Hd.CurrDebugVarints.bEnable_AmplitudeTemperatureCompensate) { if (Stopwatch_AmplitudeTemperatureCompensate.ElapsedMilliseconds > (PhyAnalogChAmplitudeTemperaturesCompensationIntervalByMs)) { SysMonitor.Default.ReadAnalogChannelTemperatures(); if (Hd.currProduct.Acquirer_AnalogChannel!.GetPhyAnalogChAmplitudeTemperaturesCompensationCoefficient(out _)) { Stopwatch_AmplitudeTemperatureCompensate.Restart(); AbstractController_AnalogChannel.CtrlGainByFpga(); } } } } internal static void InitAcq(bool bForce) { if (bForce) { DoAmplitudeTemperatureCompensate(); HdIO.WriteReg(ProcBdReg.W.FifoCtrl_AcqWriteEnable, 0); HdIO.WriteReg(PcieBdReg.W.RST_CTRL_SysResetFromPcie, 0x1);//处于复位中(态),为0时开始工作 Hd.currProduct?.AcqBd?.WriteToAllFpga(AcqBdReg.W.Scan_AcqScanEnable, Hd.CurrHdMessage!.Timebase!.IsScan ? 1U : 0);//采集板SCAN模式开启1,关闭0 HdIO.WriteReg(ProcBdReg.W.Scan_ProScanEnable, Hd.CurrHdMessage!.Timebase!.IsScan ? 1U : 0); //处理板SCAN模式开启1,关闭0 foreach (AbstractAcquirer? acquirer in allAcquirer) acquirer?.InitAcq(); //发令枪 StartingGunPang(); } } internal static void CreateAcquireAttribute() { foreach (AbstractAcquirer? acquirer in allAcquirer) acquirer?.CreateAcquireAttribute(); } internal static DateTime lastSimulateScanTime = DateTime.Now; internal static Boolean Acquire() { Hd.trigState = AbstractController_Misc.ReadTrigStatus(); bool bAcqOk = false; if (HdIO.CurrDriver == null || !HdIO.CurrDriver.bOpen || Hd.bPowerOff) { if ((Hd.CurrHdMessage?.Timebase?.IsScan ?? false)) { //模拟Scan double xDiv = Hd.CurrHdMessage!.Timebase.TmbScale / 1000; if ((DateTime.Now - lastSimulateScanTime).TotalMilliseconds < xDiv) { Hd.bAcqedNewData = false; bAcqOk = false; } else { lastSimulateScanTime = DateTime.Now; Hd.bAcqedNewData = true; bAcqOk = true; } } else bAcqOk = true; } else bAcqOk = AbstractController_Misc.AcqIsFulled(); if (bAcqOk) { foreach (AbstractAcquirer? acquirer in allAcquirer) { if (acquirer?.ReadAcqData() ?? false) acquirer?.PostProcess(); } InitAcq(!Hd.CurrHdMessage?.Timebase?.IsScan ?? true); } return bAcqOk; } internal record FifoDepthDefine() { public UInt32 Proc_FullProgDepth = 12288; public UInt32 Pcie_FullProgDepth = 12288; public UInt32 Pcie_ReadFromFIFO_Count = 15000; } private static Dictionary allDataTypeDepthDefine = new Dictionary() { [DMAReadSourceMuxType.AnalogChanneData] = new() { Pcie_FullProgDepth = 12288, Pcie_ReadFromFIFO_Count = 15000, Proc_FullProgDepth = 12288 }, [DMAReadSourceMuxType.Decoder] = new() { Pcie_FullProgDepth = 12288, Pcie_ReadFromFIFO_Count = 15000, Proc_FullProgDepth = 12288 }, [DMAReadSourceMuxType.Dpx] = new() { Pcie_FullProgDepth = 12288, Pcie_ReadFromFIFO_Count = 15000, Proc_FullProgDepth = 12288 }, [DMAReadSourceMuxType.LA] = new() { Pcie_FullProgDepth = 12288, Pcie_ReadFromFIFO_Count = 15000, Proc_FullProgDepth = 12288 }, [DMAReadSourceMuxType.FreqDomain] = new() { Pcie_FullProgDepth = 12288, Pcie_ReadFromFIFO_Count = 15000, Proc_FullProgDepth = 12288 }, [DMAReadSourceMuxType.DDRFast] = new() { Pcie_FullProgDepth = 12288, Pcie_ReadFromFIFO_Count = 15000, Proc_FullProgDepth = 12288 }, }; internal static void SwitchDataPathMuxTo(DMAReadSourceMuxType toType, FifoDepthDefine? fifoDepthDefine = null) { FifoDepthDefine ourFifoDepthDefine = fifoDepthDefine == null ? allDataTypeDepthDefine[toType] : fifoDepthDefine; HdIO.WriteReg(ProcBdReg.W.FifoCtrl_FullProgDepth, ourFifoDepthDefine.Proc_FullProgDepth); HdIO.WriteReg(PcieBdReg.W.FifoCtrl_FullProgDepth, ourFifoDepthDefine.Pcie_FullProgDepth); HdIO.WriteReg(PcieBdReg.W.FifoCtrl_ReadFromFIFO_Num, ourFifoDepthDefine.Pcie_ReadFromFIFO_Count); Hd.currProduct?.AcqBd?.WriteToAllFpga(AcqBdReg.W.DataPath_acq_linkmux_select, (UInt32)toType); HdIO.WriteReg(ProcBdReg.W.DataPath_pro_linkmux_select, (UInt32)toType); HdIO.WriteReg(ProcBdReg.W.DataPath_pro_linkdemux_select, (UInt32)toType); HdIO.WriteReg(PcieBdReg.W.DataPath_pcie_linkdemux_select, (UInt32)toType); } } }