HONGRI_uds_tools/CAN_Tool/CanDevice/PCAN/Pcan.cs
liudagui beceab4798 第一次提交:
支持广成CAN,PCAN,同星(要用低版本的TSMaster),TOOMOSS(没有测试过)
2024-11-06 16:52:30 +08:00

370 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using Peak.Can.Basic;
namespace Can
{
using TPCANHandle = System.UInt16;
//using TPCANBitrateFD = System.String;
//using TPCANTimestampFD = System.UInt64;
class PcanDevice : CanDevice
{
private TPCANHandle PcanHandle;
Thread ReadThread;
AutoResetEvent ReceiveEvent;
bool IsConnect;
//private TPCANBaudrate Baudrate;
public PcanDevice()
{
IsConnect = false;
this.PcanHandle = PCANBasic.PCAN_USBBUS1;
}
public override string CanInit()
{
TPCANStatus stsResult;
string ret;
/*stsResult = PCANBasic.Initialize(
PcanHandle,
TPCANBaudrate.PCAN_BAUD_500K,
TPCANType.PCAN_TYPE_ISA,
(UInt32)0x0100,
(UInt16)0x03);*/
stsResult = PCANBasic.Initialize(
PcanHandle,
TPCANBaudrate.PCAN_BAUD_500K,
TPCANType.PCAN_TYPE_ISA,
(UInt32)0x0,
(UInt16)0x0);
if (stsResult != TPCANStatus.PCAN_ERROR_OK)
{
ret = GetFormatedError(stsResult);
}
else //连接成功
{
IsConnect = true;
ReadThread = new Thread(new ThreadStart(this.CANReadThreadFunc));
ReceiveEvent = new System.Threading.AutoResetEvent(false);
ReadThread.IsBackground = true;
//ReadThread.Start();
ret = "OK";
}
return ret;
}
public override string CanDeInit()
{
base.CanDeInit();
TPCANStatus stsResult;
stsResult = PCANBasic.Uninitialize(PcanHandle);
if (TPCANStatus.PCAN_ERROR_OK == stsResult)
{
IsConnect = false;
ReadThread.Abort();
return "OK";
}
else
{
return GetFormatedError(stsResult);
}
}
public override string CanReceiveEventEnable()
{
string ret;
if (null == ReadThread)
{
ret = "线程为null";
}
else
{
ReadThread.Start();
ret = "OK";
}
return ret;
}
public override string CanReceiveEventDisable()
{
string ret;
if (null == ReadThread)
{
ret = "线程为null";
}
else
{
ReadThread.Abort();
ret = "OK";
}
return ret;
}
public override string CanSetFilter(UInt32 stratId, UInt32 endId)
{
string ret;
TPCANStatus stsResult;
stsResult = PCANBasic.FilterMessages(PcanHandle, stratId, endId, TPCANMode.PCAN_MODE_STANDARD);
//stsResult = PCANBasic.FilterMessages(PcanHandle, stratId, endId, TPCANMode.PCAN_MODE_EXTENDED);
if (stsResult != TPCANStatus.PCAN_ERROR_OK)
{
ret = GetFormatedError(stsResult);
}
else
{
ret = "OK";
}
return ret;
}
private string GetFormatedError(TPCANStatus error)
{
StringBuilder strTemp;
// Creates a buffer big enough for a error-text
//
strTemp = new StringBuilder(256);
// Gets the text using the GetErrorText API function
// If the function success, the translated error is returned. If it fails,
// a text describing the current error is returned.
//
if (PCANBasic.GetErrorText(error, 0, strTemp) != TPCANStatus.PCAN_ERROR_OK)
return string.Format("An error occurred. Error-code's text ({0:X}) couldn't be retrieved", error);
else
return strTemp.ToString();
}
public override void CanSendMessage(UInt32 id, byte[] data, int len)
{
TPCANMsg msg;
msg.ID = id;
msg.DATA = data;
msg.LEN = MessagesLenToDlc(len);
msg.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD;
PCANBasic.Write(PcanHandle, ref msg);
}
public override bool CanReadMessage(ref UInt32 id, byte[] data, ref int len)
{
TPCANMsg msg;
TPCANTimestamp timeStamp;
TPCANStatus stsResult;
stsResult = PCANBasic.Read(PcanHandle, out msg, out timeStamp);
if (stsResult != TPCANStatus.PCAN_ERROR_QRCVEMPTY)
{
id = msg.ID;
msg.DATA.CopyTo(data, 0);
len = msg.LEN;
return true;
}
else
{
return false;
}
}
private void CANReadThreadFunc()
{
UInt32 id = 0;
byte[] data = new byte[8];
int len = 0;
UInt32 iBuffer;
TPCANStatus stsResult;
iBuffer = Convert.ToUInt32(ReceiveEvent.SafeWaitHandle.DangerousGetHandle().ToInt32());
// Sets the handle of the Receive-Event.
//
stsResult = PCANBasic.SetValue(PcanHandle, TPCANParameter.PCAN_RECEIVE_EVENT, ref iBuffer, sizeof(UInt32));
if (stsResult != TPCANStatus.PCAN_ERROR_OK)
{
return;
}
// While this mode is selected
while (IsConnect)
{
if (ReceiveEvent.WaitOne(50))
{
while (true == CanReadMessage(ref id, data, ref len))
{
CanReadEventInvoke(id, data, len);
}
}
}
}
public override string CanFdInit()
{
string ret;
TPCANStatus stsResult;
stsResult = PCANBasic.InitializeFD(PcanHandle, "f_clock_mhz=24, nom_brp=8, nom_tseg1=4, nom_tseg2=1, nom_sjw=1, data_brp=2, data_tseg1=4, data_tseg2=1, data_sjw=1");
if (stsResult != TPCANStatus.PCAN_ERROR_OK)
{
ret = GetFormatedError(stsResult);
}
else //连接成功
{
IsConnect = true;
ReadThread = new Thread(new ThreadStart(this.CanFdReadThreadFunc));
ReceiveEvent = new System.Threading.AutoResetEvent(false);
ReadThread.IsBackground = true;
ret = "OK";
}
return ret;
}
//CANFD初始化
public override string CanFdDeInit()
{
return this.CanDeInit();
}
public override string CanFdReceiveEventEnable()
{
return this.CanReceiveEventEnable();
}
public override string CanFdReceiveEventDisable()
{
return this.CanReceiveEventDisable();
}
//CANFD设置ID过滤器
public override string CanFdSetFilter(UInt32 startId, UInt32 endId)
{
return this.CanSetFilter(startId, endId);
}
//CANFD发送一帧报文
public override void CanFdSendMessage(UInt32 id, byte[] data, int len)
{
TPCANMsgFD msg = new TPCANMsgFD();
msg.ID = id;
msg.DLC = MessagesLenToDlc(len);
msg.DATA = new byte[64];
Array.Copy(data, msg.DATA, len);
//msg.MSGTYPE = (chbExtended.Checked) ? TPCANMessageType.PCAN_MESSAGE_EXTENDED : TPCANMessageType.PCAN_MESSAGE_STANDARD;
// msg.MSGTYPE |= (chbFD.Checked) ? TPCANMessageType.PCAN_MESSAGE_FD : TPCANMessageType.PCAN_MESSAGE_STANDARD;
//msg.MSGTYPE |= (chbBRS.Checked) ? TPCANMessageType.PCAN_MESSAGE_BRS : TPCANMessageType.PCAN_MESSAGE_STANDARD;
msg.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD;
msg.MSGTYPE |= TPCANMessageType.PCAN_MESSAGE_FD;
msg.MSGTYPE |= TPCANMessageType.PCAN_MESSAGE_BRS;
//msg.MSGTYPE |= TPCANMessageType.PCAN_MESSAGE_RTR;
PCANBasic.WriteFD(PcanHandle, ref msg);
}
//CANFD从FIFO读取一帧报文
public override bool CanFdReadMessage(ref UInt32 id, byte[] data, ref int len)
{
TPCANMsgFD msg;
UInt64 timeStamp;
TPCANStatus stsResult;
// We execute the "Read" function of the PCANBasic
//
stsResult = PCANBasic.ReadFD(PcanHandle, out msg, out timeStamp);
if (stsResult != TPCANStatus.PCAN_ERROR_QRCVEMPTY)
{
id = msg.ID;
msg.DATA.CopyTo(data, 0);
len = MessagesDlcToLen(msg.DLC);
return true;
}
else
{
return false;
}
}
private void CanFdReadThreadFunc()
{
UInt32 id = 0;
byte[] data = new byte[64];
int len = 0;
UInt32 iBuffer;
TPCANStatus stsResult;
iBuffer = Convert.ToUInt32(ReceiveEvent.SafeWaitHandle.DangerousGetHandle().ToInt32());
// Sets the handle of the Receive-Event.
//
stsResult = PCANBasic.SetValue(PcanHandle, TPCANParameter.PCAN_RECEIVE_EVENT, ref iBuffer, sizeof(UInt32));
if (stsResult != TPCANStatus.PCAN_ERROR_OK)
{
return;
}
// While this mode is selected
while (IsConnect)
{
if (ReceiveEvent.WaitOne(50))
{
while (true == CanFdReadMessage(ref id, data, ref len))
{
CanReadEventInvoke(id, data, len);
}
}
}
}
}
}