import { createInjectionState } from "@vueuse/core"; import { shallowRef, reactive, ref, computed } from "vue"; import { Mutex } from "async-mutex"; import { CaptureConfig, CaptureStatus, LogicAnalyzerClient, GlobalCaptureMode, SignalOperator, SignalTriggerConfig, SignalValue, } from "@/APIClient"; import { AuthManager } from "@/utils/AuthManager"; import { useAlertStore } from "@/components/Alert"; import { useRequiredInjection } from "@/utils/Common"; export type LogicDataType = { x: number[]; y: number[][]; // 8 channels of digital data (0 or 1) xUnit: "s" | "ms" | "us" | "ns"; }; // 通道接口定义 export type Channel = { enabled: boolean; label: string; color: string; }; // 全局模式选项 const globalModes = [ { value: GlobalCaptureMode.AND, label: "AND", description: "所有条件都满足时触发", }, { value: GlobalCaptureMode.OR, label: "OR", description: "任一条件满足时触发", }, { value: GlobalCaptureMode.NAND, label: "NAND", description: "AND的非" }, { value: GlobalCaptureMode.NOR, label: "NOR", description: "OR的非" }, ]; // 操作符选项 const operators = [ { value: SignalOperator.Equal, label: "=" }, { value: SignalOperator.NotEqual, label: "≠" }, { value: SignalOperator.LessThan, label: "<" }, { value: SignalOperator.LessThanOrEqual, label: "≤" }, { value: SignalOperator.GreaterThan, label: ">" }, { value: SignalOperator.GreaterThanOrEqual, label: "≥" }, ]; // 信号值选项 const signalValues = [ { value: SignalValue.Logic0, label: "0" }, { value: SignalValue.Logic1, label: "1" }, { value: SignalValue.NotCare, label: "X" }, { value: SignalValue.Rise, label: "↑" }, { value: SignalValue.Fall, label: "↓" }, { value: SignalValue.RiseOrFall, label: "↕" }, { value: SignalValue.NoChange, label: "—" }, { value: SignalValue.SomeNumber, label: "#" }, ]; // 默认颜色数组 const defaultColors = [ "#FF5733", "#33FF57", "#3357FF", "#FF33F5", "#F5FF33", "#33FFF5", "#FF8C33", "#8C33FF", ]; // 添加逻辑分析仪频率常量 const LOGIC_ANALYZER_FREQUENCY = 5_000_000; // 5MHz const SAMPLE_PERIOD_NS = 1_000_000_000 / LOGIC_ANALYZER_FREQUENCY; // 采样周期,单位:纳秒 const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState( () => { const logicData = shallowRef(); const alert = useRequiredInjection(useAlertStore); // 添加互斥锁 const operationMutex = new Mutex(); // 触发设置相关状态 const currentGlobalMode = ref(GlobalCaptureMode.AND); const isApplying = ref(false); const isCapturing = ref(false); // 添加捕获状态标识 // 通道配置 const channels = reactive( Array.from({ length: 8 }, (_, index) => ({ enabled: false, label: `CH${index}`, color: defaultColors[index], })), ); // 8个信号通道的配置 const signalConfigs = reactive( Array.from( { length: 8 }, (_, index) => new SignalTriggerConfig({ signalIndex: index, operator: SignalOperator.Equal, value: SignalValue.NotCare, }), ), ); // 计算启用的通道数量 const enabledChannelCount = computed( () => channels.filter((channel) => channel.enabled).length, ); // 添加计算属性:获取通道名称数组 const channelNames = computed(() => channels.map((channel) => channel.label), ); // 添加计算属性:获取启用通道的名称数组 const enabledChannels = computed(() => channels.filter((channel) => channel.enabled), ); const enableAllChannels = () => { channels.forEach((channel) => { channel.enabled = true; }); }; const disableAllChannels = () => { channels.forEach((channel) => { channel.enabled = false; }); }; const setGlobalMode = async (mode: GlobalCaptureMode) => { // 检查是否有其他操作正在进行 if (operationMutex.isLocked()) { alert.warn("有其他操作正在进行中,请稍后再试", 3000); return; } const release = await operationMutex.acquire(); try { const client = AuthManager.createAuthenticatedLogicAnalyzerClient(); const success = await client.setGlobalTrigMode(mode); if (success) { currentGlobalMode.value = mode; alert?.success( `全局触发模式已设置为 ${globalModes.find((m) => m.value === mode)?.label}`, 3000, ); } else { throw new Error("设置失败"); } } catch (error) { console.error("设置全局触发模式失败:", error); alert?.error("设置全局触发模式失败", 3000); } finally { release(); } }; const applyConfiguration = async () => { // 检查是否有其他操作正在进行 if (operationMutex.isLocked()) { alert.warn("有其他操作正在进行中,请稍后再试", 3000); return; } const release = await operationMutex.acquire(); isApplying.value = true; try { const client = AuthManager.createAuthenticatedLogicAnalyzerClient(); // 准备配置数据 - 只包含启用的通道 const enabledSignals = signalConfigs.filter( (signal, index) => channels[index].enabled, ); const config = new CaptureConfig({ globalMode: currentGlobalMode.value, signalConfigs: enabledSignals, }); // 发送配置 const success = await client.configureCapture(config); if (success) { const enabledChannelCount = channels.filter( (ch) => ch.enabled, ).length; alert?.success( `配置已成功应用,启用了 ${enabledChannelCount} 个通道和触发条件`, 3000, ); } else { throw new Error("应用配置失败"); } } catch (error) { console.error("应用配置失败:", error); alert?.error("应用配置失败,请检查设备连接", 3000); } finally { isApplying.value = false; release(); } }; const resetConfiguration = () => { currentGlobalMode.value = GlobalCaptureMode.AND; channels.forEach((channel, index) => { channel.enabled = false; channel.label = `CH${index}`; channel.color = defaultColors[index]; }); signalConfigs.forEach((signal) => { signal.operator = SignalOperator.Equal; signal.value = SignalValue.NotCare; }); alert?.info("配置已重置", 2000); }; // 添加设置逻辑数据的方法 const setLogicData = (data: LogicDataType) => { logicData.value = data; }; const getCaptureData = async () => { try { const client = AuthManager.createAuthenticatedLogicAnalyzerClient(); // 3. 获取捕获数据 const base64Data = await client.getCaptureData(); // 4. 将base64数据转换为bytes const binaryString = atob(base64Data); const bytes = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } // 5. 解析数据为8个通道的数字信号 const sampleCount = bytes.length; const timeStepNs = SAMPLE_PERIOD_NS; // 每个采样点间隔200ns (1/5MHz) // 创建时间轴(转换为合适的单位) const x = Array.from( { length: sampleCount }, (_, i) => (i * timeStepNs) / 1000, ); // 转换为微秒 // 创建8个通道的数据 const y: number[][] = Array.from( { length: 8 }, () => new Array(sampleCount), ); // 解析每个字节的8个位到对应通道 for (let i = 0; i < sampleCount; i++) { const byte = bytes[i]; for (let channel = 0; channel < 8; channel++) { // bit0对应ch0, bit1对应ch1, ..., bit7对应ch7 y[channel][i] = (byte >> channel) & 1; } } // 6. 设置逻辑数据 const logicData: LogicDataType = { x, y, xUnit: "us", // 改为微秒单位 }; setLogicData(logicData); } catch (error) { console.error("获取捕获数据失败:", error); } }; const startCapture = async () => { // 检查是否有其他操作正在进行 if (operationMutex.isLocked()) { alert.warn("有其他操作正在进行中,请稍后再试", 3000); return; } isCapturing.value = true; const release = await operationMutex.acquire(); try { const client = AuthManager.createAuthenticatedLogicAnalyzerClient(); // 1. 设置捕获模式为开始捕获 const captureStarted = await client.setCaptureMode(true, false); if (!captureStarted) { throw new Error("无法启动捕获"); } alert?.info("开始捕获信号...", 2000); // 2. 轮询捕获状态 let captureCompleted = false; while (isCapturing.value) { const status = await client.getCaptureStatus(); // 检查是否捕获完成 if (status === CaptureStatus.CaptureDone) { captureCompleted = true; break; } // 检查是否仍在捕获中 if ( status === CaptureStatus.CaptureBusy || status === CaptureStatus.CaptureOn || status === CaptureStatus.CaptureForce ) { // 等待500毫秒后继续轮询 await new Promise((resolve) => setTimeout(resolve, 500)); continue; } // 其他状态视为错误 // throw new Error(`捕获状态异常: ${status}`); } // 如果捕获被停止,不继续处理数据 if (!captureCompleted) { alert?.info("捕获已停止", 2000); return; } await getCaptureData(); alert.success(`捕获完成!`, 3000); } catch (error) { console.error("捕获失败:", error); alert?.error( `捕获失败: ${error instanceof Error ? error.message : "未知错误"}`, 3000, ); } finally { isCapturing.value = false; release(); } }; const stopCapture = async () => { // 检查是否正在捕获 if (!isCapturing.value) { alert.warn("当前没有正在进行的捕获操作", 2000); return; } // 设置捕获状态为false,这会使轮询停止 isCapturing.value = false; const release = await operationMutex.acquire(); try { const client = AuthManager.createAuthenticatedLogicAnalyzerClient(); // 执行强制捕获来停止当前捕获 const forceSuccess = await client.setCaptureMode(false, false); if (!forceSuccess) { throw new Error("无法停止捕获"); } alert.info("已停止强制捕获...", 2000); } catch (error) { console.error("停止捕获失败:", error); alert.error( `停止捕获失败: ${error instanceof Error ? error.message : "未知错误"}`, 3000, ); } finally { release(); } }; const forceCapture = async () => { // 设置捕获状态为false,这会使轮询停止 isCapturing.value = false; const release = await operationMutex.acquire(); try { const client = AuthManager.createAuthenticatedLogicAnalyzerClient(); // 执行强制捕获来停止当前捕获 const forceSuccess = await client.setCaptureMode(true, true); if (!forceSuccess) { throw new Error("无法执行强制捕获"); } await getCaptureData(); alert.success(`捕获完成!`, 3000); } catch (error) { console.error("强制捕获失败:", error); alert.error( `强制捕获失败: ${error instanceof Error ? error.message : "未知错误"}`, 3000, ); } finally{ release(); } }; // 添加检查操作状态的计算属性 const isOperationInProgress = computed( () => isApplying.value || isCapturing.value || operationMutex.isLocked(), ); // 添加生成测试数据的方法 const generateTestData = () => { const sampleRate = LOGIC_ANALYZER_FREQUENCY; // 使用实际的逻辑分析仪频率 const duration = 0.001; // 1ms的数据 const points = Math.floor(sampleRate * duration); const x = Array.from( { length: points }, (_, i) => (i * SAMPLE_PERIOD_NS) / 1000, // 时间轴,单位:微秒 ); // Generate 8 channels with different digital patterns const y = [ // Channel 0: Clock signal 1MHz Array.from( { length: points }, (_, i) => Math.floor((1_000_000 * i) / sampleRate) % 2, ), // Channel 1: Clock/2 signal 500kHz Array.from( { length: points }, (_, i) => Math.floor((500_000 * i) / sampleRate) % 2, ), // Channel 2: Clock/4 signal 250kHz Array.from( { length: points }, (_, i) => Math.floor((250_000 * i) / sampleRate) % 2, ), // Channel 3: Clock/8 signal 125kHz Array.from( { length: points }, (_, i) => Math.floor((125_000 * i) / sampleRate) % 2, ), // Channel 4: Data signal (pseudo-random pattern) Array.from({ length: points }, (_, i) => Math.abs(Math.floor(Math.sin(i * 0.001) * 10) % 2), ), // Channel 5: Enable signal (periodic pulse) Array.from({ length: points }, (_, i) => Math.floor(i / 250) % 10 < 3 ? 1 : 0, ), // Channel 6: Reset signal (occasional pulse) Array.from({ length: points }, (_, i) => Math.floor(i / 1000) % 20 === 0 ? 1 : 0, ), // Channel 7: Status signal (slow changing) Array.from({ length: points }, (_, i) => Math.floor(i / 5000) % 2), ]; // 同时更新通道标签为更有意义的名称 const testChannelNames = [ "CLK", "CLK/2", "CLK/4", "CLK/8", "PWM", "ENABLE", "RESET", "STATUS", ]; channels.forEach((channel, index) => { channel.label = testChannelNames[index]; }); // 设置逻辑数据 enableAllChannels(); setLogicData({ x, y, xUnit: "us" }); // 改为微秒单位 alert?.success("测试数据生成成功", 2000); }; return { // 原有的逻辑数据 logicData, // 触发设置状态 currentGlobalMode, isApplying, isCapturing, // 导出捕获状态 isOperationInProgress, // 导出操作进行状态 channels, signalConfigs, enabledChannelCount, channelNames, enabledChannels, // 选项数据 globalModes, operators, signalValues, // 触发设置方法 enableAllChannels, disableAllChannels, setGlobalMode, applyConfiguration, resetConfiguration, setLogicData, startCapture, forceCapture, stopCapture, generateTestData, }; }, ); export { useProvideLogicAnalyzer, useLogicAnalyzerState };