diff --git a/server/src/Controllers/OscilloscopeController.cs b/server/src/Controllers/OscilloscopeController.cs index dee7b48..046426a 100644 --- a/server/src/Controllers/OscilloscopeController.cs +++ b/server/src/Controllers/OscilloscopeController.cs @@ -118,16 +118,16 @@ public class OscilloscopeApiController : ControllerBase return StatusCode(StatusCodes.Status500InternalServerError, "设置抽样率失败"); } - // 刷新RAM - if (config.AutoRefreshRAM) - { - var refreshResult = await oscilloscope.RefreshRAM(); - if (!refreshResult.IsSuccessful) - { - logger.Error($"刷新RAM失败: {refreshResult.Error}"); - return StatusCode(StatusCodes.Status500InternalServerError, "刷新RAM失败"); - } - } + // // 刷新RAM + // if (config.AutoRefreshRAM) + // { + // var refreshResult = await oscilloscope.RefreshRAM(); + // if (!refreshResult.IsSuccessful) + // { + // logger.Error($"刷新RAM失败: {refreshResult.Error}"); + // return StatusCode(StatusCodes.Status500InternalServerError, "刷新RAM失败"); + // } + // } // 设置捕获开关 var captureResult = await oscilloscope.SetCaptureEnable(config.CaptureEnabled); diff --git a/server/src/Peripherals/OscilloscopeClient.cs b/server/src/Peripherals/OscilloscopeClient.cs index d3055a1..1726775 100644 --- a/server/src/Peripherals/OscilloscopeClient.cs +++ b/server/src/Peripherals/OscilloscopeClient.cs @@ -24,40 +24,45 @@ static class OscilloscopeAddr /// public const UInt32 TRIG_EDGE = BASE + 0x0000_0002; - /// - /// 0x0000_0003: R/W[9:0] h shift 水平偏移量 - /// - public const UInt32 H_SHIFT = BASE + 0x0000_0003; - /// /// 0x0000_0004: R/W[9:0] deci rate 抽样率,0—1023 /// - public const UInt32 DECI_RATE = BASE + 0x0000_0004; + public const UInt32 DECI_RATE = BASE + 0x0000_0003; /// /// 0x0000_0005:R/W[0] ram refresh RAM刷新 /// - public const UInt32 RAM_FRESH = BASE + 0x0000_0005; + public const UInt32 RAM_FRESH = BASE + 0x0000_0004; + + /// + /// 0x0000_0005:R/W[0] wave ready 波形数据就绪 + /// + public const UInt32 WAVE_READY = BASE + 0x0000_0005; + + /// + /// 0x0000_0005:R/W[0] trig postion 触发地址 + /// + public const UInt32 TRIG_POSIION = BASE + 0x0000_0006; /// /// 0x0000 0006:R[19: 0] ad_freq AD采样频率 /// - public const UInt32 AD_FREQ = BASE + 0x0000_0006; + public const UInt32 AD_FREQ = BASE + 0x0000_0007; /// /// Ox0000_0007: R[7:0] ad_vpp AD采样幅度 /// - public const UInt32 AD_VPP = BASE + 0x0000_0007; + public const UInt32 AD_VPP = BASE + 0x0000_0008; /// /// 0x0000_0008: R[7:0] ad max AD采样最大值 /// - public const UInt32 AD_MAX = BASE + 0x0000_0008; + public const UInt32 AD_MAX = BASE + 0x0000_0009; /// /// 0x0000_0009: R[7:0] ad_min AD采样最小值 /// - public const UInt32 AD_MIN = BASE + 0x0000_0009; + public const UInt32 AD_MIN = BASE + 0x0000_000A; /// /// 0x0000_1000-0x0000_13FF:R[7:0] wave_rd_data 共1024个字节 @@ -165,20 +170,6 @@ class Oscilloscope /// 操作结果,成功返回true,否则返回异常信息 public async ValueTask> SetHorizontalShift(UInt16 shift) { - if (shift > 1023) - return new(new ArgumentException("Horizontal shift must be 0-1023", nameof(shift))); - - var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, OscilloscopeAddr.H_SHIFT, shift, this.timeout); - if (!ret.IsSuccessful) - { - logger.Error($"Failed to set horizontal shift: {ret.Error}"); - return new(ret.Error); - } - if (!ret.Value) - { - logger.Error("WriteAddr to H_SHIFT returned false"); - return new(new Exception("Failed to set horizontal shift")); - } return true; } @@ -315,6 +306,23 @@ class Oscilloscope /// 操作结果,成功返回采样数据数组,否则返回异常信息 public async ValueTask> GetWaveformData() { + // 等待WAVE_READY[0]位为1,最多等待50ms(5次x10ms间隔) + var readyResult = await UDPClientPool.ReadAddrWithWait( + this.ep, this.taskID, OscilloscopeAddr.WAVE_READY, 0b00, 0x01, 10, 50); + + if (!readyResult.IsSuccessful) + { + logger.Error($"Failed to wait for wave ready: {readyResult.Error}"); + return new(readyResult.Error); + } + + // 无论准备好与否,都继续读取数据(readyResult.Value表示是否在超时前准备好) + if (!readyResult.Value) + { + logger.Warn("Wave data may not be ready, but continuing to read"); + } + + // 无论准备好与否,都继续读取数据 var ret = await UDPClientPool.ReadAddr4BytesAsync( this.ep, this.taskID, @@ -345,6 +353,42 @@ class Oscilloscope waveformData[i] = data[4 * i + 3]; } - return waveformData; + // 获取触发地址用作数据偏移量 + var trigPosResult = await UDPClientPool.ReadAddrByte(this.ep, this.taskID, OscilloscopeAddr.TRIG_POSIION, this.timeout); + if (!trigPosResult.IsSuccessful) + { + logger.Error($"Failed to read trigger position: {trigPosResult.Error}"); + return new(trigPosResult.Error); + } + if (trigPosResult.Value.Options.Data == null || trigPosResult.Value.Options.Data.Length < 4) + { + logger.Error("ReadAddr returned invalid data for trigger position"); + return new(new Exception("Failed to read trigger position")); + } + + UInt32 trigAddr = Number.BytesToUInt32(trigPosResult.Value.Options.Data).Value; + + // 根据触发地址对数据进行偏移,使触发点位于数据中间 + int targetPos = sampleCount / 2; // 目标位置:数据中间 + int actualTrigPos = (int)(trigAddr % (UInt32)sampleCount); // 实际触发位置 + int shiftAmount = targetPos - actualTrigPos; + + // 创建偏移后的数据数组 + byte[] offsetData = new byte[sampleCount]; + for (int i = 0; i < sampleCount; i++) + { + int sourceIndex = (i - shiftAmount + sampleCount) % sampleCount; + offsetData[i] = waveformData[sourceIndex]; + } + + // 刷新RAM + var refreshResult = await RefreshRAM(); + if (!refreshResult.IsSuccessful) + { + logger.Error($"Failed to refresh RAM after reading waveform data: {refreshResult.Error}"); + return new(refreshResult.Error); + } + + return offsetData; } }