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