Skip to content
24 changes: 19 additions & 5 deletions can/interfaces/ixxat/canlib_vcinpl.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import functools
import logging
import sys
import time
import warnings
from typing import Callable, List, Optional, Sequence, Tuple, Union

Expand Down Expand Up @@ -619,7 +620,15 @@ def __init__(
log.info("Accepting ID: 0x%X MASK: 0x%X", code, mask)

# Start the CAN controller. Messages will be forwarded to the channel
start_begin = time.time()
_canlib.canControlStart(self._control_handle, constants.TRUE)
start_end = time.time()

# Calculate an offset to make them relative to epoch
# Assume that the time offset is in the middle of the start command
self._timeoffset = start_begin + (start_end - start_begin / 2)
self._overrunticks = 0
self._starttickoffset = 0

# For cyclic transmit list. Set when .send_periodic() is first called
self._scheduler = None
Expand Down Expand Up @@ -692,6 +701,9 @@ def _recv_internal(self, timeout):
f"Unknown CAN info message code {self._message.abData[0]}",
)
)
# Handle CAN start info message
if self._message.abData[0] == constants.CAN_INFO_START:
self._starttickoffset = self._message.dwTime
elif self._message.uMsgInfo.Bits.type == constants.CAN_MSGTYPE_ERROR:
if self._message.uMsgInfo.Bytes.bFlags & constants.CAN_MSGFLAGS_OVR:
log.warning("CAN error: data overrun")
Expand All @@ -708,7 +720,8 @@ def _recv_internal(self, timeout):
self._message.uMsgInfo.Bytes.bFlags,
)
elif self._message.uMsgInfo.Bits.type == constants.CAN_MSGTYPE_TIMEOVR:
pass
# Add the number of timestamp overruns to the high word
self._overrunticks += self._message.dwMsgId << 32
else:
log.warning(
"Unexpected message info type 0x%X",
Expand Down Expand Up @@ -740,11 +753,12 @@ def _recv_internal(self, timeout):
# Timed out / can message type is not DATA
return None, True

# The _message.dwTime is a 32bit tick value and will overrun,
# so expect to see the value restarting from 0
rx_msg = Message(
timestamp=self._message.dwTime
/ self._tick_resolution, # Relative time in s
timestamp=(
(self._message.dwTime + self._overrunticks - self._starttickoffset)
/ self._tick_resolution
)
+ self._timeoffset,
is_remote_frame=bool(self._message.uMsgInfo.Bits.rtr),
is_extended_id=bool(self._message.uMsgInfo.Bits.ext),
arbitration_id=self._message.dwMsgId,
Expand Down
24 changes: 18 additions & 6 deletions can/interfaces/ixxat/canlib_vcinpl2.py
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,15 @@ def __init__(
log.info("Accepting ID: 0x%X MASK: 0x%X", code, mask)

# Start the CAN controller. Messages will be forwarded to the channel
start_begin = time.time()
_canlib.canControlStart(self._control_handle, constants.TRUE)
start_end = time.time()

# Calculate an offset to make them relative to epoch
# Assume that the time offset is in the middle of the start command
self._timeoffset = start_begin + (start_end - start_begin / 2)
self._overrunticks = 0
self._starttickoffset = 0

# For cyclic transmit list. Set when .send_periodic() is first called
self._scheduler = None
Expand Down Expand Up @@ -831,7 +839,9 @@ def _recv_internal(self, timeout):
f"Unknown CAN info message code {self._message.abData[0]}",
)
)

# Handle CAN start info message
elif self._message.abData[0] == constants.CAN_INFO_START:
self._starttickoffset = self._message.dwTime
elif (
self._message.uMsgInfo.Bits.type == constants.CAN_MSGTYPE_ERROR
):
Expand All @@ -853,7 +863,8 @@ def _recv_internal(self, timeout):
self._message.uMsgInfo.Bits.type
== constants.CAN_MSGTYPE_TIMEOVR
):
pass
# Add the number of timestamp overruns to the high word
self._overrunticks += self._message.dwMsgId << 32
else:
log.warning("Unexpected message info type")

Expand All @@ -867,11 +878,12 @@ def _recv_internal(self, timeout):
return None, True

data_len = dlc2len(self._message.uMsgInfo.Bits.dlc)
# The _message.dwTime is a 32bit tick value and will overrun,
# so expect to see the value restarting from 0
rx_msg = Message(
timestamp=self._message.dwTime
/ self._tick_resolution, # Relative time in s
timestamp=(
(self._message.dwTime + self._overrunticks - self._starttickoffset)
/ self._tick_resolution
)
+ self._timeoffset,
is_remote_frame=bool(self._message.uMsgInfo.Bits.rtr),
is_fd=bool(self._message.uMsgInfo.Bits.edl),
is_rx=True,
Expand Down
Loading