import { ref, watchEffect } from 'vue' import { defineStore } from 'pinia' import { isString, toNumber, isUndefined } from 'lodash'; import { Common } from '@/Common'; import z from "zod" import { isNumber } from 'mathjs'; import { JtagClient } from "@/APIClient"; import { Mutex, withTimeout } from 'async-mutex'; import { useConstraintsStore } from "@/stores/constraints"; import { useDialogStore } from './dialog'; export const useEquipments = defineStore('equipments', () => { // Global Stores const constrainsts = useConstraintsStore(); const dialog = useDialogStore(); const boardAddr = ref("127.0.0.1"); const boardPort = ref(1234); const jtagBitstream = ref(); const jtagBoundaryScanFreq = ref(100); const jtagClientMutex = withTimeout(new Mutex(), 1000, new Error("JtagClient Mutex Timeout!")) const jtagClient = new JtagClient(); const enableJtagBoundaryScan = ref(false); function setAddr(address: string | undefined): boolean { if (isString(address) && z.string().ip("4").safeParse(address).success) { boardAddr.value = address; return true; } return false; } function setPort(port: string | number | undefined): boolean { if (isString(port) && port.length != 0) { const portNumber = toNumber(port); if (z.number().nonnegative().max(65535).safeParse(portNumber).success) { boardPort.value = portNumber; return true; } } else if (isNumber(port)) { if (z.number().nonnegative().max(65535).safeParse(port).success) { boardPort.value = port; return true; } } return false; } watchEffect(() => { if (enableJtagBoundaryScan.value) jtagBoundaryScan(); }); async function jtagBoundaryScan() { const release = await jtagClientMutex.acquire(); try { const portStates = await jtagClient.boundaryScanLogicalPorts( boardAddr.value, boardPort.value, ); constrainsts.batchSetConstraintStates(portStates); } catch (error) { dialog.error("边界扫描发生错误"); console.error(error); enableJtagBoundaryScan.value = false; } finally { release(); if (enableJtagBoundaryScan.value) setTimeout(jtagBoundaryScan, 1000 / jtagBoundaryScanFreq.value); } } async function jtagUploadBitstream(bitstream: File): Promise { try { const resp = await jtagClient.uploadBitstream( boardAddr.value, Common.toFileParameterOrNull(bitstream), ); return resp; } catch (e) { dialog.error("上传错误"); console.error(e); return false; } } async function jtagDownloadBitstream(): Promise { const release = await jtagClientMutex.acquire(); try { 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 { const release = await jtagClientMutex.acquire(); try { 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 { const release = await jtagClientMutex.acquire(); try { const resp = await jtagClient.setSpeed( boardAddr.value, boardPort.value, speed ); return resp; } catch (e) { dialog.error("设置Jtag速度失败"); return false; } finally { release(); } } return { boardAddr, boardPort, setAddr, setPort, jtagBitstream, jtagBoundaryScanFreq, jtagClientMutex, jtagClient, jtagUploadBitstream, jtagDownloadBitstream, jtagGetIDCode, jtagSetSpeed, enableJtagBoundaryScan, } })