Files
PR_PRM_GUI/LFP_Manager_PRM/Threads/csValueCanThread.cs
2026-02-11 10:10:43 +09:00

942 lines
36 KiB
C#

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
}
}