This repository has been archived on 2025-10-29. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
FPGA_WebLab/src/components/LogicAnalyzer/LogicAnalyzerManager.ts

862 lines
27 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
AnalyzerChannelDiv,
AnalyzerClockDiv,
} 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 channelDivOptions = [
{ value: 1, label: "1通道", description: "启用1个通道 (CH0)" },
{ value: 2, label: "2通道", description: "启用2个通道 (CH0-CH1)" },
{ value: 4, label: "4通道", description: "启用4个通道 (CH0-CH3)" },
{ value: 8, label: "8通道", description: "启用8个通道 (CH0-CH7)" },
{ value: 16, label: "16通道", description: "启用16个通道 (CH0-CH15)" },
{ value: 32, label: "32通道", description: "启用32个通道 (CH0-CH31)" },
];
const ClockDivOptions = [
{
value: AnalyzerClockDiv.DIV1,
label: "120MHz",
description: "采样频率120MHz",
},
{
value: AnalyzerClockDiv.DIV2,
label: "60MHz",
description: "采样频率60MHz",
},
{
value: AnalyzerClockDiv.DIV4,
label: "30MHz",
description: "采样频率30MHz",
},
{
value: AnalyzerClockDiv.DIV8,
label: "15MHz",
description: "采样频率15MHz",
},
{
value: AnalyzerClockDiv.DIV16,
label: "7.5MHz",
description: "采样频率7.5MHz",
},
{
value: AnalyzerClockDiv.DIV32,
label: "3.75MHz",
description: "采样频率3.75MHz",
},
{
value: AnalyzerClockDiv.DIV64,
label: "1.875MHz",
description: "采样频率1.875MHz",
},
{
value: AnalyzerClockDiv.DIV128,
label: "937.5KHz",
description: "采样频率937.5KHz",
},
];
// 捕获深度限制常量
const CAPTURE_LENGTH_MIN = 1024; // 最小捕获深度 1024
const CAPTURE_LENGTH_MAX = 0x10000000 - 0x01000000; // 最大捕获深度
// 预捕获深度限制常量
const PRE_CAPTURE_LENGTH_MIN = 2; // 最小预捕获深度 2
// 默认颜色数组
const defaultColors = [
"#FF5733",
"#33FF57",
"#3357FF",
"#FF33F5",
"#F5FF33",
"#33FFF5",
"#FF8C33",
"#8C33FF",
];
// 添加逻辑分析仪基础频率常量
const BASE_LOGIC_ANALYZER_FREQUENCY = 120_000_000; // 120MHz基础频率
const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState(
() => {
const logicData = shallowRef<LogicDataType>();
const alert = useRequiredInjection(useAlertStore);
// 添加互斥锁
const operationMutex = new Mutex();
// 触发设置相关状态
const currentGlobalMode = ref<GlobalCaptureMode>(GlobalCaptureMode.AND);
const currentChannelDiv = ref<number>(8); // 默认启用8个通道
const captureLength = ref<number>(CAPTURE_LENGTH_MIN); // 捕获深度,默认为最小值
const preCaptureLength = ref<number>(PRE_CAPTURE_LENGTH_MIN); // 预捕获深度默认0
const currentclockDiv = ref<AnalyzerClockDiv>(AnalyzerClockDiv.DIV1); // 默认时钟分频为1
const isApplying = ref(false);
const isCapturing = ref(false); // 添加捕获状态标识
// 通道配置
const channels = reactive<Channel[]>(
Array.from({ length: 32 }, (_, index) => ({
enabled: index < 8, // 默认启用前8个通道
label: `CH${index}`,
color: defaultColors[index % defaultColors.length], // 使用模运算避免数组越界
})),
);
// 32个信号通道的配置
const signalConfigs = reactive<SignalTriggerConfig[]>(
Array.from(
{ length: 32 },
(_, 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 currentSampleFrequency = computed(() => {
const divValue = Math.pow(2, currentclockDiv.value);
return BASE_LOGIC_ANALYZER_FREQUENCY / divValue;
});
// 计算属性:获取当前采样周期(纳秒)
const currentSamplePeriodNs = computed(() => {
return 1_000_000_000 / currentSampleFrequency.value;
});
// 转换通道数字到枚举值
const getChannelDivEnum = (channelCount: number): AnalyzerChannelDiv => {
switch (channelCount) {
case 1:
return AnalyzerChannelDiv.ONE;
case 2:
return AnalyzerChannelDiv.TWO;
case 4:
return AnalyzerChannelDiv.FOUR;
case 8:
return AnalyzerChannelDiv.EIGHT;
case 16:
return AnalyzerChannelDiv.XVI;
case 32:
return AnalyzerChannelDiv.XXXII;
default:
return AnalyzerChannelDiv.EIGHT;
}
};
// 验证捕获深度
const validateCaptureLength = (
value: number,
): { valid: boolean; message?: string } => {
if (!Number.isInteger(value)) {
return { valid: false, message: "捕获深度必须是整数" };
}
if (value < CAPTURE_LENGTH_MIN) {
return {
valid: false,
message: `捕获深度不能小于 ${CAPTURE_LENGTH_MIN}`,
};
}
if (value > CAPTURE_LENGTH_MAX) {
return {
valid: false,
message: `捕获深度不能大于 ${CAPTURE_LENGTH_MAX.toLocaleString()}`,
};
}
return { valid: true };
};
// 验证预捕获深度
const validatePreCaptureLength = (
value: number,
currentCaptureLength: number,
): { valid: boolean; message?: string } => {
if (!Number.isInteger(value)) {
return { valid: false, message: "预捕获深度必须是整数" };
}
if (value < PRE_CAPTURE_LENGTH_MIN) {
return {
valid: false,
message: `预捕获深度不能小于 ${PRE_CAPTURE_LENGTH_MIN}`,
};
}
if (value >= currentCaptureLength) {
return {
valid: false,
message: `预捕获深度不能大于等于捕获深度 (${currentCaptureLength})`,
};
}
return { valid: true };
};
// 设置捕获深度
const setCaptureLength = (value: number) => {
const validation = validateCaptureLength(value);
if (!validation.valid) {
alert?.error(validation.message!, 3000);
return false;
}
// 检查预捕获深度是否仍然有效
if (preCaptureLength.value >= value) {
preCaptureLength.value = Math.max(0, value - 1);
alert?.warn(`预捕获深度已自动调整为 ${preCaptureLength.value}`, 3000);
}
captureLength.value = value;
return true;
};
// 设置预捕获深度
const setPreCaptureLength = (value: number) => {
const validation = validatePreCaptureLength(value, captureLength.value);
if (!validation.valid) {
alert?.error(validation.message!, 3000);
return false;
}
preCaptureLength.value = value;
return true;
};
// 设置通道组
const setChannelDiv = (channelCount: number) => {
// 验证通道数量是否有效
if (!channelDivOptions.find((option) => option.value === channelCount)) {
console.error(`无效的通道组设置: ${channelCount}`);
return;
}
currentChannelDiv.value = channelCount;
// 禁用所有通道
channels.forEach((channel) => {
channel.enabled = false;
});
// 启用指定数量的通道从CH0开始
for (let i = 0; i < channelCount && i < channels.length; i++) {
channels[i].enabled = true;
}
const option = channelDivOptions.find(
(opt) => opt.value === channelCount,
);
alert?.success(`已设置为${option?.label}`, 2000);
};
const setGlobalMode = (mode: GlobalCaptureMode) => {
currentGlobalMode.value = mode;
const modeOption = globalModes.find((m) => m.value === mode);
alert?.info(`全局触发模式已设置为 ${modeOption?.label}`, 2000);
};
const setClockDiv = (mode: AnalyzerClockDiv) => {
currentclockDiv.value = mode;
const modeOption = ClockDivOptions.find((m) => m.value === mode);
alert?.info(`时钟分频已设置为 ${modeOption?.label}`, 2000);
};
const resetConfiguration = () => {
currentGlobalMode.value = GlobalCaptureMode.AND;
currentChannelDiv.value = 8; // 重置为默认的8通道
currentclockDiv.value = AnalyzerClockDiv.DIV1; // 重置为默认采样频率
setChannelDiv(8); // 重置为默认的8通道
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.createClient(LogicAnalyzerClient);
// 获取捕获数据,使用当前设置的捕获长度
const base64Data = await client.getCaptureData(captureLength.value);
// 将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);
}
// 根据当前通道数量解析数据
const channelCount = currentChannelDiv.value;
const timeStepNs = currentSamplePeriodNs.value;
let sampleCount: number;
let x: number[];
let y: number[][];
if (channelCount === 1) {
// 1通道每个字节包含8个时间单位的数据
sampleCount = bytes.length * 8;
// 创建时间轴
x = Array.from(
{ length: sampleCount },
(_, i) => (i * timeStepNs) / 1000,
); // 转换为微秒
// 创建通道数据数组
y = Array.from({ length: 1 }, () => new Array(sampleCount));
// 解析数据每个字节的8个位对应8个时间单位
for (let byteIndex = 0; byteIndex < bytes.length; byteIndex++) {
const byte = bytes[byteIndex];
for (let bitIndex = 0; bitIndex < 8; bitIndex++) {
const timeIndex = byteIndex * 8 + bitIndex;
y[0][timeIndex] = (byte >> bitIndex) & 1;
}
}
} else if (channelCount === 2) {
// 2通道每个字节包含4个时间单位的数据
sampleCount = bytes.length * 4;
// 创建时间轴
x = Array.from(
{ length: sampleCount },
(_, i) => (i * timeStepNs) / 1000,
); // 转换为微秒
// 创建通道数据数组
y = Array.from({ length: 2 }, () => new Array(sampleCount));
// 解析数据每个字节的8个位对应4个时间单位的2通道数据
// 位分布:[T3_CH1, T3_CH0, T2_CH1, T2_CH0, T1_CH1, T1_CH0, T0_CH1, T0_CH0]
for (let byteIndex = 0; byteIndex < bytes.length; byteIndex++) {
const byte = bytes[byteIndex];
for (let timeUnit = 0; timeUnit < 4; timeUnit++) {
const timeIndex = byteIndex * 4 + timeUnit;
const bitOffset = timeUnit * 2;
y[0][timeIndex] = (byte >> bitOffset) & 1; // CH0
y[1][timeIndex] = (byte >> (bitOffset + 1)) & 1; // CH1
}
}
} else if (channelCount === 4) {
// 4通道每个字节包含2个时间单位的数据
sampleCount = bytes.length * 2;
// 创建时间轴
x = Array.from(
{ length: sampleCount },
(_, i) => (i * timeStepNs) / 1000,
); // 转换为微秒
// 创建通道数据数组
y = Array.from({ length: 4 }, () => new Array(sampleCount));
// 解析数据每个字节的8个位对应2个时间单位的4通道数据
// 位分布:[T1_CH3, T1_CH2, T1_CH1, T1_CH0, T0_CH3, T0_CH2, T0_CH1, T0_CH0]
for (let byteIndex = 0; byteIndex < bytes.length; byteIndex++) {
const byte = bytes[byteIndex];
// 处理第一个时间单位低4位
const timeIndex1 = byteIndex * 2;
for (let channel = 0; channel < 4; channel++) {
y[channel][timeIndex1] = (byte >> channel) & 1;
}
// 处理第二个时间单位高4位
const timeIndex2 = byteIndex * 2 + 1;
for (let channel = 0; channel < 4; channel++) {
y[channel][timeIndex2] = (byte >> (channel + 4)) & 1;
}
}
} else if (channelCount === 8) {
// 8通道每个字节包含1个时间单位的8个通道数据
sampleCount = bytes.length;
// 创建时间轴
x = Array.from(
{ length: sampleCount },
(_, i) => (i * timeStepNs) / 1000,
); // 转换为微秒
// 创建8个通道的数据
y = 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;
}
}
} else if (channelCount === 16) {
// 16通道每2个字节包含1个时间单位的16个通道数据
sampleCount = bytes.length / 2;
// 创建时间轴
x = Array.from(
{ length: sampleCount },
(_, i) => (i * timeStepNs) / 1000,
); // 转换为微秒
// 创建16个通道的数据
y = Array.from({ length: 16 }, () => new Array(sampleCount));
// 解析数据每2个字节为一个时间单位
for (let timeIndex = 0; timeIndex < sampleCount; timeIndex++) {
const byteIndex = timeIndex * 2;
const byte1 = bytes[byteIndex]; // [7:0]
const byte2 = bytes[byteIndex + 1]; // [15:8]
// 处理低8位通道 [7:0]
for (let channel = 0; channel < 8; channel++) {
y[channel][timeIndex] = (byte1 >> channel) & 1;
}
// 处理高8位通道 [15:8]
for (let channel = 0; channel < 8; channel++) {
y[channel + 8][timeIndex] = (byte2 >> channel) & 1;
}
}
} else if (channelCount === 32) {
// 32通道每4个字节包含1个时间单位的32个通道数据
sampleCount = bytes.length / 4;
// 创建时间轴
x = Array.from(
{ length: sampleCount },
(_, i) => (i * timeStepNs) / 1000,
); // 转换为微秒
// 创建32个通道的数据
y = Array.from({ length: 32 }, () => new Array(sampleCount));
// 解析数据每4个字节为一个时间单位
for (let timeIndex = 0; timeIndex < sampleCount; timeIndex++) {
const byteIndex = timeIndex * 4;
const byte1 = bytes[byteIndex]; // [7:0]
const byte2 = bytes[byteIndex + 1]; // [15:8]
const byte3 = bytes[byteIndex + 2]; // [23:16]
const byte4 = bytes[byteIndex + 3]; // [31:24]
// 处理 [7:0]
for (let channel = 0; channel < 8; channel++) {
y[channel][timeIndex] = (byte1 >> channel) & 1;
}
// 处理 [15:8]
for (let channel = 0; channel < 8; channel++) {
y[channel + 8][timeIndex] = (byte2 >> channel) & 1;
}
// 处理 [23:16]
for (let channel = 0; channel < 8; channel++) {
y[channel + 16][timeIndex] = (byte3 >> channel) & 1;
}
// 处理 [31:24]
for (let channel = 0; channel < 8; channel++) {
y[channel + 24][timeIndex] = (byte4 >> channel) & 1;
}
}
} else {
throw new Error(`不支持的通道数量: ${channelCount}`);
}
// 设置逻辑数据
const logicData: LogicDataType = {
x,
y,
xUnit: "us", // 微秒单位
};
setLogicData(logicData);
} catch (error) {
console.error("获取捕获数据失败:", error);
alert?.error("获取捕获数据失败", 3000);
}
};
const startCapture = async () => {
// 检查是否有其他操作正在进行
if (operationMutex.isLocked()) {
alert.warn("有其他操作正在进行中,请稍后再试", 3000);
return;
}
isCapturing.value = true;
const release = await operationMutex.acquire();
try {
const client = AuthManager.createClient(LogicAnalyzerClient);
// 1. 先应用配置
alert?.info("正在应用配置...", 2000);
// 准备配置数据 - 包含所有32个通道未启用的通道设置为默认值
const allSignals = signalConfigs.map((signal, index) => {
if (channels[index].enabled) {
// 启用的通道使用用户配置的触发条件
return signal;
} else {
// 未启用的通道设置为默认触发条件
return new SignalTriggerConfig({
signalIndex: index,
operator: SignalOperator.Equal,
value: SignalValue.NotCare,
});
}
});
const config = new CaptureConfig({
globalMode: currentGlobalMode.value,
channelDiv: getChannelDivEnum(currentChannelDiv.value),
captureLength: captureLength.value,
preCaptureLength: preCaptureLength.value,
clockDiv: currentclockDiv.value,
signalConfigs: allSignals,
});
// 发送配置
const configSuccess = await client.configureCapture(config);
if (!configSuccess) {
throw new Error("配置应用失败");
}
const enabledChannelCount = channels.filter((ch) => ch.enabled).length;
alert?.success(
`配置已应用,启用了 ${enabledChannelCount} 个通道,捕获深度: ${captureLength.value}`,
2000,
);
// 2. 设置捕获模式为开始捕获
const captureStarted = await client.setCaptureMode(true, false);
if (!captureStarted) {
throw new Error("无法启动捕获");
}
alert?.info("开始捕获信号...", 2000);
// 3. 轮询捕获状态
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.createClient(LogicAnalyzerClient);
// 执行强制捕获来停止当前捕获
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 () => {
// 检查是否正在捕获
if (!isCapturing.value) {
alert.warn("当前没有正在进行的捕获操作", 2000);
return;
}
const release = await operationMutex.acquire();
try {
const client = AuthManager.createClient(LogicAnalyzerClient);
// 执行强制捕获来停止当前捕获
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 = currentSampleFrequency.value; // 使用当前设置的采样频率
const duration = 0.001; // 1ms的数据
const points = Math.floor(sampleRate * duration);
const x = Array.from(
{ length: points },
(_, i) => (i * currentSamplePeriodNs.value) / 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];
});
// 设置逻辑数据
setChannelDiv(8);
setLogicData({ x, y, xUnit: "us" }); // 改为微秒单位
alert?.success("测试数据生成成功", 2000);
};
return {
// 原有的逻辑数据
logicData,
// 触发设置状态
currentGlobalMode,
currentChannelDiv, // 导出当前通道组状态
captureLength, // 导出捕获深度
preCaptureLength, // 导出预捕获深度
currentclockDiv, // 导出当前采样频率状态
isApplying,
isCapturing, // 导出捕获状态
isOperationInProgress, // 导出操作进行状态
channels,
signalConfigs,
enabledChannelCount,
channelNames,
enabledChannels,
currentSampleFrequency, // 导出当前采样频率
currentSamplePeriodNs, // 导出当前采样周期
// 选项数据
globalModes,
operators,
signalValues,
channelDivOptions, // 导出通道组选项
ClockDivOptions, // 导出采样频率选项
// 捕获深度常量和验证
CAPTURE_LENGTH_MIN,
CAPTURE_LENGTH_MAX,
PRE_CAPTURE_LENGTH_MIN,
validateCaptureLength,
validatePreCaptureLength,
setCaptureLength,
setPreCaptureLength,
// 触发设置方法
setChannelDiv, // 导出设置通道组方法
setGlobalMode,
setClockDiv, // 导出设置采样频率方法
resetConfiguration,
setLogicData,
startCapture,
forceCapture,
stopCapture,
generateTestData,
};
},
);
export { useProvideLogicAnalyzer, useLogicAnalyzerState };