792 lines
30 KiB
C#
792 lines
30 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Runtime.InteropServices;
|
|
|
|
using System.Threading;
|
|
using System.IO;
|
|
using System.IO.Ports;
|
|
using System.Windows.Forms;
|
|
|
|
using LFP_Manager.DataStructure;
|
|
using LFP_Manager.Function;
|
|
using LFP_Manager.Utils;
|
|
|
|
namespace LFP_Manager.Threads
|
|
{
|
|
public delegate void CanDataUpdate(object sender, ref DeviceSystemData aSystemData);
|
|
public delegate void CanDataRecv(UInt32 hdr, byte[] data);
|
|
public delegate void CanDataPrint(object sender, string msg);
|
|
|
|
class csCanThread
|
|
{
|
|
#region DLL FUNCTION
|
|
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_OpenDevice(UInt32 DeviceType, UInt32 DeviceInd, UInt32 Reserved);
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_CloseDevice(UInt32 DeviceType, UInt32 DeviceInd);
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_InitCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_INIT_CONFIG pInitConfig);
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_ReadBoardInfo(UInt32 DeviceType, UInt32 DeviceInd, ref VCI_BOARD_INFO pInfo);
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_ReadErrInfo(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_ERR_INFO pErrInfo);
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_ReadCANStatus(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_STATUS pCANStatus);
|
|
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_GetReference(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, UInt32 RefType, ref byte pData);
|
|
[DllImport("library\\controlcan.dll")]
|
|
//static extern UInt32 VCI_SetReference(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, UInt32 RefType, ref byte pData);
|
|
unsafe static extern UInt32 VCI_SetReference(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, UInt32 RefType, byte* pData);
|
|
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_GetReceiveNum(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_ClearBuffer(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
|
|
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_StartCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_ResetCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
|
|
|
|
[DllImport("library\\controlcan.dll")]
|
|
static extern UInt32 VCI_Transmit(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pSend, UInt32 Len);
|
|
|
|
//[DllImport("library\\controlcan.dll")]
|
|
//static extern UInt32 VCI_Receive(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pReceive, UInt32 Len, Int32 WaitTime);
|
|
[DllImport("library\\controlcan.dll", CharSet = CharSet.Ansi)]
|
|
static extern UInt32 VCI_Receive(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, IntPtr pReceive, UInt32 Len, Int32 WaitTime);
|
|
|
|
#endregion
|
|
|
|
#region VARIABLES
|
|
|
|
public delegate void invokeDelegate();
|
|
|
|
CommConfig Config;
|
|
DeviceSystemData SystemData;
|
|
|
|
TCanTxBuff CanTxBuf;
|
|
|
|
int SystemId = 0;
|
|
|
|
Thread canCommTx = null;
|
|
Thread canCommRx = null;
|
|
//string Msg = "";
|
|
|
|
static UInt32 can_devtype = 21; //USBCAN-2e-u
|
|
|
|
////////////////////////////////////////
|
|
const UInt32 STATUS_OK = 1;
|
|
|
|
bool can_bOpen = false;
|
|
UInt32 can_devind = 0;
|
|
UInt32 can_canind = 0;
|
|
|
|
bool CanTxThreadEnd = true;
|
|
bool CanRxThreadEnd = true;
|
|
|
|
bool CanPolling = false;
|
|
bool AutoCanTx = true;
|
|
|
|
int dcp = 0; // Data Control Parameter
|
|
|
|
public event CanDataUpdate OnUpdate = null;
|
|
public event CanDataPrint OnPrint = null;
|
|
public event CanDataRecv OnDataRecv = null;
|
|
|
|
private object lockObject = new object();
|
|
#endregion
|
|
|
|
#region CONSTRUCTORS
|
|
public csCanThread(int sId, CommConfig aConfig, ref DeviceSystemData aSystemData)
|
|
{
|
|
SystemId = sId;
|
|
Config = aConfig;
|
|
SystemData = aSystemData;
|
|
|
|
CanTxBuf = new TCanTxBuff();
|
|
|
|
canCommTx = new Thread(CanTxThread);
|
|
canCommRx = new Thread(CanRxThread);
|
|
}
|
|
|
|
public void disposeThread()
|
|
{
|
|
CanTxThreadEnd = true;
|
|
if (canCommTx != null)
|
|
{
|
|
if (canCommTx.IsAlive)
|
|
{
|
|
canCommTx.Abort();
|
|
}
|
|
canCommTx = null;
|
|
}
|
|
CanRxThreadEnd = true;
|
|
if (canCommRx != null)
|
|
{
|
|
if (canCommRx.IsAlive)
|
|
{
|
|
canCommRx.Abort();
|
|
}
|
|
canCommRx = null;
|
|
}
|
|
|
|
if (can_bOpen == true)
|
|
{
|
|
_ = VCI_CloseDevice(can_devtype, can_devind);
|
|
}
|
|
}
|
|
|
|
public unsafe bool Start(ref CommConfig aConfig, int sId, bool aPolling)
|
|
{
|
|
bool result = false;
|
|
|
|
SystemId = sId;
|
|
CanPolling = aPolling;
|
|
Config = aConfig;
|
|
|
|
can_devtype = (UInt32)csCanConstData.CanDeviceInfo.DeviceIds[Config.CanDevice];
|
|
can_devind = (UInt32)Config.CanIndex;
|
|
can_canind = (UInt32)Config.CanNo;
|
|
|
|
try
|
|
{
|
|
if (VCI_OpenDevice(can_devtype, can_devind, 0) == 0)
|
|
throw new System.InvalidOperationException("Failed to open the device, please check if the device type and device index number are correct.");
|
|
|
|
//USB-E-U Code
|
|
UInt32 baud;
|
|
VCI_INIT_CONFIG config = new VCI_INIT_CONFIG();
|
|
|
|
if (can_devtype == csCanConstData.CanDeviceInfo.VCI_USBCAN_2E_U)
|
|
{
|
|
baud = (UInt32)csCanConstData.BaudRate.BaudRates[aConfig.CanBaudrate];
|
|
config.Timing0 = 0x00;
|
|
config.Timing1 = 0x14;
|
|
|
|
if (VCI_SetReference(can_devtype, can_devind, can_canind, 0, (byte*)&baud) != STATUS_OK)
|
|
{
|
|
VCI_CloseDevice(can_devtype, can_devind);
|
|
throw new System.InvalidOperationException("Set baud rate error, failed to open device!");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
baud = (UInt32)csCanConstData.BaudRate.BaudRatesOther[aConfig.CanBaudrate];
|
|
config.Timing0 = (byte)(baud >> 8);
|
|
config.Timing1 = (byte)(baud & 0xFF);
|
|
}
|
|
can_bOpen = true;
|
|
|
|
//Config setting
|
|
config.AccCode = 0x00000000;
|
|
config.AccMask = 0xFFFFFFFF;
|
|
config.Filter = 1;
|
|
config.Mode = 0;
|
|
|
|
VCI_InitCAN(can_devtype, can_devind, can_canind, ref config);
|
|
|
|
////Filter setting
|
|
//Int32 filterMode = comboBox_e_u_Filter.SelectedIndex;
|
|
//if (2 != filterMode)//Not disabled
|
|
//{
|
|
// VCI_FILTER_RECORD filterRecord = new VCI_FILTER_RECORD();
|
|
// filterRecord.ExtFrame = (UInt32)filterMode;
|
|
// filterRecord.Start = System.Convert.ToUInt32("0x" + textBox_e_u_startid.Text, 16);
|
|
// filterRecord.End = System.Convert.ToUInt32("0x" + textBox_e_u_endid.Text, 16);
|
|
// //Fill filter table
|
|
// VCI_SetReference(m_devtype, m_devind, m_canind, 1, (byte*)&filterRecord);
|
|
// //Make the filter table take effect
|
|
// byte tm = 0;
|
|
// if (VCI_SetReference(m_devtype, m_devind, m_canind, 2, &tm) != STATUS_OK)
|
|
// {
|
|
// MessageBox.Show("Set filter failed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
|
// VCI_CloseDevice(m_devtype, m_devind);
|
|
// return;
|
|
// }
|
|
//}
|
|
////////////////////////////////////////////////////////////////////////////
|
|
////buttonConnect.Text = m_bOpen == 1 ? "DISCONNECT" : "CONNECT";
|
|
////timer_rec.Enabled = m_bOpen == 1 ? true : false;
|
|
|
|
UInt32 res;
|
|
res = VCI_StartCAN(can_devtype, can_devind, can_canind);
|
|
|
|
CanTxThreadEnd = false;
|
|
CanRxThreadEnd = false;
|
|
|
|
canCommTx.Start();
|
|
canCommRx.Start();
|
|
|
|
result = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Exception Ex = new System.Exception(ex.Message, ex);
|
|
throw Ex;
|
|
}
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
#region TX FUNCTION
|
|
public void SetAutoTx(bool autoTx)
|
|
{
|
|
AutoCanTx = autoTx;
|
|
}
|
|
|
|
public void SetDcp(int aDcp)
|
|
{
|
|
dcp = aDcp;
|
|
}
|
|
|
|
//public void SendProcessFromApp(int sId, int mode, int index, int flag, ref DeviceParamData aParam, ref DeviceCalibration aCalib, int type)
|
|
//{
|
|
// if (can_bOpen == true)
|
|
// {
|
|
// TCanTRxData[] CanTRxData = csCanCommFunction.SendProcessFromAppPacket(sId, mode, index, flag, ref aParam, ref aCalib);
|
|
// if (CanTRxData != null)
|
|
// {
|
|
// for (int i = 0; i < CanTRxData.Length; i++)
|
|
// {
|
|
// CanTRxData[i].type = type;
|
|
// CanTxBuf.PutBuff(CanTRxData[i]);
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|
|
public void SendDataFromApp(uint header, byte[] data, int type)
|
|
{
|
|
if (can_bOpen == true)
|
|
{
|
|
TCanTRxData CanTRxData = new TCanTRxData
|
|
{
|
|
exid = header
|
|
};
|
|
for (int i = 0; i < data.Length; i++)
|
|
{
|
|
CanTRxData.data[i] = data[i];
|
|
}
|
|
CanTxBuf.PutBuff(CanTRxData);
|
|
}
|
|
}
|
|
unsafe public void SendDataFromAppA(UInt32 header, byte[] data)
|
|
{
|
|
if (can_bOpen == false) return;
|
|
|
|
VCI_CAN_OBJ sendobj = new VCI_CAN_OBJ();
|
|
|
|
sendobj.SendType = csCanConstData.SendType.Normal;
|
|
sendobj.ExternFlag = csCanConstData.FrameType.Extended;
|
|
sendobj.RemoteFlag = csCanConstData.FrameFormat.Data_Frame;
|
|
sendobj.ID = header; // 0x1815c9c8
|
|
|
|
int len = 8;
|
|
sendobj.DataLen = System.Convert.ToByte(len);
|
|
for (int i = 0; i < len; i++)
|
|
sendobj.Data[i] = data[i];
|
|
|
|
//int nTimeOut = 3000;
|
|
//if (can_devtype == csCanConstData.CanDeviceInfo.VCI_USBCAN_2E_U)
|
|
//{
|
|
// VCI_SetReference(can_devtype, can_devind, can_canind, 3, (byte*)&nTimeOut);
|
|
//}
|
|
|
|
if (VCI_Transmit(can_devtype, can_devind, can_canind, ref sendobj, 1) == 0)
|
|
{
|
|
throw new Exception("Failed to send");
|
|
}
|
|
|
|
OnPrint?.Invoke(this, csCanCommFunction.PacketToMsg(sendobj, 1));
|
|
}
|
|
|
|
public void SetPolling(bool flag, int sId, ref DeviceSystemData aSystemData)
|
|
{
|
|
SystemId = sId;
|
|
CanPolling = flag;
|
|
SystemData = aSystemData;
|
|
SystemData.mNo = SystemId;
|
|
}
|
|
|
|
unsafe public void SendData()
|
|
{
|
|
if (can_bOpen == false) return;
|
|
|
|
VCI_CAN_OBJ sendobj = new VCI_CAN_OBJ();
|
|
sendobj.SendType = csCanConstData.SendType.Normal;
|
|
sendobj.ExternFlag = csCanConstData.FrameType.Extended;
|
|
sendobj.RemoteFlag = csCanConstData.FrameFormat.Data_Frame;
|
|
sendobj.ID = 0x1815c9c8; // 0x1815c9c8
|
|
|
|
int len = 8;
|
|
sendobj.DataLen = Convert.ToByte(len);
|
|
sendobj.Data[0] = 0xff;
|
|
sendobj.Data[1] = 0xff;
|
|
sendobj.Data[2] = 0xff;
|
|
sendobj.Data[3] = 0xff;
|
|
sendobj.Data[4] = 0xff;
|
|
sendobj.Data[5] = 0xff;
|
|
sendobj.Data[6] = 0xff;
|
|
sendobj.Data[7] = 0xff;
|
|
|
|
//int nTimeOut = 3000;
|
|
//if (can_devtype == csCanConstData.CanDeviceInfo.VCI_USBCAN_2E_U)
|
|
//{
|
|
// VCI_SetReference(can_devtype, can_devind, can_canind, 3, (byte*)&nTimeOut);
|
|
//}
|
|
|
|
if (VCI_Transmit(can_devtype, can_devind, can_canind, ref sendobj, 1) == 0)
|
|
{
|
|
throw new Exception("Failed to send");
|
|
}
|
|
}
|
|
|
|
public void SendProcessFromApp(int sId, int mode, int flag, int dcp, ref DeviceParamData aParam, ref DeviceCalibration aCalib)
|
|
{
|
|
switch (mode)
|
|
{
|
|
case 5: // Cell Volatge Parameter
|
|
SendData(sId, 5, flag, dcp, ref aParam, ref aCalib);
|
|
SendData(sId, 23, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 7:
|
|
SendData(sId, 7, flag, dcp, ref aParam, ref aCalib);
|
|
SendData(sId, 23, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 6:
|
|
SendData(sId, 6, flag, dcp, ref aParam, ref aCalib);
|
|
SendData(sId, 24, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 22:
|
|
SendData(sId, 22, flag, dcp, ref aParam, ref aCalib);
|
|
SendData(sId, 24, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 14:
|
|
SendData(sId, 14, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 99: // All param read
|
|
SendData(sId, 5, flag, dcp, ref aParam, ref aCalib);
|
|
SendData(sId, 6, flag, dcp, ref aParam, ref aCalib);
|
|
SendData(sId, 7, flag, dcp, ref aParam, ref aCalib);
|
|
SendData(sId, 14, flag, dcp, ref aParam, ref aCalib);
|
|
SendData(sId, 22, flag, dcp, ref aParam, ref aCalib);
|
|
SendData(sId, 23, flag, dcp, ref aParam, ref aCalib);
|
|
SendData(sId, 24, flag, dcp, ref aParam, ref aCalib);
|
|
SendData(sId, 2, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 9: // Cell Voltage Calibration
|
|
SendData(sId, 9, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 1: // Cell Balancing Flag Set
|
|
SendData(sId, 1, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 12: // Cell Voltage Calibration
|
|
SendData(sId, 12, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 8: // Battery Parameter Setting
|
|
SendData(sId, 8, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 17: // Cell Balancing Parameter - 240531
|
|
SendData(sId, 17, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 21: // System Information (Device Address)
|
|
SendData(sId, 21, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 13: // Soc Calibration
|
|
SendData(sId, 13, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 15: // Default Parameter
|
|
SendData(sId, 15, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 16: // Default Parameter
|
|
if (aParam.DefalutParamAll == 1)
|
|
SendData(0xFF, 16, flag, dcp, ref aParam, ref aCalib);
|
|
else
|
|
SendData(sId, 16, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 2: // Cell Voltage Difference Parameter
|
|
SendData(sId, 2, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 25:
|
|
SendData(sId, 25, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
|
|
// Inventory Data Control
|
|
case 900: // Manufacturer Cmd
|
|
SendData(sId, 900, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 901: // Serial Number #1 Cmd
|
|
SendData(sId, 901, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
case 902: // Serial Number #2 Cmd
|
|
SendData(sId, 902, flag, dcp, ref aParam, ref aCalib);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//unsafe void SendData(int sId, int mode, int flag, ref DeviceParamData aParam, ref DeviceCalibration aCalib)
|
|
//{
|
|
// if (can_bOpen == 0) return;
|
|
|
|
// VCI_CAN_OBJ sendobj = MakeTxData(sId, mode, flag, ref aParam, ref aCalib);
|
|
|
|
// Monitor.Enter(lockObject);
|
|
// try
|
|
// {
|
|
// OnPrint?.Invoke(this, csCanCommFunction.PacketToMsg(sendobj, 1));
|
|
|
|
// if (VCI_Transmit(can_devtype, can_devind, can_canind, ref sendobj, 1) == 0)
|
|
// {
|
|
// throw new Exception("Failed to send");
|
|
// }
|
|
// }
|
|
// catch (Exception)
|
|
// {
|
|
// //throw new Exception(String.Format("CAN Transmit Exception", ex.Message));
|
|
// }
|
|
// finally
|
|
// {
|
|
// Monitor.Exit(lockObject);
|
|
// }
|
|
//}
|
|
|
|
void SendData(int sid, int mode, int flag, int dcp, ref DeviceParamData aParam, ref DeviceCalibration aCalib)
|
|
{
|
|
UInt32 exID;
|
|
byte[] sendData = new byte[8];
|
|
|
|
exID = MakeTxData(sid, mode, flag, dcp, ref aParam, ref aCalib, ref sendData);
|
|
|
|
SendDataFromApp(exID, sendData, 0);
|
|
//SendCAN(exID, sendData);
|
|
}
|
|
|
|
unsafe void SendCAN(UInt32 exID, byte[] data)
|
|
{
|
|
if (can_bOpen == false) return;
|
|
|
|
VCI_CAN_OBJ sendobj = new VCI_CAN_OBJ();
|
|
|
|
sendobj.SendType = csCanConstData.SendType.Normal;
|
|
sendobj.RemoteFlag = csCanConstData.FrameFormat.Data_Frame;
|
|
sendobj.ExternFlag = csCanConstData.FrameType.Extended;
|
|
|
|
sendobj.ID = exID;
|
|
sendobj.DataLen = (byte)data.Length;
|
|
for (int i = 0; i < data.Length; i++)
|
|
sendobj.Data[i] = data[i];
|
|
|
|
//Monitor.Enter(lockObject);
|
|
if (Monitor.TryEnter(lockObject, 2000))
|
|
{
|
|
try
|
|
{
|
|
if (VCI_Transmit(can_devtype, can_devind, can_canind, ref sendobj, 1) == 0)
|
|
{
|
|
throw new Exception("Failed to send");
|
|
}
|
|
OnPrint?.Invoke(this, csCanCommFunction.PacketToMsg(sendobj, 1));
|
|
|
|
//OnPrint?.Invoke(this, csCanCommFunction.PacketToMsg(sendobj, 1));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
//throw new Exception(String.Format("CAN Transmit Exception", ex.Message));
|
|
}
|
|
finally
|
|
{
|
|
Monitor.Exit(lockObject);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//OnPrint?.Invoke(this, "CAN SEND FAIL");
|
|
throw new Exception("CAN SEND FAIL");
|
|
}
|
|
//try
|
|
//{
|
|
// if (VCI_Transmit(can_devtype, can_devind, can_canind, ref sendobj, 1) == 0)
|
|
// {
|
|
// throw new Exception("Failed to send");
|
|
// }
|
|
// OnPrint?.Invoke(this, csCanCommFunction.PacketToMsg(sendobj, 1));
|
|
//}
|
|
//catch (Exception)
|
|
//{
|
|
// //throw new Exception(String.Format("CAN Transmit Exception", ex.Message));
|
|
//}
|
|
//finally
|
|
//{
|
|
// Monitor.Exit(lockObject);
|
|
//}
|
|
}
|
|
|
|
private UInt32 MakeID(int sId, int mode)
|
|
{
|
|
UInt32 result = 0;
|
|
PACKET_HEADER hdr = new PACKET_HEADER();
|
|
|
|
hdr.Index = 6; // Fixed 6
|
|
hdr.R = 0; // Fixed 0
|
|
hdr.DP = 0; // Fixed 0
|
|
hdr.PF = (byte)mode; // Command
|
|
if (sId == 0xFF) hdr.PS = (byte)(sId); // PDU SPECIFIC
|
|
else hdr.PS = (byte)(sId + 200); // PDU SPECIFIC
|
|
hdr.SA = 200; // SOURCE ADDRESS
|
|
|
|
result = csCanCommFunction.CovertHtoP(hdr);
|
|
return result;
|
|
}
|
|
|
|
private UInt32 MakeInvID(int sId, int mode)
|
|
{
|
|
UInt32 result = 0;
|
|
PACKET_HEADER hdr = new PACKET_HEADER();
|
|
|
|
hdr.Index = 1; // Fixed 1 for Inventory Data
|
|
hdr.R = 0; // Fixed 0
|
|
hdr.DP = 0; // Fixed 0
|
|
hdr.PF = (byte)((mode % 900) + 1); // Command
|
|
if (sId == 0xFF) hdr.PS = (byte)(sId); // PDU SPECIFIC
|
|
else hdr.PS = (byte)(sId + 200); // PDU SPECIFIC
|
|
hdr.SA = 200; // SOURCE ADDRESS
|
|
|
|
result = csCanCommFunction.CovertHtoP(hdr);
|
|
return result;
|
|
}
|
|
|
|
unsafe private VCI_CAN_OBJ MakeTxData(int sId, int mode, int flag, int dcp, ref DeviceParamData aParam, ref DeviceCalibration aCalib)
|
|
{
|
|
VCI_CAN_OBJ sendobj = new VCI_CAN_OBJ();
|
|
|
|
sendobj.SendType = csCanConstData.SendType.Normal;
|
|
sendobj.RemoteFlag = csCanConstData.FrameFormat.Data_Frame;
|
|
sendobj.ExternFlag = csCanConstData.FrameType.Extended;
|
|
if (mode < 900)
|
|
{ sendobj.ID = MakeID(sId, mode); }
|
|
else
|
|
{ sendobj.ID = MakeInvID(sId, mode); }
|
|
sendobj.DataLen = (byte)(8);
|
|
|
|
byte[] aData = csCanCommFunction.MakeCanData(mode, flag, dcp, ref aParam, ref aCalib);
|
|
for (int i = 0; i < 8; i++)
|
|
{ sendobj.Data[i] = aData[i]; }
|
|
|
|
return sendobj;
|
|
}
|
|
|
|
private UInt32 MakeTxData(int sId, int mode, int flag, int dcp, ref DeviceParamData aParam, ref DeviceCalibration aCalib, ref byte[] wData)
|
|
{
|
|
UInt32 result = 0;
|
|
|
|
if (mode < 900)
|
|
{ result = MakeID(sId, mode); }
|
|
else
|
|
{ result = MakeInvID(sId, mode); }
|
|
|
|
wData = csCanCommFunction.MakeCanData(mode, flag, dcp, ref aParam, ref aCalib);
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region COMM TX THREAD
|
|
int current_cmd = 0;
|
|
int RxSystemId = 0;
|
|
|
|
public int GetCommSystemId()
|
|
{
|
|
return RxSystemId;
|
|
}
|
|
|
|
unsafe private void CanTxThread()
|
|
{
|
|
while (CanTxThreadEnd == false)
|
|
{
|
|
TCanTRxData tData = CanTxBuf.GetBuff();
|
|
if (tData != null)
|
|
{
|
|
SendCanPacket(tData, tData.type);
|
|
//Thread.Sleep(1);
|
|
}
|
|
else
|
|
{
|
|
if ((CanPolling) && (AutoCanTx))
|
|
{
|
|
int flag = 0;
|
|
|
|
TxProcess(ref flag);
|
|
RxSystemId = SystemId;
|
|
SendData(SystemId, current_cmd, flag, dcp, ref SystemData.ParamData, ref SystemData.CalibriationData);
|
|
}
|
|
Thread.Sleep(50);
|
|
}
|
|
Thread.Sleep(1);
|
|
}
|
|
}
|
|
|
|
int TxFlag = 0;
|
|
void TxProcess(ref int aflag)
|
|
{
|
|
switch (TxFlag)
|
|
{
|
|
case 0:
|
|
current_cmd = 900;
|
|
TxFlag = 1;
|
|
break;
|
|
case 1:
|
|
current_cmd = 901;
|
|
TxFlag = 2;
|
|
break;
|
|
case 2:
|
|
current_cmd = 902;
|
|
TxFlag = 3;
|
|
break;
|
|
default:
|
|
switch (current_cmd)
|
|
{
|
|
case 900: current_cmd = 901; break; // INV Manufacture Date
|
|
case 901: current_cmd = 902; break; // INV pcb sn MSB
|
|
case 902: current_cmd = 9; break; // INV pcb sn LSB
|
|
|
|
case 9: current_cmd = 20; break; // Module Address get
|
|
|
|
case 20: current_cmd = 1; break;
|
|
|
|
case 1: current_cmd = 19; break; // Status
|
|
case 19: current_cmd = 3; break;
|
|
case 3: current_cmd = 4; break;
|
|
case 4: current_cmd = 11; break;
|
|
case 10: current_cmd = 11; break;
|
|
case 11: current_cmd = 15; break;
|
|
case 15: current_cmd = 16; break;
|
|
case 16: current_cmd = 900; break;
|
|
default: current_cmd = 900; break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
private unsafe void SendCanPacket(TCanTRxData CanTxData, int type)
|
|
{
|
|
VCI_CAN_OBJ sendobj = new VCI_CAN_OBJ();
|
|
|
|
sendobj.SendType = csCanConstData.SendType.Normal;
|
|
sendobj.RemoteFlag = csCanConstData.FrameFormat.Data_Frame;
|
|
sendobj.ExternFlag = csCanConstData.FrameType.Extended;
|
|
sendobj.ID = CanTxData.exid;
|
|
sendobj.DataLen = (byte)(8);
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
sendobj.Data[i] = CanTxData.data[i];
|
|
}
|
|
|
|
Monitor.Enter(lockObject);
|
|
try
|
|
{
|
|
if (VCI_Transmit(can_devtype, can_devind, can_canind, ref sendobj, 1) == 0)
|
|
{
|
|
throw new Exception("Failed to send");
|
|
}
|
|
//OnPrint?.Invoke(this, csCanConstData.PacketToMsg(CanTxData.exid, CanTxData.data, 1, type));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
finally
|
|
{
|
|
Monitor.Exit(lockObject);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region COMM RX THREAD
|
|
unsafe private void CanRxThread()
|
|
{
|
|
DateTime aTime;
|
|
|
|
while (CanRxThreadEnd == false)
|
|
{
|
|
UInt32 res = new UInt32();
|
|
aTime = DateTime.Now;
|
|
|
|
res = VCI_GetReceiveNum(can_devtype, can_devind, can_canind);
|
|
if (res > 0)
|
|
{
|
|
// Received data
|
|
IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(VCI_CAN_OBJ)) * (Int32)res);
|
|
res = VCI_Receive(can_devtype, can_devind, can_canind, pt, res, 100);
|
|
|
|
for (UInt32 i = 0; i < res; i++)
|
|
{
|
|
VCI_CAN_OBJ obj = (VCI_CAN_OBJ)Marshal.PtrToStructure((IntPtr)((UInt32)pt + i * Marshal.SizeOf(typeof(VCI_CAN_OBJ))),
|
|
typeof(VCI_CAN_OBJ));
|
|
OnPrint?.Invoke(this, csCanCommFunction.PacketToMsg(obj, 0));
|
|
|
|
UInt32 exID = obj.ID;
|
|
byte[] adata = new byte[obj.DataLen];
|
|
for (int j = 0; j < obj.DataLen; j++) adata[j] = obj.Data[j];
|
|
|
|
PACKET_HEADER pHeader = csCanCommFunction.CovertPtoH(exID);
|
|
|
|
switch (pHeader.Index)
|
|
{
|
|
case 0x01: // Inventory Data Packet
|
|
if ((pHeader.SA == (200 + SystemId)))
|
|
{
|
|
RxSystemId = pHeader.SA - 200;
|
|
csCanCommFunction.CanInvRxProcess(RxSystemId, exID, adata, ref SystemData, aTime);
|
|
OnUpdate?.Invoke(this, ref SystemData);
|
|
}
|
|
break;
|
|
case 0x04: // Firmware Update Packet
|
|
OnDataRecv?.Invoke(exID, adata);
|
|
break;
|
|
case 0x06: // Normal Packet
|
|
if (pHeader.SA == (200 + SystemId))
|
|
{
|
|
RxSystemId = pHeader.SA - 200;
|
|
csCanCommFunction.CanRxProcess(ref Config, RxSystemId, exID, adata, ref SystemData, aTime);
|
|
|
|
OnUpdate?.Invoke(this, ref SystemData);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
Marshal.FreeHGlobal(pt);
|
|
|
|
Thread.Sleep(1);
|
|
}
|
|
else if (res == 0)
|
|
{
|
|
TimeSpan dTime = DateTime.Now - SystemData.LastRxTime;
|
|
if (SystemData.ShelfCommFail == false)
|
|
{
|
|
if (dTime.TotalSeconds > 3)
|
|
{
|
|
SystemData.ShelfCommFail = true;
|
|
DataInit();
|
|
}
|
|
}
|
|
OnUpdate?.Invoke(this, ref SystemData);
|
|
Thread.Sleep(100);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region DATA INIT
|
|
private void DataInit()
|
|
{
|
|
DataFunction.DataInit(ref SystemData, ref Config);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|