This is how I initialize the CAN channel:
Code: Select all
protected override void Initialize()
{
lock (_PortLock)
{
TPCANStatus ret = PCANBasic.Initialize(
PCANHandle,
PCANBaudrate);
if (ret != TPCANStatus.PCAN_ERROR_OK)
throw new IOException(String.Format("{0} failed to connect: {1}", Name, ret));
//to save sent frames on receive side with timestamp
UInt32 iBuffer;
iBuffer = PCANBasic.PCAN_PARAMETER_ON;
TPCANStatus ret2 = PCANBasic.SetValue(PCANHandle, TPCANParameter.PCAN_ALLOW_ECHO_FRAMES, ref iBuffer, sizeof(UInt32));
if (ret2 != TPCANStatus.PCAN_ERROR_OK)
throw new IOException(String.Format("{0} failed to activate echo frames: {1}", Name, ret2));
}
}
Code: Select all
protected override Frame ReadInternal(int timeout)
{
TPCANMsg pcanMsg;
TPCANTimestamp timestamp;
long ticks;
// start the timeout watch
Stopwatch watch = new Stopwatch();
watch.Start();
TPCANStatus ret;
// keep trying to read if the receive queue is empty
do
{
lock (_PortLock)
{
ret = PCANBasic.Read(PCANHandle, out pcanMsg, out timestamp);
}
} while (ret == TPCANStatus.PCAN_ERROR_QRCVEMPTY && (Timeout.IsInfinite(timeout) || watch.ElapsedMilliseconds < timeout));
// if there was still no success then the operation has timed out
if (ret == TPCANStatus.PCAN_ERROR_QRCVEMPTY)
{
// if there is no timeout then simply return null
if (timeout == Timeout.None)
return null;
else
throw new TimeoutException(String.Format("{0} read timed out", Name));
}
// if it was not a timeout then we got a different error
if (ret != TPCANStatus.PCAN_ERROR_OK)
throw new CANException(String.Format("{0} failed to read: {1}", Name, ret));
//ticks according to peakcan
ticks = timestamp.micros + timestamp.millis * 1000 + 0x100000000 * 1000 * timestamp.millis_overflow;
if ((pcanMsg.MSGTYPE & TPCANMessageType.PCAN_MESSAGE_ECHO) == TPCANMessageType.PCAN_MESSAGE_ECHO)
{
return new Frame((int)pcanMsg.ID, FrameType.Standard_echo, pcanMsg.DATA, ticks);
}
return new Frame((int)pcanMsg.ID, FrameTypeFromPCAN(pcanMsg.MSGTYPE), pcanMsg.DATA,ticks);
}
Code: Select all
private void OnFrameReceived(Frame frame, Message msg)
{
var timestamp = frame.Ticks;
if (frame.Type == FrameType.Standard_echo)
{
frame.Type = FrameType.Extended;
Log(frame, msg, timestamp, TraceEntryDirection.TX);
}
else
{
Log(frame, msg, timestamp, TraceEntryDirection.RX);
}
}
Code: Select all
private void Log(Frame frame, Message msg, DateTime timeStamp, TraceEntryDirection direction)
{
var entry = new TraceEntry(frame, msg, timeStamp, direction);
foreach (var sink in _Sinks)
sink.Write(entry);
}
Code: Select all
public void Write(TraceEntry entry)
{
var ts = entry.Ticks;
var data = String.Join(" ", entry.Frame.Data.Select((b) => $"{b:X2}"));
var line = $"[{ts}] Dir: {entry.Direction} Name: {entry.Message?.Name} ID: {entry.Frame.Id:X} Type: {entry.Frame.Type} Data: {data}";
lock (_Lock)
{
_Writer?.WriteLine(line);
}
}