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);
}
}
}