using System.Net; using DotNext; namespace Peripherals.DDSClient; static class DDSAddr { /*地址定义:(以2路输出,4波形存储为例) 00 R/W CHANNEL0 wave_sel 01 R/W CHANNEL0 STORE0 freq_ctrl 02 R/W CHANNEL0 STORE1 freq_ctrl 03 R/W CHANNEL0 STORE2 freq_ctrl 04 R/W CHANNEL0 STORE3 freq_ctrl 05 R/W CHANNEL0 STORE0 phase_ctrl 06 R/W CHANNEL0 STORE1 phase_ctrl 07 R/W CHANNEL0 STORE2 phase_ctrl 08 R/W CHANNEL0 STORE3 phase_ctrl 09 R/W CHANNEL0 dds_wr_enable 0A WO CHANNEL0 data 10 R/W CHANNEL1 wave_sel 11 R/W CHANNEL1 STORE0 freq_ctrl 12 R/W CHANNEL1 STORE1 freq_ctrl 13 R/W CHANNEL1 STORE2 freq_ctrl 14 R/W CHANNEL1 STORE3 freq_ctrl 15 R/W CHANNEL1 STORE0 phase_ctrl 16 R/W CHANNEL1 STORE1 phase_ctrl 17 R/W CHANNEL1 STORE2 phase_ctrl 18 R/W CHANNEL1 STORE3 phase_ctrl 19 R/W CHANNEL1 dds_wr_enable 1A WO CHANNEL1 data */ public const UInt32 Base = 0x4000_0000; public static readonly ChannelAddr[] Channel = { new ChannelAddr(0x00), new ChannelAddr(0x10) }; public class ChannelAddr { private readonly UInt32 Offset; public readonly UInt32 WaveSelect; public readonly UInt32[] FreqCtrl; public readonly UInt32[] PhaseCtrl; public readonly UInt32 WriteEnable; public readonly UInt32 WriteData; public ChannelAddr(UInt32 offset) { this.Offset = offset; this.WaveSelect = Base + Offset + 0x00; this.FreqCtrl = new UInt32[] { Base + offset + 0x01, Base + offset + 0x02, Base + offset + 0x03, Base + offset + 0x04 }; this.PhaseCtrl = new UInt32[] { Base + Offset + 0x05, Base + Offset + 0x06, Base + Offset + 0x07, Base + Offset + 0x08 }; this.WriteEnable = Base + Offset + 0x09; this.WriteData = Base + Offset + 0x0A; } } } /// /// [TODO:description] /// public class DDS { private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); readonly int timeout = 2000; readonly int port; readonly string address; private IPEndPoint ep; /// /// [TODO:description] /// /// [TODO:parameter] /// [TODO:parameter] /// [TODO:parameter] /// [TODO:return] public DDS(string address, int port, int timeout = 2000) { if (timeout < 0) throw new ArgumentException("Timeout couldn't be negative", nameof(timeout)); this.address = address; this.port = port; this.ep = new IPEndPoint(IPAddress.Parse(address), port); this.timeout = timeout; } /// /// [TODO:description] /// /// [TODO:parameter] /// [TODO:parameter] /// [TODO:return] public async ValueTask> SetWaveNum(int channelNum, int waveNum) { if (channelNum < 0 || channelNum > 1) return new(new ArgumentException( $"Channel number should be 0 ~ 1 instead of {channelNum}", nameof(channelNum))); if (waveNum < 0 || waveNum > 3) return new(new ArgumentException( $"Wave number should be 0 ~ 3 instead of {waveNum}", nameof(waveNum))); await MsgBus.UDPServer.ClearUDPData(this.address, 1); logger.Trace("Clear udp data finished"); var ret = await UDPClientPool.WriteAddr( this.ep, 1, DDSAddr.Channel[channelNum].WaveSelect, (UInt32)waveNum, this.timeout); if (!ret.IsSuccessful) return new(ret.Error); return ret.Value; } /// /// [TODO:description] /// /// [TODO:parameter] /// [TODO:parameter] /// [TODO:parameter] /// [TODO:return] public async ValueTask> SetFreq(int channelNum, int waveNum, UInt32 step) { if (channelNum < 0 || channelNum > 1) return new(new ArgumentException( $"Channel number should be 0 ~ 1 instead of {channelNum}", nameof(channelNum))); if (waveNum < 0 || waveNum > 3) return new(new ArgumentException( $"Wave number should be 0 ~ 3 instead of {waveNum}", nameof(waveNum))); await MsgBus.UDPServer.ClearUDPData(this.address, 1); logger.Trace("Clear udp data finished"); var ret = await UDPClientPool.WriteAddr( this.ep, 1, DDSAddr.Channel[channelNum].FreqCtrl[waveNum], step, this.timeout); if (!ret.IsSuccessful) return new(ret.Error); return ret.Value; } /// /// [TODO:description] /// /// [TODO:parameter] /// [TODO:parameter] /// [TODO:parameter] /// [TODO:return] public async ValueTask> SetPhase(int channelNum, int waveNum, int phase) { if (channelNum < 0 || channelNum > 1) return new(new ArgumentException( $"Channel number should be 0 ~ 1 instead of {channelNum}", nameof(channelNum))); if (waveNum < 0 || waveNum > 3) return new(new ArgumentException( $"Wave number should be 0 ~ 3 instead of {waveNum}", nameof(waveNum))); if (phase < 0 || phase > 4096) return new(new ArgumentException( $"Phase should be 0 ~ 4096 instead of {phase}", nameof(phase))); await MsgBus.UDPServer.ClearUDPData(this.address, 1); logger.Trace("Clear udp data finished"); var ret = await UDPClientPool.WriteAddr( this.ep, 1, DDSAddr.Channel[channelNum].PhaseCtrl[waveNum], (UInt32)phase, this.timeout); if (!ret.IsSuccessful) return new(ret.Error); return ret.Value; } }