370 lines
10 KiB
C#
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);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|