초기 커밋.
This commit is contained in:
791
LFP_Manager_PRM/Threads/csCanThread.cs
Normal file
791
LFP_Manager_PRM/Threads/csCanThread.cs
Normal file
@@ -0,0 +1,791 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
299
LFP_Manager_PRM/Threads/csDbThread.cs
Normal file
299
LFP_Manager_PRM/Threads/csDbThread.cs
Normal file
@@ -0,0 +1,299 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Data;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using System.Threading;
|
||||
using System.IO.Ports;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using LFP_Manager.DataStructure;
|
||||
using LFP_Manager.Function;
|
||||
using LFP_Manager.Utils;
|
||||
|
||||
using System.Data.SQLite;
|
||||
|
||||
namespace LFP_Manager.Threads
|
||||
{
|
||||
public delegate void DbDataPrint(object sender, string msg);
|
||||
|
||||
class csDbThread
|
||||
{
|
||||
#region VARIABLES
|
||||
|
||||
CommConfig Config;
|
||||
DeviceSystemData SystemData;
|
||||
short[] Status, oldStatus;
|
||||
|
||||
bool Active = false;
|
||||
|
||||
Thread dbProc = null;
|
||||
|
||||
int CellDivUnit = csConstData.Unit.CELL_DIV_P3;
|
||||
|
||||
////////////////////////////////////////
|
||||
bool DbThreadEnd = true;
|
||||
|
||||
public event DbDataPrint OnPrint = null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public csDbThread(ref CommConfig aConfig, ref DeviceSystemData aSystemData)
|
||||
{
|
||||
Status = new short[2];
|
||||
oldStatus = new short[2];
|
||||
Config = aConfig;
|
||||
SystemData = aSystemData;
|
||||
|
||||
dbProc = new Thread(dbThreadProcess);
|
||||
}
|
||||
|
||||
public void disposeThread()
|
||||
{
|
||||
DbThreadEnd = true;
|
||||
if (dbProc != null)
|
||||
{
|
||||
if (dbProc.IsAlive)
|
||||
{
|
||||
dbProc.Abort();
|
||||
}
|
||||
dbProc = null;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe bool Start(CommConfig aConfig)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
Config = aConfig;
|
||||
switch (Config.TargetModelIndex)
|
||||
{
|
||||
case 0: // PR-57150
|
||||
CellDivUnit = csConstData.Unit.CELL_DIV_P3;
|
||||
break;
|
||||
case 1: // PR-64150
|
||||
CellDivUnit = csConstData.Unit.CELL_DIV_P4;
|
||||
break;
|
||||
case 2: // LFPM-57080
|
||||
CellDivUnit = csConstData.Unit.CELL_DIV_P4;
|
||||
break;
|
||||
case 3: // PR-102150
|
||||
CellDivUnit = csConstData.Unit.CELL_DIV_P4;
|
||||
break;
|
||||
case 4: // PR-115300
|
||||
CellDivUnit = csConstData.Unit.CELL_DIV_P4;
|
||||
break;
|
||||
case 5: // PR-67150
|
||||
CellDivUnit = csConstData.Unit.CELL_DIV_P4;
|
||||
break;
|
||||
default:
|
||||
CellDivUnit = csConstData.Unit.CELL_DIV_P3;
|
||||
break;
|
||||
}
|
||||
|
||||
// DB Create with Path Create
|
||||
csHistoryFunction.DbCreate(Path.GetDirectoryName(Application.ExecutablePath));
|
||||
|
||||
try
|
||||
{
|
||||
DbThreadEnd = false;
|
||||
dbProc.Start();
|
||||
|
||||
Active = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnPrint?.Invoke(this, ex.Message);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
DbThreadEnd = true;
|
||||
|
||||
Active = false;
|
||||
}
|
||||
|
||||
public void UpdateStatus(short st1, short st2)
|
||||
{
|
||||
Status[0] = st1;
|
||||
Status[1] = st2;
|
||||
}
|
||||
|
||||
#region UPDATE DATA
|
||||
|
||||
public void UpdateData(ref DeviceSystemData aSystemData)
|
||||
{
|
||||
SystemData = aSystemData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region MAKE ALARM HISTORY
|
||||
|
||||
private void CheckAlarm()
|
||||
{
|
||||
bool[] Data1 = csUtils.Int16ToBitArray((short)Status[0]);
|
||||
bool[] Data2 = csUtils.Int16ToBitArray((short)Status[1]);
|
||||
bool[] oData1 = csUtils.Int16ToBitArray((short)oldStatus[0]);
|
||||
bool[] oData2 = csUtils.Int16ToBitArray((short)oldStatus[1]);
|
||||
|
||||
// Cell Over Voltage
|
||||
if (oData2[0] != Data2[0])
|
||||
{
|
||||
if (Data2[0] == true)
|
||||
{
|
||||
IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_TRIP);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (oData1[0] != Data1[0])
|
||||
{
|
||||
if (Data1[0] == true)
|
||||
IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_WARNING);
|
||||
else
|
||||
IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_RELEASE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Data1[0] == false)
|
||||
IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_RELEASE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (oData1[0] != Data1[0])
|
||||
{
|
||||
if (Data1[0] == true)
|
||||
IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_WARNING);
|
||||
else
|
||||
IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_RELEASE);
|
||||
}
|
||||
}
|
||||
oldStatus = Status;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DB INSERT DATA
|
||||
private void IDInsert(string mPath, int aCode, int fCode)
|
||||
{
|
||||
//string dbFilename = mPath + csDbConstData.DataBase.FileName;
|
||||
string dbFilename = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + csDbConstData.DataBase.FileName;
|
||||
|
||||
// Open database
|
||||
string strConn = @"Data Source=" + dbFilename;
|
||||
using (var connection = new SQLiteConnection(strConn))
|
||||
{
|
||||
connection.Open();
|
||||
try
|
||||
{
|
||||
// Insert data
|
||||
using (SQLiteCommand command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = "BEGIN;"; //명시적 트렌젝션 시작
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
//sSQL = "insert into TrendTable ( TrendStamp, TagName, TagValue) Values ( " + IntToStr(stamp) + "," + name + "," + value + ");";
|
||||
command.CommandText = "INSERT INTO " + csDbConstData.DataBase.TableName + "(HTime, model, sno, alarm_name, alarm_code, flag_name, flag, param1, param2) "
|
||||
+ " Values (@HTime, @model, @sno, @alarm_name, @alarm_code, @flag_name, @flag, @param1, @param2);";
|
||||
SQLiteParameter[] p = new SQLiteParameter[]
|
||||
{
|
||||
new SQLiteParameter("@HTime", DbType.DateTime),
|
||||
new SQLiteParameter("@model", DbType.String),
|
||||
new SQLiteParameter("@sno", DbType.Int16),
|
||||
new SQLiteParameter("@alarm_name", DbType.String),
|
||||
new SQLiteParameter("@alarm_code", DbType.Int16),
|
||||
new SQLiteParameter("@flag_name", DbType.String),
|
||||
new SQLiteParameter("@flag", DbType.Int16),
|
||||
new SQLiteParameter("@param1", DbType.Decimal),
|
||||
new SQLiteParameter("@param2", DbType.Decimal),
|
||||
}; // end SQLiteParameter
|
||||
|
||||
command.Parameters.AddRange(p);
|
||||
|
||||
int result = 0;
|
||||
|
||||
p[0].Value = DateTime.Now; // DateTime
|
||||
p[1].Value = "AAA"; // Model Name
|
||||
p[2].Value = 1; // System No
|
||||
p[3].Value = csDbConstData.DB_ALARM.ALARM_NAME[aCode]; // alarm_name
|
||||
p[4].Value = aCode; // alarm_code
|
||||
p[5].Value = csDbConstData.DB_ALARM.FLAG_NAME[fCode]; // flag_name
|
||||
p[6].Value = fCode; // flag_code
|
||||
p[7].Value = 0.0; // param1
|
||||
p[8].Value = 0.0; // param2
|
||||
|
||||
try
|
||||
{
|
||||
result = command.ExecuteNonQuery();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
command.CommandText = "COMMIT;"; //명시적 트렌젝션 시작
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//MessageBox.Show(e.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
connection.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DB THREAD
|
||||
|
||||
private void dbThreadProcess()
|
||||
{
|
||||
DateTime bakDateTime = DateTime.Now;
|
||||
int ss = Config.DbLogPeriod;
|
||||
|
||||
while (DbThreadEnd == false)
|
||||
{
|
||||
if (Active)
|
||||
{
|
||||
DateTime cDate = DateTime.Now;
|
||||
|
||||
if (
|
||||
((bakDateTime.Minute != cDate.Minute)
|
||||
|| (bakDateTime.Second != cDate.Second))
|
||||
&& ((cDate.Second % ss) == 0)
|
||||
)
|
||||
{
|
||||
// Database Log Process
|
||||
try
|
||||
{
|
||||
csDbUtils.LogDbCreate(csConstData.CommType.CAN_MODEL[Config.TargetModelIndex]);
|
||||
csDbUtils.BmsLogDataInsert(ref Config, ref SystemData, cDate, CellDivUnit);
|
||||
|
||||
bakDateTime = cDate;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
941
LFP_Manager_PRM/Threads/csValueCanThread.cs
Normal file
941
LFP_Manager_PRM/Threads/csValueCanThread.cs
Normal file
@@ -0,0 +1,941 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using LFP_Manager.DataStructure;
|
||||
using LFP_Manager.Function;
|
||||
using LFP_Manager.Utils;
|
||||
using static DevExpress.Utils.Drawing.Helpers.NativeMethods;
|
||||
|
||||
namespace LFP_Manager.Threads
|
||||
{
|
||||
class csValueCanThread
|
||||
{
|
||||
#region DLL FUNCTION
|
||||
|
||||
#endregion
|
||||
|
||||
#region VARIABLES
|
||||
|
||||
int TxThreadPeriod = 10;
|
||||
int RxThreadPeriod = 1;
|
||||
|
||||
public delegate void invokeDelegate();
|
||||
|
||||
CommConfig Config;
|
||||
DeviceSystemData SystemData;
|
||||
|
||||
int SystemId = 0;
|
||||
int DCP = 0;
|
||||
|
||||
Thread canCommTx = null;
|
||||
Thread canCommRx = null;
|
||||
//string Msg = "";
|
||||
|
||||
// ValueCAN Variables
|
||||
IntPtr m_hObject; // handle for device
|
||||
NeoDevice ndNeoToOpen;
|
||||
byte[] bNetwork = new byte[255]; // List of hardware IDs
|
||||
|
||||
int iOpenDeviceType; // Storage for the device type that is open
|
||||
|
||||
////////////////////////////////////////
|
||||
bool can_bOpen = false;
|
||||
|
||||
bool CanTxThreadEnd = true;
|
||||
bool CanRxThreadEnd = true;
|
||||
|
||||
bool CanPolling = false;
|
||||
bool AutoCanTx = true;
|
||||
|
||||
// Message Queue
|
||||
icsSpyMessage[] stMessages = new icsSpyMessage[20000]; // TempSpace for messages
|
||||
|
||||
const int RX_QUEUE_MAX = 512;
|
||||
icsSpyMessage[] RxMsgQueue = new icsSpyMessage[RX_QUEUE_MAX]; // RX Message Queue
|
||||
int RxQueueFront = 0;
|
||||
int RxQueueEnd = 0;
|
||||
|
||||
void RxQueuePut(ref icsSpyMessage rxMsg)
|
||||
{
|
||||
RxMsgQueue[RxQueueFront++] = rxMsg;
|
||||
RxQueueFront %= RX_QUEUE_MAX;
|
||||
}
|
||||
|
||||
bool RxQueueGet(ref icsSpyMessage rxMsg)
|
||||
{
|
||||
if (RxQueueFront != RxQueueEnd)
|
||||
{
|
||||
rxMsg = RxMsgQueue[RxQueueEnd++];
|
||||
RxQueueEnd %= RX_QUEUE_MAX;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public event CanDataUpdate OnUpdate = null;
|
||||
public event CanDataPrint OnPrint = null;
|
||||
public event CanDataRecv OnDataRecv = null;
|
||||
|
||||
private object lockObject = new object();
|
||||
#endregion
|
||||
|
||||
#region CONSTRUCTORS
|
||||
public csValueCanThread(int sId, CommConfig aConfig, ref DeviceSystemData aSystemData)
|
||||
{
|
||||
SystemId = sId;
|
||||
Config = aConfig;
|
||||
SystemData = aSystemData;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//close the port
|
||||
int iNumberOfErrors = 0;
|
||||
int iResult = icsNeoDll.icsneoClosePort(m_hObject, ref iNumberOfErrors);
|
||||
if (iResult == 1)
|
||||
{
|
||||
//MessageBox.Show("Port Closed OK!");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(String.Format("ValueCAN - Problem ClosingPort"));
|
||||
}
|
||||
|
||||
//Clear device type and open flag
|
||||
iOpenDeviceType = 0;
|
||||
can_bOpen = false;
|
||||
}
|
||||
|
||||
public int CloseValueCAN()
|
||||
{
|
||||
int iNumberOfErrors = 0;
|
||||
int iResult = icsNeoDll.icsneoClosePort(m_hObject, ref iNumberOfErrors);
|
||||
if (iResult == 1)
|
||||
{
|
||||
//MessageBox.Show("Port Closed OK!");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(String.Format("ValueCAN - Problem ClosingPort"));
|
||||
}
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
public int ReOpenValueCAN()
|
||||
{
|
||||
int iNumberOfErrors = 0;
|
||||
int iResult = icsNeoDll.icsneoClosePort(m_hObject, ref iNumberOfErrors);
|
||||
if (iResult != 1) throw new Exception(String.Format("ValueCAN - Problem ClosingPort"));
|
||||
|
||||
iResult = icsNeoDll.icsneoOpenNeoDevice(ref ndNeoToOpen, ref m_hObject, ref bNetwork[0], 1, 0);
|
||||
if (iResult != 1) throw new Exception(String.Format("ValueCAN - Problem Opening Port"));
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
public int OpenValueCan()
|
||||
{
|
||||
int iResult;
|
||||
NeoDeviceEx[] ndNeoToOpenex = new NeoDeviceEx[16]; //Struct holding detected hardware information
|
||||
int iNumberOfDevices; //Number of hardware devices to look for
|
||||
|
||||
OptionsNeoEx neoDeviceOption = new OptionsNeoEx();
|
||||
|
||||
//Set the number of devices to find, for this example look for 16. This example will only work with the first.
|
||||
iNumberOfDevices = 15;
|
||||
|
||||
iResult = icsNeoDll.icsneoFindDevices(ref ndNeoToOpenex[0], ref iNumberOfDevices, 0, 0, ref neoDeviceOption, 0);
|
||||
if (iResult == 0)
|
||||
{
|
||||
throw new Exception(String.Format("ValueCAN - Problem finding devices"));
|
||||
}
|
||||
|
||||
if (iNumberOfDevices < 1)
|
||||
{
|
||||
throw new Exception(String.Format("ValueCAN - No devices found"));
|
||||
}
|
||||
|
||||
ndNeoToOpen = ndNeoToOpenex[0].neoDevice;
|
||||
//Open the first found device
|
||||
iResult = icsNeoDll.icsneoOpenNeoDevice(ref ndNeoToOpen, ref m_hObject, ref bNetwork[0], 1, 0);
|
||||
if (iResult == 1)
|
||||
{
|
||||
//MessageBox.Show("Port Opened OK!");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(String.Format("ValueCAN - Problem Opening Port"));
|
||||
}
|
||||
//Set the device type for later use
|
||||
iOpenDeviceType = ndNeoToOpen.DeviceType;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void ConfigBitRate(CommConfig aConfig)
|
||||
{
|
||||
//Get the network name index to set the baud rate of
|
||||
int iNetworkID = (int)eNETWORK_ID.NETID_HSCAN;
|
||||
int iBitRateToUse = csCanConstData.BaudRate.BaudRateInts[aConfig.CanBaudrate];
|
||||
|
||||
//Set the bit rate
|
||||
int iResult = icsNeoDll.icsneoSetBitRate(m_hObject, iBitRateToUse, iNetworkID);
|
||||
if (iResult != 1)
|
||||
{
|
||||
throw new Exception(String.Format("ValueCAN - Problem setting bit rate"));
|
||||
}
|
||||
else
|
||||
{
|
||||
//MessageBox.Show("Bit Rate Set");
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigFDRate(CommConfig aConfig)
|
||||
{
|
||||
//Get the network name index to set the baud rate of
|
||||
int iNetworkID = (int)eNETWORK_ID.NETID_HSCAN;
|
||||
int iBitRateToUse = 10000000;
|
||||
|
||||
//Set the bit rate
|
||||
int iResult = icsNeoDll.icsneoSetFDBitRate(m_hObject, iBitRateToUse, iNetworkID);
|
||||
if (iResult != 1)
|
||||
{
|
||||
throw new Exception(String.Format("ValueCAN - Problem setting FD bit rate"));
|
||||
}
|
||||
else
|
||||
{
|
||||
//MessageBox.Show("FD Bit Rate Set");
|
||||
}
|
||||
}
|
||||
|
||||
private void GetSetting(CommConfig aConfig)
|
||||
{
|
||||
SVCAN3Settings VcanReadSettings = new SVCAN3Settings();
|
||||
SFireSettings FireReadSettings = new SFireSettings();
|
||||
SFire2Settings Fire2ReadSettings = new SFire2Settings();
|
||||
SRADGalaxySettings RadGalaxyReadSettings = new SRADGalaxySettings();
|
||||
SVCANRFSettings VcanRFReadSettings = new SVCANRFSettings();
|
||||
SVCAN412Settings Vcan412ReadSettings = new SVCAN412Settings();
|
||||
SRADPlutoSettingsPack RADPlutoSettings = new SRADPlutoSettingsPack();
|
||||
|
||||
CAN_SETTINGS HSCanSettings = new CAN_SETTINGS();
|
||||
int iNumberOfBytes = 0;
|
||||
int iResult;
|
||||
|
||||
//Get the settigns of the connected hardware
|
||||
switch (iOpenDeviceType)
|
||||
{
|
||||
case (int)eHardwareTypes.NEODEVICE_FIRE: //FIRE
|
||||
//Get the settings
|
||||
iNumberOfBytes = System.Runtime.InteropServices.Marshal.SizeOf(FireReadSettings);
|
||||
iResult = icsNeoDll.icsneoGetFireSettings(m_hObject, ref FireReadSettings, iNumberOfBytes);
|
||||
if (iResult == 0)
|
||||
{
|
||||
MessageBox.Show("Problem reading FIRE configuration");
|
||||
return;
|
||||
}
|
||||
//Copy the HS CAN settings from the structure to sub struct
|
||||
HSCanSettings = FireReadSettings.can1;
|
||||
break;
|
||||
|
||||
case (int)eHardwareTypes.NEODEVICE_VCAN3: //Vcan3
|
||||
//Get the setting
|
||||
iNumberOfBytes = System.Runtime.InteropServices.Marshal.SizeOf(VcanReadSettings);
|
||||
iResult = icsNeoDll.icsneoGetVCAN3Settings(m_hObject, ref VcanReadSettings, iNumberOfBytes);
|
||||
if (iResult == 0)
|
||||
{
|
||||
MessageBox.Show("Problem reading VCAN3 configuration");
|
||||
return;
|
||||
}
|
||||
//Copy the HS CAN settings from the structure to sub struct
|
||||
HSCanSettings = VcanReadSettings.Can1;
|
||||
break;
|
||||
|
||||
case (int)eHardwareTypes.NEODEVICE_FIRE2: //FIRE2
|
||||
//Get the setting
|
||||
iNumberOfBytes = System.Runtime.InteropServices.Marshal.SizeOf(Fire2ReadSettings);
|
||||
iResult = icsNeoDll.icsneoGetFire2Settings(m_hObject, ref Fire2ReadSettings, iNumberOfBytes);
|
||||
if (iResult == 0)
|
||||
{
|
||||
MessageBox.Show("Problem reading FIRE2 configuration");
|
||||
return;
|
||||
}
|
||||
//Copy the HS CAN settings from the structure to sub struct
|
||||
HSCanSettings = Fire2ReadSettings.can1;
|
||||
break;
|
||||
|
||||
case (int)eHardwareTypes.NEODEVICE_RADGALAXY: //RadGalaxy
|
||||
//Get the setting
|
||||
iNumberOfBytes = System.Runtime.InteropServices.Marshal.SizeOf(RadGalaxyReadSettings);
|
||||
iResult = icsNeoDll.icsneoGetRADGalaxySettings(m_hObject, ref RadGalaxyReadSettings, iNumberOfBytes);
|
||||
if (iResult == 0)
|
||||
{
|
||||
MessageBox.Show("Problem reading RADGalaxy configuration");
|
||||
return;
|
||||
}
|
||||
//Copy the HS CAN settings from the structure to sub struct
|
||||
HSCanSettings = RadGalaxyReadSettings.Can1;
|
||||
break;
|
||||
|
||||
case (int)eHardwareTypes.NEODEVICE_VCANRF: //VcanRF
|
||||
//Get the setting
|
||||
iNumberOfBytes = System.Runtime.InteropServices.Marshal.SizeOf(VcanRFReadSettings);
|
||||
iResult = icsNeoDll.icsneoGetVCANRFSettings(m_hObject, ref VcanRFReadSettings, iNumberOfBytes);
|
||||
if (iResult == 0)
|
||||
{
|
||||
MessageBox.Show("Problem reading VCANRF configuration");
|
||||
return;
|
||||
}
|
||||
//Copy the HS CAN settings from the structure to sub struct
|
||||
HSCanSettings = VcanRFReadSettings.can1;
|
||||
break;
|
||||
|
||||
case (int)eHardwareTypes.NEODEVICE_VCAN42: //Vcan4-2
|
||||
case (int)eHardwareTypes.NEODEVICE_VCAN41: //Vcan4-1 (Same steps for both)
|
||||
//Get the setting
|
||||
iNumberOfBytes = System.Runtime.InteropServices.Marshal.SizeOf(Vcan412ReadSettings);
|
||||
iResult = icsNeoDll.icsneoGetVCAN412Settings(m_hObject, ref Vcan412ReadSettings, iNumberOfBytes);
|
||||
if (iResult == 0)
|
||||
{
|
||||
MessageBox.Show("Problem reading VCAN412 configuration");
|
||||
return;
|
||||
}
|
||||
//Copy the HS CAN settings from the structure to sub struct
|
||||
HSCanSettings = Vcan412ReadSettings.can1;
|
||||
break;
|
||||
case (int)eHardwareTypes.NEODEVICE_RADPLUTO: //RAD Pluto
|
||||
//Get the setting
|
||||
RADPlutoSettings.uiDevice = (UInt32)EDeviceSettingsType.DeviceRADPlutoSettingsType;
|
||||
iNumberOfBytes = System.Runtime.InteropServices.Marshal.SizeOf(RADPlutoSettings);
|
||||
iResult = icsNeoDll.icsneoGetDeviceSettings(m_hObject, ref RADPlutoSettings, iNumberOfBytes, 0);
|
||||
if (iResult == 0)
|
||||
{
|
||||
MessageBox.Show("Problem reading RAD Pluto configuration");
|
||||
return;
|
||||
}
|
||||
//Copy the HS CAN settings from the structure to sub struct
|
||||
HSCanSettings = RADPlutoSettings.PlutoSettings.can1;
|
||||
break;
|
||||
default:
|
||||
//Connected hardware does not support this command
|
||||
MessageBox.Show("Problem reading configuration, unsupported device");
|
||||
return;
|
||||
}
|
||||
|
||||
//fill text boxes with data from sub struct
|
||||
//txt3GPSeg1.Text = Convert.ToString(HSCanSettings.TqSeg1);
|
||||
//txt3GPSeg2.Text = Convert.ToString(HSCanSettings.TqSeg2);
|
||||
//txt3GPropDelay.Text = Convert.ToString(HSCanSettings.TqProp);
|
||||
//txt3GSJumpW.Text = Convert.ToString(HSCanSettings.TqSync);
|
||||
//txt3GBRP.Text = Convert.ToString(HSCanSettings.BRP);
|
||||
|
||||
}
|
||||
|
||||
public unsafe bool Start(CommConfig aConfig, int sId, bool aPolling)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
SystemId = sId;
|
||||
CanPolling = aPolling;
|
||||
|
||||
try
|
||||
{
|
||||
if (OpenValueCan() == 0)
|
||||
throw new System.InvalidOperationException("Failed to open the device, please check if the device type and device index number are correct.");
|
||||
|
||||
// Baudrate Config
|
||||
ConfigBitRate(aConfig);
|
||||
|
||||
// FD Rate Config
|
||||
ConfigFDRate(aConfig);
|
||||
|
||||
// Get Setting Value
|
||||
GetSetting(aConfig);
|
||||
|
||||
can_bOpen = true;
|
||||
|
||||
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
|
||||
|
||||
private int GetErrorValueCAN()
|
||||
{
|
||||
int result = 0;
|
||||
int[] iErrors = new int[600]; //Array for Error Numbers
|
||||
int iNumberOfErrors = 0; // Storage for number of errors
|
||||
|
||||
// Read Out the errors
|
||||
int iResult = icsNeoDll.icsneoGetErrorMessages(m_hObject, ref iErrors[0], ref iNumberOfErrors);
|
||||
|
||||
// Test the returned result
|
||||
if (iResult == 0)
|
||||
{
|
||||
MessageBox.Show("Problem Reading Errors");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iNumberOfErrors != 0)
|
||||
{
|
||||
ReOpenValueCAN();
|
||||
for (int iCount = 0; iCount < iNumberOfErrors; iCount++)
|
||||
{
|
||||
if (iErrors[iCount] == 44) result++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private void SendPacketByValueCAN(UInt32 ExID, byte[] Data)
|
||||
{
|
||||
Monitor.Enter(lockObject);
|
||||
try
|
||||
{
|
||||
//OnPrint?.Invoke(this, csCanCommFunction.PacketToMsg(sendobj, 1));
|
||||
|
||||
long lResult;
|
||||
icsSpyMessage stMessagesTx = new icsSpyMessage();
|
||||
long lNetworkID;
|
||||
string sTempString;
|
||||
|
||||
// Read the Network we will transmit on (indicated by lstNetwork ListBox)
|
||||
sTempString = "HSCAN";
|
||||
lNetworkID = icsNeoDll.GetNetworkIDfromString(ref sTempString);
|
||||
|
||||
// Is this a CAN network or a J1850/ISO one?
|
||||
// load the message structure
|
||||
|
||||
//Make id Extended
|
||||
stMessagesTx.StatusBitField = Convert.ToInt16(eDATA_STATUS_BITFIELD_1.SPY_STATUS_XTD_FRAME);
|
||||
|
||||
stMessagesTx.ArbIDOrHeader = (int)ExID; // The ArbID
|
||||
stMessagesTx.NumberBytesData = (byte)Data.Length; // The number of Data Bytes
|
||||
if (stMessagesTx.NumberBytesData > 8) stMessagesTx.NumberBytesData = 8; // You can only have 8 databytes with CAN
|
||||
// Load all of the data bytes in the structure
|
||||
|
||||
stMessagesTx.Data1 = Data[0];
|
||||
stMessagesTx.Data2 = Data[1];
|
||||
stMessagesTx.Data3 = Data[2];
|
||||
stMessagesTx.Data4 = Data[3];
|
||||
stMessagesTx.Data5 = Data[4];
|
||||
stMessagesTx.Data6 = Data[5];
|
||||
stMessagesTx.Data7 = Data[6];
|
||||
stMessagesTx.Data8 = Data[7];
|
||||
|
||||
// Transmit the assembled message
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
lResult = icsNeoDll.icsneoTxMessages(m_hObject, ref stMessagesTx, Convert.ToInt32(lNetworkID), 1);
|
||||
if (lResult == 1)
|
||||
break;
|
||||
else
|
||||
{
|
||||
if (GetErrorValueCAN() == 0) break;
|
||||
//ReOpenValueCAN();
|
||||
}
|
||||
}
|
||||
//GetErrorValueCAN();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//throw new Exception(String.Format("CAN Transmit Exception", ex.Message));
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(lockObject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private unsafe void SendPacketByValueCAN(ref VCI_CAN_OBJ senObj)
|
||||
{
|
||||
long lResult;
|
||||
icsSpyMessage stMessagesTx = new icsSpyMessage();
|
||||
long lNetworkID;
|
||||
string sTempString;
|
||||
|
||||
// Read the Network we will transmit on (indicated by lstNetwork ListBox)
|
||||
sTempString = "HSCAN";
|
||||
lNetworkID = icsNeoDll.GetNetworkIDfromString(ref sTempString);
|
||||
|
||||
// Is this a CAN network or a J1850/ISO one?
|
||||
// load the message structure
|
||||
|
||||
//Make id Extended
|
||||
stMessagesTx.StatusBitField = Convert.ToInt16(eDATA_STATUS_BITFIELD_1.SPY_STATUS_XTD_FRAME);
|
||||
|
||||
stMessagesTx.ArbIDOrHeader = (int)senObj.ID; // The ArbID
|
||||
stMessagesTx.NumberBytesData = (byte)senObj.DataLen; // The number of Data Bytes
|
||||
if (stMessagesTx.NumberBytesData > 8) stMessagesTx.NumberBytesData = 8; // You can only have 8 databytes with CAN
|
||||
// Load all of the data bytes in the structure
|
||||
|
||||
stMessagesTx.Data1 = senObj.Data[0];
|
||||
stMessagesTx.Data2 = senObj.Data[1];
|
||||
stMessagesTx.Data3 = senObj.Data[2];
|
||||
stMessagesTx.Data4 = senObj.Data[3];
|
||||
stMessagesTx.Data5 = senObj.Data[4];
|
||||
stMessagesTx.Data6 = senObj.Data[5];
|
||||
stMessagesTx.Data7 = senObj.Data[6];
|
||||
stMessagesTx.Data8 = senObj.Data[7];
|
||||
|
||||
// Transmit the assembled message
|
||||
lResult = icsNeoDll.icsneoTxMessages(m_hObject, ref stMessagesTx, Convert.ToInt32(lNetworkID), 1);
|
||||
// Test the returned result
|
||||
if (lResult != 1)
|
||||
{
|
||||
MessageBox.Show(String.Format("Problem Transmitting Message - ({0})", lResult));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetAutoTx(bool autoTx)
|
||||
{
|
||||
AutoCanTx = autoTx;
|
||||
}
|
||||
|
||||
unsafe public void SendDataFromApp(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];
|
||||
|
||||
SendPacketByValueCAN(sendobj.ID, data);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public void SetDCP(int aDCP)
|
||||
{
|
||||
DCP = aDCP;
|
||||
}
|
||||
|
||||
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 Voltage Calibration
|
||||
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, int dcp, ref DeviceParamData aParam, ref DeviceCalibration aCalib)
|
||||
{
|
||||
if (can_bOpen == false) return;
|
||||
|
||||
VCI_CAN_OBJ sendobj = MakeTxData(sId, mode, flag, dcp, ref aParam, ref aCalib);
|
||||
|
||||
byte[] data = new byte[8];
|
||||
for (int i = 0; i < 8; i++) data[i] = sendobj.Data[i];
|
||||
|
||||
SendPacketByValueCAN(sendobj.ID, data);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region COMM TX THREAD
|
||||
|
||||
int current_cmd = 0;
|
||||
int RxSystemId = 0;
|
||||
|
||||
public int GetCommSystemId()
|
||||
{
|
||||
return RxSystemId;
|
||||
}
|
||||
|
||||
unsafe private void canTxThread()
|
||||
{
|
||||
int txTick = 0;
|
||||
|
||||
while (CanTxThreadEnd == false)
|
||||
{
|
||||
txTick++;
|
||||
if (txTick >= TxThreadPeriod)
|
||||
{
|
||||
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(1);
|
||||
}
|
||||
txTick %= TxThreadPeriod;
|
||||
}
|
||||
GetMessageBuff();
|
||||
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void TxProcess(ref int aflag)
|
||||
{
|
||||
switch (current_cmd)
|
||||
{
|
||||
case 20: current_cmd = 900; break;
|
||||
case 900: current_cmd = 901; break;
|
||||
case 901: current_cmd = 902; break;
|
||||
case 902: current_cmd = 1; break;
|
||||
case 1: current_cmd = 19; break;
|
||||
case 19: current_cmd = 3; break;
|
||||
case 3: current_cmd = 4; break;
|
||||
case 4: current_cmd = 11; break;
|
||||
case 11: current_cmd = 16; break;
|
||||
case 16: current_cmd = 20; break;
|
||||
default: current_cmd = 20; break;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region COMM RX THREAD
|
||||
unsafe private void canRxThread()
|
||||
{
|
||||
while (CanRxThreadEnd == false)
|
||||
{
|
||||
DateTime aTime = DateTime.Now;
|
||||
|
||||
if (GetMessageProcess())
|
||||
{
|
||||
// Received data
|
||||
SystemData.ShelfCommFail = false;
|
||||
SystemData.LastRxTime = DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
TimeSpan dTime = DateTime.Now - SystemData.LastRxTime;
|
||||
if (SystemData.ShelfCommFail == false)
|
||||
{
|
||||
if (dTime.TotalSeconds > 10)
|
||||
{
|
||||
SystemData.ShelfCommFail = true;
|
||||
DataInit();
|
||||
OnUpdate?.Invoke(this, ref SystemData);
|
||||
}
|
||||
}
|
||||
}
|
||||
Thread.Sleep(RxThreadPeriod);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe private int GetMessageBuff()
|
||||
{
|
||||
int result = 0;
|
||||
int lNumberOfMessages = 1;
|
||||
int lNumberOfErrors = 0;
|
||||
//double dTime = 0;
|
||||
|
||||
// read the messages from the driver
|
||||
int lResult = icsNeoDll.icsneoGetMessages(m_hObject, ref stMessages[0], ref lNumberOfMessages, ref lNumberOfErrors);
|
||||
|
||||
// was the read successful?
|
||||
if (lResult == 1)
|
||||
{
|
||||
for (int i = 0; i < lNumberOfMessages; i++)
|
||||
{
|
||||
// Calculate the messages timestamp
|
||||
//lResult = icsNeoDll.icsneoGetTimeStampForMsg(m_hObject, ref stMessages[i], ref dTime);
|
||||
if ((stMessages[i].StatusBitField & Convert.ToInt32(eDATA_STATUS_BITFIELD_1.SPY_STATUS_TX_MSG)) == 0)
|
||||
{
|
||||
// Rx Data
|
||||
if (stMessages[i].ArbIDOrHeader != 0)
|
||||
RxQueuePut(ref stMessages[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool GetMessageProcess()
|
||||
{
|
||||
bool result = false;
|
||||
icsSpyMessage rxMsg = new icsSpyMessage();
|
||||
|
||||
if (RxQueueGet(ref rxMsg))
|
||||
{
|
||||
switch (rxMsg.Protocol)
|
||||
{
|
||||
case (int)ePROTOCOL.SPY_PROTOCOL_CAN:
|
||||
{
|
||||
UInt32 exID = (UInt32)rxMsg.ArbIDOrHeader;
|
||||
byte[] rData = new byte[8];
|
||||
|
||||
rData[0] = rxMsg.Data1;
|
||||
rData[1] = rxMsg.Data2;
|
||||
rData[2] = rxMsg.Data3;
|
||||
rData[3] = rxMsg.Data4;
|
||||
rData[4] = rxMsg.Data5;
|
||||
rData[5] = rxMsg.Data6;
|
||||
rData[6] = rxMsg.Data7;
|
||||
rData[7] = rxMsg.Data8;
|
||||
|
||||
OnPrint?.Invoke(this, csCanCommFunction.PacketToMsg(exID, rData, 0));
|
||||
|
||||
PACKET_HEADER pHeader = csCanCommFunction.CovertPtoH(exID);
|
||||
switch (pHeader.Index)
|
||||
{
|
||||
case 0x01: // Inventory Data Packet
|
||||
if ((pHeader.SA == (200 + SystemId)))
|
||||
{
|
||||
result = true;
|
||||
|
||||
RxSystemId = pHeader.SA - 200;
|
||||
csCanCommFunction.CanInvRxProcess(RxSystemId, exID, rData, ref SystemData, DateTime.Now);
|
||||
OnUpdate?.Invoke(this, ref SystemData);
|
||||
}
|
||||
break;
|
||||
case 0x04: // Firmware Update Packet
|
||||
OnDataRecv?.Invoke(exID, rData);
|
||||
break;
|
||||
case 0x06: // Normal Packet
|
||||
if (pHeader.SA == (200 + SystemId))
|
||||
{
|
||||
result = true;
|
||||
|
||||
RxSystemId = pHeader.SA - 200;
|
||||
csCanCommFunction.CanRxProcess(ref Config, RxSystemId, exID, rData, ref SystemData, DateTime.Now);
|
||||
OnUpdate?.Invoke(this, ref SystemData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DATA INIT
|
||||
|
||||
private void DataInit()
|
||||
{
|
||||
SystemData.ShelfCommFail = true;
|
||||
|
||||
for (int j = 0; j < csConstData.SystemInfo.MAX_MODULE_CELL_SIZE; j++)
|
||||
{
|
||||
SystemData.ValueData.CellVoltage[j] = 0;
|
||||
}
|
||||
for (int j = 0; j < csConstData.SystemInfo.MAX_MODULE_TEMP_SIZE; j++)
|
||||
{
|
||||
SystemData.ValueData.CellTemperature[j] = 0;
|
||||
}
|
||||
SystemData.ValueData.voltageOfPack = 0;
|
||||
SystemData.ValueData.current = 0;
|
||||
SystemData.ValueData.rSOC = 0;
|
||||
SystemData.AvgData.maxCellVoltage = 0;
|
||||
SystemData.AvgData.minCellVoltage = 0;
|
||||
SystemData.AvgData.avgCellVoltage = 0;
|
||||
SystemData.AvgData.maxTemp = 0;
|
||||
SystemData.AvgData.minTemp = 0;
|
||||
SystemData.AvgData.avgTemp = 0;
|
||||
SystemData.heatbeat = 0;
|
||||
SystemData.StatusData.warning = 0;
|
||||
SystemData.StatusData.protect = 0;
|
||||
|
||||
for (int j = 0; j < SystemData.Information.pcb_sn.Length; j++)
|
||||
{
|
||||
SystemData.Information.pcb_sn[j] = 0;
|
||||
}
|
||||
for (int j = 0; j < SystemData.Information.module_sn.Length; j++)
|
||||
{
|
||||
SystemData.Information.module_sn[j] = 0;
|
||||
}
|
||||
|
||||
SystemData.CalibriationData.Battery.Capacity = 0;
|
||||
SystemData.CalibriationData.Current.ChaAndDchSelect = 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user