Compare commits

..

3 Commits

9 changed files with 1057 additions and 125 deletions

View File

@ -3,6 +3,12 @@
pwd pwd
echo echo
clean:
rm -rf "server/bin"
rm -rf "server/obj"
rm -rf "server.test/bin"
rm -rf "server.test/obj"
[working-directory: "server"] [working-directory: "server"]
publish: _show-dir publish: _show-dir
dotnet publish --self-contained false -t:PublishAllRids dotnet publish --self-contained false -t:PublishAllRids

14
package-lock.json generated
View File

@ -30,6 +30,7 @@
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"daisyui": "^5.0.0", "daisyui": "^5.0.0",
"npm-run-all2": "^7.0.2", "npm-run-all2": "^7.0.2",
"nswag": "^14.3.0",
"postcss": "^8.5.3", "postcss": "^8.5.3",
"tailwindcss": "^4.0.12", "tailwindcss": "^4.0.12",
"typescript": "~5.7.3", "typescript": "~5.7.3",
@ -3172,6 +3173,19 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/nswag": {
"version": "14.3.0",
"resolved": "https://registry.npmjs.org/nswag/-/nswag-14.3.0.tgz",
"integrity": "sha512-6/vGw9VtCBn788WFyPLwO4TWxZghDy+KSELjowXt12ZAu/0n3lLfQnJ4ws4rbXrO2Jrv0Tm3uzIfYNatrrs8bQ==",
"dev": true,
"license": "MIT",
"bin": {
"nswag": "bin/nswag.js"
},
"engines": {
"npm": ">=3.10.8"
}
},
"node_modules/open": { "node_modules/open": {
"version": "10.1.1", "version": "10.1.1",
"resolved": "https://registry.npmjs.org/open/-/open-10.1.1.tgz", "resolved": "https://registry.npmjs.org/open/-/open-10.1.1.tgz",

View File

@ -1,16 +1,17 @@
{ {
"name": "fpga-weblab", "name": "fpga-weblab",
"version": "0.0.0", "version": "0.1.0",
"private": true, "private": true,
"type": "module", "type": "module",
"main": "./server/index.ts",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "run-p type-check \"build-only {@}\" --", "build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview", "preview": "vite preview",
"build-only": "vite build", "build-only": "vite build",
"type-check": "vue-tsc --build", "type-check": "vue-tsc --build",
"server": "run --watch ./server/index.ts" "pregen-api": "cd server && dotnet run &",
"gen-api": "npx nswag openapi2tsclient /input:http://localhost:5000/swagger/v1/swagger.json /output:src/APIClient.ts",
"postgen-api": "pkill server"
}, },
"dependencies": { "dependencies": {
"@types/lodash": "^4.17.16", "@types/lodash": "^4.17.16",
@ -35,6 +36,7 @@
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"daisyui": "^5.0.0", "daisyui": "^5.0.0",
"npm-run-all2": "^7.0.2", "npm-run-all2": "^7.0.2",
"nswag": "^14.3.0",
"postcss": "^8.5.3", "postcss": "^8.5.3",
"tailwindcss": "^4.0.12", "tailwindcss": "^4.0.12",
"typescript": "~5.7.3", "typescript": "~5.7.3",

View File

@ -18,10 +18,10 @@ namespace Common
{ {
if (length > 8) if (length > 8)
{ {
throw new ArgumentException( return new(new ArgumentException(
"Unsigned long number can't over 8 bytes(64 bits).", "Unsigned long number can't over 8 bytes(64 bits).",
nameof(length) nameof(length)
); ));
} }
var arr = new byte[length]; var arr = new byte[length];
@ -53,10 +53,10 @@ namespace Common
{ {
if (bytes.Length > 8) if (bytes.Length > 8)
{ {
throw new ArgumentException( return new(new ArgumentException(
"Unsigned long number can't over 8 bytes(64 bits).", "Unsigned long number can't over 8 bytes(64 bits).",
nameof(bytes) nameof(bytes)
); ));
} }
ulong num = 0; ulong num = 0;
@ -106,7 +106,7 @@ namespace Common
/// <returns>[TODO:return]</returns> /// <returns>[TODO:return]</returns>
public static Result<ulong> MultiBitsToNumber(ulong bits1, uint bits1Len, ulong bits2, uint bits2Len) public static Result<ulong> MultiBitsToNumber(ulong bits1, uint bits1Len, ulong bits2, uint bits2Len)
{ {
if (bits1Len + bits2Len > 64) throw new ArgumentException("Two Bits is more than 64 bits"); if (bits1Len + bits2Len > 64) return new(new ArgumentException("Two Bits is more than 64 bits"));
ulong num = (bits1 << Convert.ToInt32(bits2Len)) | bits2; ulong num = (bits1 << Convert.ToInt32(bits2Len)) | bits2;
return num; return num;
@ -122,7 +122,7 @@ namespace Common
/// <returns>[TODO:return]</returns> /// <returns>[TODO:return]</returns>
public static Result<uint> MultiBitsToNumber(uint bits1, uint bits1Len, uint bits2, uint bits2Len) public static Result<uint> MultiBitsToNumber(uint bits1, uint bits1Len, uint bits2, uint bits2Len)
{ {
if (bits1Len + bits2Len > 64) throw new ArgumentException("Two Bits is more than 64 bits"); if (bits1Len + bits2Len > 64) return new(new ArgumentException("Two Bits is more than 64 bits"));
uint num = (bits1 << Convert.ToInt32(bits2Len)) | bits2; uint num = (bits1 << Convert.ToInt32(bits2Len)) | bits2;
return num; return num;

View File

@ -1,5 +1,6 @@
using System.Net; using System.Net;
using Common; using Common;
using DotNext;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json; using Newtonsoft.Json;
using WebProtocol; using WebProtocol;
@ -149,6 +150,7 @@ public class JtagController : ControllerBase
{ {
return "This is Jtag Controller"; return "This is Jtag Controller";
} }
/// <summary> /// <summary>
/// 执行一个Jtag命令 /// 执行一个Jtag命令
/// </summary> /// </summary>
@ -182,8 +184,16 @@ public class JtagController : ControllerBase
var jtagCtrl = new JtagClient.Jtag(address, port); var jtagCtrl = new JtagClient.Jtag(address, port);
var ret = await jtagCtrl.ReadIDCode(); var ret = await jtagCtrl.ReadIDCode();
if (ret.IsSuccessful) { return TypedResults.Ok(ret.Value); } if (ret.IsSuccessful)
else { return TypedResults.InternalServerError(ret.Error); } {
logger.Info($"Get device {address} ID code: 0x{ret.Value:X4}");
return TypedResults.Ok(ret.Value);
}
else
{
logger.Error(ret.Error);
return TypedResults.InternalServerError(ret.Error);
}
} }
/// <summary> /// <summary>
@ -217,7 +227,8 @@ public class JtagController : ControllerBase
await file.CopyToAsync(stream); await file.CopyToAsync(stream);
} }
return TypedResults.Ok("文件上传成功"); logger.Info($"Device {address} Upload Bitstream Successfully");
return TypedResults.Ok("Bitstream Upload Successfully");
} }
/// <summary> /// <summary>
@ -265,8 +276,16 @@ public class JtagController : ControllerBase
var jtagCtrl = new JtagClient.Jtag(address, port); var jtagCtrl = new JtagClient.Jtag(address, port);
var ret = await jtagCtrl.DownloadBitstream(fileBytes); var ret = await jtagCtrl.DownloadBitstream(fileBytes);
if (ret.IsSuccessful) { return TypedResults.Ok(ret.Value); } if (ret.IsSuccessful)
else { return TypedResults.InternalServerError(ret.Error); } {
logger.Info($"Device {address} dowload bitstream successfully");
return TypedResults.Ok(ret.Value);
}
else
{
logger.Error(ret.Error);
return TypedResults.InternalServerError(ret.Error);
}
} }
} }
catch (Exception error) catch (Exception error)

View File

@ -213,23 +213,34 @@ public static class JtagCmd
public const UInt32 CMD_JTAG_IDLE_DELAY = 0b0101; public const UInt32 CMD_JTAG_IDLE_DELAY = 0b0101;
} }
class Jtag /// <summary>
/// Jtag控制器
/// </summary>
public class Jtag
{ {
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
readonly int timeout; readonly int timeout;
readonly int port; readonly int port;
readonly string address; readonly string address;
private IPEndPoint ep; private IPEndPoint ep;
public Jtag(string address, int port, int outTime = 2000) /// <summary>
/// Jtag构造函数
/// </summary>
/// <param name="address">目标IP地址</param>
/// <param name="port">目标UDP端口</param>
/// <param name="timeout">超时时间</param>
public Jtag(string address, int port, int timeout = 2000)
{ {
this.address = address; this.address = address;
this.port = port; this.port = port;
this.ep = new IPEndPoint(IPAddress.Parse(address), port); this.ep = new IPEndPoint(IPAddress.Parse(address), port);
this.timeout = outTime; this.timeout = timeout;
} }
public async ValueTask<Result<uint>> ReadFIFO(uint devAddr) async ValueTask<Result<uint>> ReadFIFO(uint devAddr)
{ {
var ret = false; var ret = false;
var opts = new SendAddrPackOptions(); var opts = new SendAddrPackOptions();
@ -242,23 +253,23 @@ class Jtag
// Read Jtag State Register // Read Jtag State Register
opts.IsWrite = false; opts.IsWrite = false;
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send Address Package Failed!"); if (!ret) return new(new Exception("Send Address Package Failed!"));
// Wait for Read Ack // Wait for Read Ack
if (!MsgBus.IsRunning) if (!MsgBus.IsRunning)
throw new Exception("Message Bus not Working!"); return new(new Exception("Message Bus not Working!"));
var retPack = await MsgBus.UDPServer.WaitForDataAsync(address, port); var retPack = await MsgBus.UDPServer.WaitForDataAsync(address, port);
if (!retPack.IsSuccessful || !retPack.Value.IsSuccessful) if (!retPack.IsSuccessful || !retPack.Value.IsSuccessful)
throw new Exception("Send address package failed"); return new(new Exception("Send address package failed"));
var retPackOpts = retPack.Value.Options; var retPackOpts = retPack.Value.Options;
if (retPackOpts.Data is null) if (retPackOpts.Data is null)
throw new Exception($"Data is Null, package: {retPackOpts.ToString()}"); return new(new Exception($"Data is Null, package: {retPackOpts.ToString()}"));
var retPackLen = retPackOpts.Data.Length; var retPackLen = retPackOpts.Data.Length;
if (retPackLen != 4) if (retPackLen != 4)
throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"); return new(new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"));
return Convert.ToUInt32(Common.Number.BytesToNumber(retPackOpts.Data).Value); return Convert.ToUInt32(Common.Number.BytesToNumber(retPackOpts.Data).Value);
} }
@ -277,36 +288,36 @@ class Jtag
// Write Jtag State Register // Write Jtag State Register
opts.IsWrite = true; opts.IsWrite = true;
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send 1st address package failed!"); if (!ret) return new(new Exception("Send 1st address package failed!"));
// Send Data Package // Send Data Package
ret = await UDPClientPool.SendDataPackAsync(ep, ret = await UDPClientPool.SendDataPackAsync(ep,
new SendDataPackage(Common.Number.NumberToBytes(data, 4).Value)); new SendDataPackage(Common.Number.NumberToBytes(data, 4).Value));
if (!ret) throw new Exception("Send data package failed!"); if (!ret) return new(new Exception("Send data package failed!"));
// Check Msg Bus // Check Msg Bus
if (!MsgBus.IsRunning) if (!MsgBus.IsRunning)
throw new Exception("Message bus not working!"); return new(new Exception("Message bus not working!"));
// Wait for Write Ack // Wait for Write Ack
var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port); var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port);
if (!udpWriteAck.IsSuccessful) throw udpWriteAck.Error; if (!udpWriteAck.IsSuccessful) return new(udpWriteAck.Error);
else if (!udpWriteAck.Value.IsSuccessful) else if (!udpWriteAck.Value.IsSuccessful)
throw new Exception("Send address package failed"); return new(new Exception("Send address package failed"));
// Read Jtag State Register // Read Jtag State Register
opts.IsWrite = false; opts.IsWrite = false;
opts.Address = JtagAddr.STATE; opts.Address = JtagAddr.STATE;
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send 2rd Address Package Failed!"); if (!ret) return new(new Exception("Send 2rd Address Package Failed!"));
// Wait for Read Data // Wait for Read Data
var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port); var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port);
if (!udpDataResp.IsSuccessful) throw udpDataResp.Error; if (!udpDataResp.IsSuccessful) return new(udpDataResp.Error);
else if (!udpDataResp.Value.IsSuccessful) else if (!udpDataResp.Value.IsSuccessful)
throw new Exception("Send address package failed"); return new(new Exception("Send address package failed"));
return udpDataResp.Value; return udpDataResp.Value;
} }
public async ValueTask<Result<RecvDataPackage>> WriteFIFO(UInt32 devAddr, byte[] dataArray) async ValueTask<Result<RecvDataPackage>> WriteFIFO(UInt32 devAddr, byte[] dataArray)
{ {
var ret = false; var ret = false;
var opts = new SendAddrPackOptions(); var opts = new SendAddrPackOptions();
@ -318,7 +329,7 @@ class Jtag
// Check Msg Bus // Check Msg Bus
if (!MsgBus.IsRunning) if (!MsgBus.IsRunning)
throw new Exception("Message bus not working!"); return new(new Exception("Message bus not working!"));
var writeTimes = dataArray.Length / (256 * (32 / 8)) + 1; var writeTimes = dataArray.Length / (256 * (32 / 8)) + 1;
for (var i = 0; i < writeTimes; i++) for (var i = 0; i < writeTimes; i++)
@ -328,7 +339,7 @@ class Jtag
opts.IsWrite = true; opts.IsWrite = true;
opts.BurstLength = isLastData ? (byte)(dataArray.Length - i * (256 * (32 / 8)) - 1) : (byte)255; opts.BurstLength = isLastData ? (byte)(dataArray.Length - i * (256 * (32 / 8)) - 1) : (byte)255;
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send 1st address package failed!"); if (!ret) return new(new Exception("Send 1st address package failed!"));
// Send Data Package // Send Data Package
ret = await UDPClientPool.SendDataPackAsync(ep, ret = await UDPClientPool.SendDataPackAsync(ep,
new SendDataPackage( new SendDataPackage(
@ -337,13 +348,13 @@ class Jtag
dataArray[(i * (256 * (32 / 8)))..((i + 1) * (256 * (32 / 8)) - 1)] dataArray[(i * (256 * (32 / 8)))..((i + 1) * (256 * (32 / 8)) - 1)]
) )
); );
if (!ret) throw new Exception("Send data package failed!"); if (!ret) return new(new Exception("Send data package failed!"));
// Wait for Write Ack // Wait for Write Ack
var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port); var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port);
if (!udpWriteAck.IsSuccessful) throw udpWriteAck.Error; if (!udpWriteAck.IsSuccessful) return new(udpWriteAck.Error);
else if (!udpWriteAck.Value.IsSuccessful) else if (!udpWriteAck.Value.IsSuccessful)
throw new Exception("Send address package failed"); return new(new Exception("Send address package failed"));
} }
// Read Jtag State Register // Read Jtag State Register
@ -351,29 +362,29 @@ class Jtag
opts.BurstLength = 0; opts.BurstLength = 0;
opts.Address = JtagAddr.STATE; opts.Address = JtagAddr.STATE;
ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
if (!ret) throw new Exception("Send 2rd Address Package Failed!"); if (!ret) return new(new Exception("Send 2rd Address Package Failed!"));
// Wait for Read Data // Wait for Read Data
var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port); var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port);
if (!udpDataResp.IsSuccessful) throw udpDataResp.Error; if (!udpDataResp.IsSuccessful) return new(udpDataResp.Error);
else if (!udpDataResp.Value.IsSuccessful) else if (!udpDataResp.Value.IsSuccessful)
throw new Exception("Send address package failed"); return new(new Exception("Send address package failed"));
return udpDataResp.Value; return udpDataResp.Value;
} }
public async ValueTask<Result<bool>> WriteFIFO async ValueTask<Result<bool>> WriteFIFO
(UInt32 devAddr, UInt32 data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF) (UInt32 devAddr, UInt32 data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF)
{ {
var ret = false; var ret = false;
var retPack = await WriteFIFO(devAddr, data); var retPack = await WriteFIFO(devAddr, data);
if (!retPack.IsSuccessful) throw retPack.Error; if (!retPack.IsSuccessful) return new(retPack.Error);
if (retPack.Value.Options.Data is null) if (retPack.Value.Options.Data is null)
throw new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}"); return new(new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}"));
var retPackLen = retPack.Value.Options.Data.Length; var retPackLen = retPack.Value.Options.Data.Length;
if (retPackLen != 4) if (retPackLen != 4)
throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"); return new(new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"));
if (Common.Number.BitsCheck( if (Common.Number.BitsCheck(
Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask)) Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask))
@ -382,18 +393,18 @@ class Jtag
return ret; return ret;
} }
public async ValueTask<Result<bool>> WriteFIFO async ValueTask<Result<bool>> WriteFIFO
(UInt32 devAddr, byte[] data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF) (UInt32 devAddr, byte[] data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF)
{ {
var ret = false; var ret = false;
var retPack = await WriteFIFO(devAddr, data); var retPack = await WriteFIFO(devAddr, data);
if (retPack.Value.Options.Data is null) if (retPack.Value.Options.Data is null)
throw new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}"); return new(new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}"));
var retPackLen = retPack.Value.Options.Data.Length; var retPackLen = retPack.Value.Options.Data.Length;
if (retPackLen != 4) if (retPackLen != 4)
throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"); return new(new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"));
if (Common.Number.BitsCheck( if (Common.Number.BitsCheck(
Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask)) Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask))
@ -431,7 +442,7 @@ class Jtag
async ValueTask<Result<bool>> IdleDelay(UInt32 milliseconds) async ValueTask<Result<bool>> IdleDelay(UInt32 milliseconds)
{ {
if (milliseconds > Math.Pow(2, 28)) throw new Exception("Timespan is over 2^28 milliseconds"); if (milliseconds > Math.Pow(2, 28)) return new(new Exception("Timespan is over 2^28 milliseconds"));
return await WriteFIFO( return await WriteFIFO(
JtagAddr.WRITE_CMD, JtagAddr.WRITE_CMD,
@ -446,8 +457,8 @@ class Jtag
JtagAddr.WRITE_DATA, JtagAddr.WRITE_DATA,
Common.Number.MultiBitsToNumber(0, 22, command, JtagCmd.LEN_JTAG_DR).Value, 0, 0); Common.Number.MultiBitsToNumber(0, 22, command, JtagCmd.LEN_JTAG_DR).Value, 0, 0);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Write JTAG_DR_IDCODE Failed"); else if (!ret.Value) return new(new Exception("Write JTAG_DR_IDCODE Failed"));
} }
{ {
var ret = await WriteFIFO( var ret = await WriteFIFO(
@ -455,8 +466,8 @@ class Jtag
Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_IR, JtagCmd.LEN_CMD_JTAG, 10, 28).Value, Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_IR, JtagCmd.LEN_CMD_JTAG, 10, 28).Value,
0x01_00_00_00, JtagState.CMD_EXEC_FINISH); 0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Write CMD_JTAG_LOAD_IR Failed"); else if (!ret.Value) return new(new Exception("Write CMD_JTAG_LOAD_IR Failed"));
} }
return await ClearWriteDataReg(); return await ClearWriteDataReg();
} }
@ -464,7 +475,7 @@ class Jtag
async ValueTask<Result<bool>> LoadDRCareInput(byte[] bytesArray) async ValueTask<Result<bool>> LoadDRCareInput(byte[] bytesArray)
{ {
var bytesLen = ((uint)(bytesArray.Length * 8)); var bytesLen = ((uint)(bytesArray.Length * 8));
if (bytesLen > Math.Pow(2, 28)) throw new Exception("Length is over 2^(28 - 3)"); if (bytesLen > Math.Pow(2, 28)) return new(new Exception("Length is over 2^(28 - 3)"));
{ {
var ret = await WriteFIFO( var ret = await WriteFIFO(
@ -472,21 +483,21 @@ class Jtag
Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_DR_CAREI, JtagCmd.LEN_CMD_JTAG, bytesLen, 28).Value, Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_DR_CAREI, JtagCmd.LEN_CMD_JTAG, bytesLen, 28).Value,
0x01_00_00_00, JtagState.CMD_EXEC_FINISH); 0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Write CMD_JTAG_LOAD_DR_CAREI Failed"); else if (!ret.Value) return new(new Exception("Write CMD_JTAG_LOAD_DR_CAREI Failed"));
} }
{ {
var ret = await WriteFIFO(JtagAddr.WRITE_DATA, bytesArray, 0x01_00_00_00, JtagState.CMD_EXEC_FINISH); var ret = await WriteFIFO(JtagAddr.WRITE_DATA, bytesArray, 0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Write Data Failed"); else if (!ret.Value) return new(new Exception("Write Data Failed"));
} }
return true; return true;
} }
async ValueTask<Result<UInt32>> LoadDRCareOutput(UInt32 bytesLen) async ValueTask<Result<UInt32>> LoadDRCareOutput(UInt32 bytesLen)
{ {
if (bytesLen > Math.Pow(2, 28)) throw new Exception("Length is over 2^(28 - 3)"); if (bytesLen > Math.Pow(2, 28)) return new(new Exception("Length is over 2^(28 - 3)"));
var ret = await WriteFIFO( var ret = await WriteFIFO(
JtagAddr.WRITE_CMD, JtagAddr.WRITE_CMD,
@ -496,7 +507,7 @@ class Jtag
if (ret.Value) if (ret.Value)
return await ReadFIFO(JtagAddr.READ_DATA); return await ReadFIFO(JtagAddr.READ_DATA);
else else
throw new Exception("LoadDRCareo Failed!"); return new(new Exception("LoadDRCareo Failed!"));
} }
public async ValueTask<Result<uint>> ReadIDCode() public async ValueTask<Result<uint>> ReadIDCode()
@ -504,28 +515,30 @@ class Jtag
// Clear Data // Clear Data
await MsgBus.UDPServer.ClearUDPData(this.address); await MsgBus.UDPServer.ClearUDPData(this.address);
logger.Trace($"Clear up udp server {this.address} receive data");
Result<bool> ret; Result<bool> ret;
ret = await ClearAllRegisters(); ret = await ClearAllRegisters();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Clear All Registers Failed"); else if (!ret.Value) return new(new Exception("Jtag Clear All Registers Failed"));
ret = await RunTest(); ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Run Test Failed"));
ret = await ExecRDCmd(JtagCmd.JTAG_DR_IDCODE); ret = await ExecRDCmd(JtagCmd.JTAG_DR_IDCODE);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_IDCODE Failed"); else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_IDCODE Failed"));
ret = await ClearWriteDataReg(); ret = await ClearWriteDataReg();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Clear Write Registers Failed"); else if (!ret.Value) return new(new Exception("Jtag Clear Write Registers Failed"));
var retData = await LoadDRCareOutput(4); var retData = await LoadDRCareOutput(4);
if (!retData.IsSuccessful) if (!retData.IsSuccessful)
{ {
throw new Exception("Get ID Code Failed"); return new(new Exception("Get ID Code Failed"));
} }
return retData.Value; return retData.Value;
@ -536,66 +549,66 @@ class Jtag
// Clear Data // Clear Data
await MsgBus.UDPServer.ClearUDPData(this.address); await MsgBus.UDPServer.ClearUDPData(this.address);
logger.Trace($"Clear up udp server {this.address} receive data");
Result<bool> ret; Result<bool> ret;
ret = await CloseTest(); ret = await CloseTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Close Test Failed"));
ret = await RunTest(); ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Run Test Failed"));
logger.Trace("Jtag initialize");
ret = await ExecRDCmd(JtagCmd.JTAG_DR_JRST); ret = await ExecRDCmd(JtagCmd.JTAG_DR_JRST);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JRST Failed"); else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_JRST Failed"));
ret = await RunTest(); ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Run Test Failed"));
ret = await ExecRDCmd(JtagCmd.JTAG_DR_CFGI); ret = await ExecRDCmd(JtagCmd.JTAG_DR_CFGI);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_CFGI Failed"); else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_CFGI Failed"));
logger.Trace("Jtag ready to write bitstream");
ret = await IdleDelay(75000); ret = await IdleDelay(75000);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed"); else if (!ret.Value) return new(new Exception("Jtag IDLE Delay Failed"));
ret = await LoadDRCareInput(bitstream); ret = await LoadDRCareInput(bitstream);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Load Data Failed"); else if (!ret.Value) return new(new Exception("Jtag Load Data Failed"));
logger.Trace("Jtag write bitstream");
ret = await CloseTest(); ret = await CloseTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Close Test Failed"));
ret = await RunTest(); ret = await RunTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Run Test Failed"));
ret = await ExecRDCmd(JtagCmd.JTAG_DR_JWAKEUP); ret = await ExecRDCmd(JtagCmd.JTAG_DR_JWAKEUP);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JWAKEUP Failed"); else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_JWAKEUP Failed"));
logger.Trace("Jtag reset device");
ret = await IdleDelay(1000); ret = await IdleDelay(1000);
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed"); else if (!ret.Value) return new(new Exception("Jtag IDLE Delay Failed"));
ret = await CloseTest(); ret = await CloseTest();
if (!ret.IsSuccessful) throw ret.Error; if (!ret.IsSuccessful) return new(ret.Error);
else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); else if (!ret.Value) return new(new Exception("Jtag Close Test Failed"));
logger.Trace("Jtag download bitstream successfully");
return true; return true;
} }

