276 lines
7.3 KiB
TypeScript
276 lines
7.3 KiB
TypeScript
import { ref, reactive, watchPostEffect, onMounted, onUnmounted } from "vue";
|
|
import { defineStore } from "pinia";
|
|
import { useLocalStorage } from "@vueuse/core";
|
|
import { isString, toNumber, type Dictionary } from "lodash";
|
|
import z from "zod";
|
|
import { isNumber } from "mathjs";
|
|
import { Mutex, withTimeout } from "async-mutex";
|
|
import { useConstraintsStore } from "@/stores/constraints";
|
|
import { useDialogStore } from "./dialog";
|
|
import { toFileParameterOrUndefined } from "@/utils/Common";
|
|
import { AuthManager } from "@/utils/AuthManager";
|
|
import { HubConnectionBuilder } from "@microsoft/signalr";
|
|
import { getHubProxyFactory, getReceiverRegister } from "@/TypedSignalR.Client";
|
|
|
|
export const useEquipments = defineStore("equipments", () => {
|
|
// Global Stores
|
|
const constrainsts = useConstraintsStore();
|
|
const dialog = useDialogStore();
|
|
|
|
const boardAddr = useLocalStorage("fpga-board-addr", "127.0.0.1");
|
|
const boardPort = useLocalStorage("fpga-board-port", 1234);
|
|
|
|
// Jtag
|
|
const jtagBitstream = ref<File>();
|
|
const jtagBoundaryScanFreq = ref(100);
|
|
const jtagClientMutex = withTimeout(
|
|
new Mutex(),
|
|
1000,
|
|
new Error("JtagClient Mutex Timeout!"),
|
|
);
|
|
const jtagHubConnection = new HubConnectionBuilder()
|
|
.withUrl("/hubs/JtagHub")
|
|
.withAutomaticReconnect()
|
|
.build();
|
|
const jtagHubProxy =
|
|
getHubProxyFactory("IJtagHub").createHubProxy(jtagHubConnection);
|
|
const jtagHubSubscription = getReceiverRegister("IJtagReceiver").register(
|
|
jtagHubConnection,
|
|
{
|
|
onReceiveBoundaryScanData: async (msg) => {
|
|
constrainsts.batchSetConstraintStates(msg);
|
|
},
|
|
},
|
|
);
|
|
onMounted(() => {
|
|
jtagHubConnection.start();
|
|
});
|
|
|
|
// Matrix Key
|
|
const matrixKeyStates = reactive(new Array<boolean>(16).fill(false));
|
|
const matrixKeypadClientMutex = withTimeout(
|
|
new Mutex(),
|
|
1000,
|
|
new Error("Matrixkeyclient Mutex Timeout!"),
|
|
);
|
|
|
|
// Power
|
|
const powerClientMutex = withTimeout(
|
|
new Mutex(),
|
|
1000,
|
|
new Error("Matrixkeyclient Mutex Timeout!"),
|
|
);
|
|
|
|
// Enable Setting
|
|
const enableJtagBoundaryScan = ref(false);
|
|
const enableMatrixKey = ref(false);
|
|
const enablePower = ref(false);
|
|
|
|
function setMatrixKey(
|
|
keyNum: number | string | undefined,
|
|
keyValue: boolean,
|
|
): boolean {
|
|
let _keyNum: number;
|
|
if (isString(keyNum)) {
|
|
_keyNum = toNumber(keyNum);
|
|
} else if (isNumber(keyNum)) {
|
|
_keyNum = keyNum;
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
if (z.number().nonnegative().max(16).safeParse(_keyNum).success) {
|
|
matrixKeyStates[_keyNum] = keyValue;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
async function jtagBoundaryScanSetOnOff(enable: boolean) {
|
|
enableJtagBoundaryScan.value = enable;
|
|
if (enable) {
|
|
jtagHubProxy.startBoundaryScan(jtagBoundaryScanFreq.value);
|
|
} else {
|
|
jtagHubProxy.stopBoundaryScan();
|
|
}
|
|
}
|
|
|
|
async function jtagUploadBitstream(bitstream: File): Promise<boolean> {
|
|
try {
|
|
// 自动开启电源
|
|
await powerSetOnOff(true);
|
|
|
|
const jtagClient = AuthManager.createAuthenticatedJtagClient();
|
|
const resp = await jtagClient.uploadBitstream(
|
|
boardAddr.value,
|
|
toFileParameterOrUndefined(bitstream),
|
|
);
|
|
return resp;
|
|
} catch (e) {
|
|
dialog.error("上传错误");
|
|
console.error(e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async function jtagDownloadBitstream(): Promise<boolean> {
|
|
const release = await jtagClientMutex.acquire();
|
|
try {
|
|
// 自动开启电源
|
|
await powerSetOnOff(true);
|
|
|
|
const jtagClient = AuthManager.createAuthenticatedJtagClient();
|
|
const resp = await jtagClient.downloadBitstream(
|
|
boardAddr.value,
|
|
boardPort.value,
|
|
);
|
|
return resp;
|
|
} catch (e) {
|
|
dialog.error("上传错误");
|
|
console.error(e);
|
|
return false;
|
|
} finally {
|
|
release();
|
|
}
|
|
}
|
|
|
|
async function jtagGetIDCode(isQuiet: boolean = false): Promise<number> {
|
|
const release = await jtagClientMutex.acquire();
|
|
try {
|
|
// 自动开启电源
|
|
await powerSetOnOff(true);
|
|
|
|
const jtagClient = AuthManager.createAuthenticatedJtagClient();
|
|
const resp = await jtagClient.getDeviceIDCode(
|
|
boardAddr.value,
|
|
boardPort.value,
|
|
);
|
|
return resp;
|
|
} catch (e) {
|
|
if (!isQuiet) dialog.error("获取IDCode错误");
|
|
return 0xffff_ffff;
|
|
} finally {
|
|
release();
|
|
}
|
|
}
|
|
|
|
async function jtagSetSpeed(speed: number): Promise<boolean> {
|
|
const release = await jtagClientMutex.acquire();
|
|
try {
|
|
// 自动开启电源
|
|
await powerSetOnOff(true);
|
|
|
|
const jtagClient = AuthManager.createAuthenticatedJtagClient();
|
|
const resp = await jtagClient.setSpeed(
|
|
boardAddr.value,
|
|
boardPort.value,
|
|
speed,
|
|
);
|
|
return resp;
|
|
} catch (e) {
|
|
dialog.error("设置Jtag速度失败");
|
|
return false;
|
|
} finally {
|
|
release();
|
|
}
|
|
}
|
|
|
|
async function matrixKeypadSetKeyStates(keyStates: boolean[]) {
|
|
const release = await matrixKeypadClientMutex.acquire();
|
|
console.log("set Key !!!!!!!!!!!!");
|
|
try {
|
|
const matrixKeypadClient =
|
|
AuthManager.createAuthenticatedMatrixKeyClient();
|
|
const resp = await matrixKeypadClient.setMatrixKeyStatus(
|
|
boardAddr.value,
|
|
boardPort.value,
|
|
keyStates,
|
|
);
|
|
return resp;
|
|
} catch (e) {
|
|
dialog.error("设置矩阵键盘时,服务器发生错误");
|
|
return false;
|
|
} finally {
|
|
release();
|
|
}
|
|
}
|
|
|
|
async function matrixKeypadEnable(enable: boolean) {
|
|
const release = await matrixKeypadClientMutex.acquire();
|
|
try {
|
|
if (enable) {
|
|
const matrixKeypadClient =
|
|
AuthManager.createAuthenticatedMatrixKeyClient();
|
|
const resp = await matrixKeypadClient.enabelMatrixKey(
|
|
boardAddr.value,
|
|
boardPort.value,
|
|
);
|
|
enableMatrixKey.value = resp;
|
|
return resp;
|
|
} else {
|
|
const matrixKeypadClient =
|
|
AuthManager.createAuthenticatedMatrixKeyClient();
|
|
const resp = await matrixKeypadClient.disableMatrixKey(
|
|
boardAddr.value,
|
|
boardPort.value,
|
|
);
|
|
enableMatrixKey.value = !resp;
|
|
return resp;
|
|
}
|
|
} catch (e) {
|
|
enableMatrixKey.value = false;
|
|
dialog.error("设置矩阵键盘是否启用时,服务器发生错误");
|
|
return false;
|
|
} finally {
|
|
release();
|
|
}
|
|
}
|
|
|
|
async function powerSetOnOff(enable: boolean) {
|
|
const release = await powerClientMutex.acquire();
|
|
try {
|
|
const powerClient = AuthManager.createAuthenticatedPowerClient();
|
|
const resp = await powerClient.setPowerOnOff(
|
|
boardAddr.value,
|
|
boardPort.value,
|
|
enable,
|
|
);
|
|
return resp;
|
|
} catch (e) {
|
|
dialog.error("无法开关电源");
|
|
console.error(e);
|
|
return false;
|
|
} finally {
|
|
release();
|
|
}
|
|
}
|
|
|
|
return {
|
|
boardAddr,
|
|
boardPort,
|
|
setMatrixKey,
|
|
|
|
// Jtag
|
|
enableJtagBoundaryScan,
|
|
jtagBoundaryScanSetOnOff,
|
|
jtagBitstream,
|
|
jtagBoundaryScanFreq,
|
|
jtagUploadBitstream,
|
|
jtagDownloadBitstream,
|
|
jtagGetIDCode,
|
|
jtagSetSpeed,
|
|
|
|
// Matrix Key
|
|
enableMatrixKey,
|
|
matrixKeyStates,
|
|
matrixKeypadClientMutex,
|
|
matrixKeypadEnable,
|
|
matrixKeypadSetKeyStates,
|
|
|
|
// Power
|
|
enablePower,
|
|
powerClientMutex,
|
|
powerSetOnOff,
|
|
};
|
|
});
|