View File

@ -5,6 +5,7 @@ using System.Text;
using DotNext; using DotNext;
using DotNext.Threading; using DotNext.Threading;
using Newtonsoft.Json; using Newtonsoft.Json;
using WebProtocol;
/// <summary> UDP接受数据包格式 </summary> /// <summary> UDP接受数据包格式 </summary>
public class UDPData public class UDPData
@ -58,9 +59,6 @@ public class UDPData
} }
} }
/// <summary>
/// UDP Server
/// </summary>
/// <summary> /// <summary>
/// UDP 服务器 /// UDP 服务器
/// </summary> /// </summary>
@ -80,6 +78,15 @@ public class UDPServer
/// </summary> /// </summary>
public bool IsRunning { get { return isRunning; } } public bool IsRunning { get { return isRunning; } }
/// <summary> UDP 服务器的错误代码 </summary>
public enum ErrorCode
{
Success = 0,
GetNoneAfterTimeout,
ResponseWrong,
NotRecvDataPackage,
}
/// <summary> /// <summary>
/// Construct a udp server with fixed port /// Construct a udp server with fixed port
/// </summary> /// </summary>
@ -132,8 +139,9 @@ public class UDPServer
{ {
var elapsed = DateTime.Now - startTime; var elapsed = DateTime.Now - startTime;
isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout); isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout);
timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed; if (isTimeout) break;
timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed;
using (await udpData.AcquireWriteLockAsync(timeleft)) using (await udpData.AcquireWriteLockAsync(timeleft))
{ {
if (udpData.ContainsKey(ipAddr) && if (udpData.ContainsKey(ipAddr) &&
@ -150,11 +158,11 @@ public class UDPServer
if (data is null) if (data is null)
{ {
logger.Trace("Get nothing even after time out"); logger.Trace("Get nothing even after time out");
return Optional<UDPData>.None; return new(null);
} }
else else
{ {
return Optional.Some((UDPData)data.DeepClone()); return new(data.DeepClone());
} }
} }
@ -175,8 +183,9 @@ public class UDPServer
{ {
var elapsed = DateTime.Now - startTime; var elapsed = DateTime.Now - startTime;
isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout); isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout);
timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed; if (isTimeout) break;
timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed;
using (await udpData.AcquireReadLockAsync(timeleft)) using (await udpData.AcquireReadLockAsync(timeleft))
{ {
if (udpData.ContainsKey(ipAddr) && if (udpData.ContainsKey(ipAddr) &&
@ -193,11 +202,11 @@ public class UDPServer
if (data is null) if (data is null)
{ {
logger.Trace("Get nothing even after time out"); logger.Trace("Get nothing even after time out");
return Optional<List<UDPData>>.None; return new(null);
} }
else else
{ {
return Optional.Some((List<UDPData>)data); return new(data);
} }
} }
@ -213,15 +222,15 @@ public class UDPServer
{ {
var data = await FindDataAsync(address, timeout); var data = await FindDataAsync(address, timeout);
if (!data.HasValue) if (!data.HasValue)
throw new Exception("Get None even after time out!"); return new(new Exception("Get None even after time out!"));
var recvData = data.Value; var recvData = data.Value;
if (recvData.Address != address || (port > 0 && recvData.Port != port)) if (recvData.Address != address || (port > 0 && recvData.Port != port))
throw new Exception("Receive Data From Wrong Board!"); return new(new Exception("Receive Data From Wrong Board!"));
var retPack = WebProtocol.RecvRespPackage.FromBytes(recvData.Data); var retPack = WebProtocol.RecvRespPackage.FromBytes(recvData.Data);
if (!retPack.IsSuccessful) if (!retPack.IsSuccessful)
throw new Exception("Not RecvDataPackage!", retPack.Error); return new(new Exception("Not RecvDataPackage!", retPack.Error));
return retPack.Value; return retPack.Value;
} }
@ -233,20 +242,20 @@ public class UDPServer
/// <param name="port">UDP 端口</param> /// <param name="port">UDP 端口</param>
/// <param name="timeout">超时时间范围</param> /// <param name="timeout">超时时间范围</param>
/// <returns>接收数据包</returns> /// <returns>接收数据包</returns>
public async ValueTask<Result<WebProtocol.RecvDataPackage>> WaitForDataAsync public async ValueTask<Result<RecvDataPackage>> WaitForDataAsync
(string address, int port = -1, int timeout = 1000) (string address, int port = -1, int timeout = 1000)
{ {
var data = await FindDataAsync(address, timeout); var data = await FindDataAsync(address, timeout);
if (!data.HasValue) if (!data.HasValue)
throw new Exception("Get None even after time out!"); return new(new Exception("Get None even after time out!"));
var recvData = data.Value; var recvData = data.Value;
if (recvData.Address != address || (port >= 0 && recvData.Port != port)) if (recvData.Address != address || (port >= 0 && recvData.Port != port))
throw new Exception("Receive Data From Wrong Board!"); return new(new Exception("Receive Data From Wrong Board!"));
var retPack = WebProtocol.RecvDataPackage.FromBytes(recvData.Data); var retPack = WebProtocol.RecvDataPackage.FromBytes(recvData.Data);
if (!retPack.IsSuccessful) if (!retPack.IsSuccessful)
throw new Exception("Not RecvDataPackage!", retPack.Error); return new(new Exception("Not RecvDataPackage!", retPack.Error));
return retPack.Value; return retPack.Value;
} }

View File

@ -234,18 +234,18 @@ namespace WebProtocol
{ {
if (bytes.Length != 8) if (bytes.Length != 8)
{ {
throw new ArgumentException( return new(new ArgumentException(
"Bytes are not equal to 8 bytes.", "Bytes are not equal to 8 bytes.",
nameof(bytes) nameof(bytes)
); ));
} }
if (checkSign && bytes[0] != (byte)PackSign.SendAddr) if (checkSign && bytes[0] != (byte)PackSign.SendAddr)
{ {
throw new ArgumentException( return new(new ArgumentException(
"The sign of bytes is not SendAddr Package, but you can disable it by set checkSign false.", "The sign of bytes is not SendAddr Package, but you can disable it by set checkSign false.",
nameof(bytes) nameof(bytes)
); ));
} }
var address = Common.Number.BytesToNumber(bytes[4..]).Value; var address = Common.Number.BytesToNumber(bytes[4..]).Value;
@ -377,10 +377,10 @@ namespace WebProtocol
public static Result<RecvDataPackage> FromBytes(byte[] bytes) public static Result<RecvDataPackage> FromBytes(byte[] bytes)
{ {
if (bytes[0] != (byte)PackSign.RecvData) if (bytes[0] != (byte)PackSign.RecvData)
throw new ArgumentException( return new(new ArgumentException(
$"The sign of bytes is not RecvData Package, Sign: 0x{BitConverter.ToString([bytes[0]])}", $"The sign of bytes is not RecvData Package, Sign: 0x{BitConverter.ToString([bytes[0]])}",
nameof(bytes) nameof(bytes)
); ));
return new RecvDataPackage(bytes[1], bytes[2], bytes[4..]); return new RecvDataPackage(bytes[1], bytes[2], bytes[4..]);
} }
@ -480,10 +480,10 @@ namespace WebProtocol
public static Result<RecvRespPackage> FromBytes(byte[] bytes) public static Result<RecvRespPackage> FromBytes(byte[] bytes)
{ {
if (bytes[0] != (byte)PackSign.RecvResp) if (bytes[0] != (byte)PackSign.RecvResp)
throw new ArgumentException( return new(new ArgumentException(
$"The sign of bytes is not RecvResp Package, Sign: 0x{BitConverter.ToString([bytes[0]])}", $"The sign of bytes is not RecvResp Package, Sign: 0x{BitConverter.ToString([bytes[0]])}",
nameof(bytes) nameof(bytes)
); ));
return new RecvRespPackage(bytes[1], bytes[2]); return new RecvRespPackage(bytes[1], bytes[2]);
} }

869
src/APIClient.ts Normal file
View File

@ -0,0 +1,869 @@
//----------------------
// <auto-generated>
// Generated using the NSwag toolchain v14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------
/* tslint:disable */
/* eslint-disable */
// ReSharper disable InconsistentNaming
export class Client {
private http: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> };
private baseUrl: string;
protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
this.http = http ? http : window as any;
this.baseUrl = baseUrl ?? "http://localhost:5000";
}
get(): Promise<void> {
let url_ = this.baseUrl + "/";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
method: "GET",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processGet(_response);
});
}
protected processGet(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(null as any);
}
}
export class UDPClient {
private http: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> };
private baseUrl: string;
protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
this.http = http ? http : window as any;
this.baseUrl = baseUrl ?? "http://localhost:5000";
}
/**
*
*/
index(): Promise<string> {
let url_ = this.baseUrl + "/api/UDP";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
method: "GET",
headers: {
"Accept": "application/json"
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processIndex(_response);
});
}
protected processIndex(response: Response): Promise<string> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result200 = resultData200 !== undefined ? resultData200 : <any>null;
return result200;
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<string>(null as any);
}
/**
*
* @param address (optional) IPV4 IPV6
* @param port (optional)
* @param text (optional)
* @return
*/
sendString(address: string | undefined, port: number | undefined, text: string | undefined): Promise<void> {
let url_ = this.baseUrl + "/api/UDP/SendString?";
if (address === null)
throw new Error("The parameter 'address' cannot be null.");
else if (address !== undefined)
url_ += "address=" + encodeURIComponent("" + address) + "&";
if (port === null)
throw new Error("The parameter 'port' cannot be null.");
else if (port !== undefined)
url_ += "port=" + encodeURIComponent("" + port) + "&";
if (text === null)
throw new Error("The parameter 'text' cannot be null.");
else if (text !== undefined)
url_ += "text=" + encodeURIComponent("" + text) + "&";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processSendString(_response);
});
}
protected processSendString(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("\u53d1\u9001\u5931\u8d25", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(null as any);
}
/**
*
* @param address (optional) IPV4 IPV6
* @param port (optional)
* @param bytes (optional) 16
*/
sendBytes(address: string | undefined, port: number | undefined, bytes: string | undefined): Promise<void> {
let url_ = this.baseUrl + "/api/UDP/SendBytes?";
if (address === null)
throw new Error("The parameter 'address' cannot be null.");
else if (address !== undefined)
url_ += "address=" + encodeURIComponent("" + address) + "&";
if (port === null)
throw new Error("The parameter 'port' cannot be null.");
else if (port !== undefined)
url_ += "port=" + encodeURIComponent("" + port) + "&";
if (bytes === null)
throw new Error("The parameter 'bytes' cannot be null.");
else if (bytes !== undefined)
url_ += "bytes=" + encodeURIComponent("" + bytes) + "&";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processSendBytes(_response);
});
}
protected processSendBytes(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("A server side error occurred.", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(null as any);
}
/**
*
* @param address (optional) IP地址
* @param port (optional) UDP
* @param opts
*/
sendAddrPackage(address: string | undefined, port: number | undefined, opts: SendAddrPackOptions): Promise<void> {
let url_ = this.baseUrl + "/api/UDP/SendAddrPackage?";
if (address === null)
throw new Error("The parameter 'address' cannot be null.");
else if (address !== undefined)
url_ += "address=" + encodeURIComponent("" + address) + "&";
if (port === null)
throw new Error("The parameter 'port' cannot be null.");
else if (port !== undefined)
url_ += "port=" + encodeURIComponent("" + port) + "&";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(opts);
let options_: RequestInit = {
body: content_,
method: "POST",
headers: {
"Content-Type": "application/json",
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processSendAddrPackage(_response);
});
}
protected processSendAddrPackage(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("A server side error occurred.", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(null as any);
}
/**
*
* @param address (optional) IP地址
* @param port (optional) UDP
* @param data (optional) 16
*/
sendDataPackage(address: string | undefined, port: number | undefined, data: string | undefined): Promise<void> {
let url_ = this.baseUrl + "/api/UDP/SendDataPackage?";
if (address === null)
throw new Error("The parameter 'address' cannot be null.");
else if (address !== undefined)
url_ += "address=" + encodeURIComponent("" + address) + "&";
if (port === null)
throw new Error("The parameter 'port' cannot be null.");
else if (port !== undefined)
url_ += "port=" + encodeURIComponent("" + port) + "&";
if (data === null)
throw new Error("The parameter 'data' cannot be null.");
else if (data !== undefined)
url_ += "data=" + encodeURIComponent("" + data) + "&";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processSendDataPackage(_response);
});
}
protected processSendDataPackage(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("A server side error occurred.", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(null as any);
}
/**
* IP地址接受的数据列表
* @param address (optional) IP地址
*/
getRecvDataArray(address: string | undefined): Promise<UDPData[]> {
let url_ = this.baseUrl + "/api/UDP/GetRecvDataArray?";
if (address === null)
throw new Error("The parameter 'address' cannot be null.");
else if (address !== undefined)
url_ += "address=" + encodeURIComponent("" + address) + "&";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
method: "GET",
headers: {
"Accept": "application/json"
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processGetRecvDataArray(_response);
});
}
protected processGetRecvDataArray(response: Response): Promise<UDPData[]> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
if (Array.isArray(resultData200)) {
result200 = [] as any;
for (let item of resultData200)
result200!.push(UDPData.fromJS(item));
}
else {
result200 = <any>null;
}
return result200;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("A server side error occurred.", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<UDPData[]>(null as any);
}
}
export class JtagClient {
private http: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> };
private baseUrl: string;
protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
this.http = http ? http : window as any;
this.baseUrl = baseUrl ?? "http://localhost:5000";
}
/**
*
*/
index(): Promise<string> {
let url_ = this.baseUrl + "/api/Jtag";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
method: "GET",
headers: {
"Accept": "application/json"
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processIndex(_response);
});
}
protected processIndex(response: Response): Promise<string> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result200 = resultData200 !== undefined ? resultData200 : <any>null;
return result200;
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<string>(null as any);
}
/**
* Jtag命令
* @param address (optional)
* @param port (optional)
* @param hexDevAddr (optional) 16(Jtag)
* @param hexCmd (optional) 16
*/
runCommand(address: string | undefined, port: number | undefined, hexDevAddr: string | undefined, hexCmd: string | undefined): Promise<void> {
let url_ = this.baseUrl + "/api/Jtag/RunCommand?";
if (address === null)
throw new Error("The parameter 'address' cannot be null.");
else if (address !== undefined)
url_ += "address=" + encodeURIComponent("" + address) + "&";
if (port === null)
throw new Error("The parameter 'port' cannot be null.");
else if (port !== undefined)
url_ += "port=" + encodeURIComponent("" + port) + "&";
if (hexDevAddr === null)
throw new Error("The parameter 'hexDevAddr' cannot be null.");
else if (hexDevAddr !== undefined)
url_ += "hexDevAddr=" + encodeURIComponent("" + hexDevAddr) + "&";
if (hexCmd === null)
throw new Error("The parameter 'hexCmd' cannot be null.");
else if (hexCmd !== undefined)
url_ += "hexCmd=" + encodeURIComponent("" + hexCmd) + "&";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processRunCommand(_response);
});
}
protected processRunCommand(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("A server side error occurred.", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(null as any);
}
/**
* Jtag ID Code
* @param address (optional)
* @param port (optional)
*/
getDeviceIDCode(address: string | undefined, port: number | undefined): Promise<void> {
let url_ = this.baseUrl + "/api/Jtag/GetDeviceIDCode?";
if (address === null)
throw new Error("The parameter 'address' cannot be null.");
else if (address !== undefined)
url_ += "address=" + encodeURIComponent("" + address) + "&";
if (port === null)
throw new Error("The parameter 'port' cannot be null.");
else if (port !== undefined)
url_ += "port=" + encodeURIComponent("" + port) + "&";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
method: "GET",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processGetDeviceIDCode(_response);
});
}
protected processGetDeviceIDCode(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("A server side error occurred.", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(null as any);
}
/**
*
* @param address (optional)
* @param file (optional)
*/
uploadBitstream(address: string | undefined, file: FileParameter | null | undefined): Promise<void> {
let url_ = this.baseUrl + "/api/Jtag/UploadBitstream?";
if (address === null)
throw new Error("The parameter 'address' cannot be null.");
else if (address !== undefined)
url_ += "address=" + encodeURIComponent("" + address) + "&";
url_ = url_.replace(/[?&]$/, "");
const content_ = new FormData();
if (file !== null && file !== undefined)
content_.append("file", file.data, file.fileName ? file.fileName : "file");
let options_: RequestInit = {
body: content_,
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processUploadBitstream(_response);
});
}
protected processUploadBitstream(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 400) {
return response.text().then((_responseText) => {
let result400: any = null;
let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result400 = ProblemDetails.fromJS(resultData400);
return throwException("A server side error occurred.", status, _responseText, _headers, result400);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(null as any);
}
/**
* Jtag下载比特流文件
* @param address (optional)
* @param port (optional)
*/
downloadBitstream(address: string | undefined, port: number | undefined): Promise<void> {
let url_ = this.baseUrl + "/api/Jtag/DownloadBitstream?";
if (address === null)
throw new Error("The parameter 'address' cannot be null.");
else if (address !== undefined)
url_ += "address=" + encodeURIComponent("" + address) + "&";
if (port === null)
throw new Error("The parameter 'port' cannot be null.");
else if (port !== undefined)
url_ += "port=" + encodeURIComponent("" + port) + "&";
url_ = url_.replace(/[?&]$/, "");
let options_: RequestInit = {
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processDownloadBitstream(_response);
});
}
protected processDownloadBitstream(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 400) {
return response.text().then((_responseText) => {
let result400: any = null;
let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result400 = ProblemDetails.fromJS(resultData400);
return throwException("A server side error occurred.", status, _responseText, _headers, result400);
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("A server side error occurred.", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(null as any);
}
}
/** Package options which to send address to read or write */
export class SendAddrPackOptions implements ISendAddrPackOptions {
/** 突发类型 */
burstType?: BurstType;
/** 任务ID */
commandID?: number;
/** 标识写入还是读取 */
isWrite?: boolean;
/** 突发长度0是32bits255是32bits x 256 */
burstLength?: number;
/** 目标地址 */
address?: number;
constructor(data?: ISendAddrPackOptions) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.burstType = _data["burstType"];
this.commandID = _data["commandID"];
this.isWrite = _data["isWrite"];
this.burstLength = _data["burstLength"];
this.address = _data["address"];
}
}
static fromJS(data: any): SendAddrPackOptions {
data = typeof data === 'object' ? data : {};
let result = new SendAddrPackOptions();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["burstType"] = this.burstType;
data["commandID"] = this.commandID;
data["isWrite"] = this.isWrite;
data["burstLength"] = this.burstLength;
data["address"] = this.address;
return data;
}
}
/** Package options which to send address to read or write */
export interface ISendAddrPackOptions {
/** 突发类型 */
burstType?: BurstType;
/** 任务ID */
commandID?: number;
/** 标识写入还是读取 */
isWrite?: boolean;
/** 突发长度0是32bits255是32bits x 256 */
burstLength?: number;
/** 目标地址 */
address?: number;
}
/** Package Burst Type */
export enum BurstType {
ExtendBurst = 0,
FixedBurst = 1,
}
/** UDP接受数据包格式 */
export class UDPData implements IUDPData {
/** 接受到的时间 */
dateTime?: Date;
/** 发送来源的IP地址 */
address?: string;
/** 发送来源的端口号 */
port?: number;
/** 接受到的数据 */
data?: string;
/** 是否被读取过 */
hasRead?: boolean;
constructor(data?: IUDPData) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.dateTime = _data["dateTime"] ? new Date(_data["dateTime"].toString()) : <any>undefined;
this.address = _data["address"];
this.port = _data["port"];
this.data = _data["data"];
this.hasRead = _data["hasRead"];
}
}
static fromJS(data: any): UDPData {
data = typeof data === 'object' ? data : {};
let result = new UDPData();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["dateTime"] = this.dateTime ? this.dateTime.toISOString() : <any>undefined;
data["address"] = this.address;
data["port"] = this.port;
data["data"] = this.data;
data["hasRead"] = this.hasRead;
return data;
}
}
/** UDP接受数据包格式 */
export interface IUDPData {
/** 接受到的时间 */
dateTime?: Date;
/** 发送来源的IP地址 */
address?: string;
/** 发送来源的端口号 */
port?: number;
/** 接受到的数据 */
data?: string;
/** 是否被读取过 */
hasRead?: boolean;
}
export class ProblemDetails implements IProblemDetails {
type?: string | undefined;
title?: string | undefined;
status?: number | undefined;
detail?: string | undefined;
instance?: string | undefined;
extensions?: { [key: string]: any; };
[key: string]: any;
constructor(data?: IProblemDetails) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
for (var property in _data) {
if (_data.hasOwnProperty(property))
this[property] = _data[property];
}
this.type = _data["type"];
this.title = _data["title"];
this.status = _data["status"];
this.detail = _data["detail"];
this.instance = _data["instance"];
if (_data["extensions"]) {
this.extensions = {} as any;
for (let key in _data["extensions"]) {
if (_data["extensions"].hasOwnProperty(key))
(<any>this.extensions)![key] = _data["extensions"][key];
}
}
}
}
static fromJS(data: any): ProblemDetails {
data = typeof data === 'object' ? data : {};
let result = new ProblemDetails();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
for (var property in this) {
if (this.hasOwnProperty(property))
data[property] = this[property];
}
data["type"] = this.type;
data["title"] = this.title;
data["status"] = this.status;
data["detail"] = this.detail;
data["instance"] = this.instance;
if (this.extensions) {
data["extensions"] = {};
for (let key in this.extensions) {
if (this.extensions.hasOwnProperty(key))
(<any>data["extensions"])[key] = (<any>this.extensions)[key];
}
}
return data;
}
}
export interface IProblemDetails {
type?: string | undefined;
title?: string | undefined;
status?: number | undefined;
detail?: string | undefined;
instance?: string | undefined;
extensions?: { [key: string]: any; };
[key: string]: any;
}
export interface FileParameter {
data: any;
fileName: string;
}
export class ApiException extends Error {
message: string;
status: number;
response: string;
headers: { [key: string]: any; };
result: any;
constructor(message: string, status: number, response: string, headers: { [key: string]: any; }, result: any) {
super();
this.message = message;
this.status = status;
this.response = response;
this.headers = headers;
this.result = result;
}
protected isApiException = true;
static isApiException(obj: any): obj is ApiException {
return obj.isApiException === true;
}
}
function throwException(message: string, status: number, response: string, headers: { [key: string]: any; }, result?: any): any {
if (result !== null && result !== undefined)
throw result;
else
throw new ApiException(message, status, response, headers, null);
}