Skip to content

Commit f43bedb

Browse files
authored
Handle timer overflow message and build timestamp according to the epoch in IXXATBus (#1934)
* Handle timer overflow message and build timestamp according to the epoch * Revert "Handle timer overflow message and build timestamp according to the epoch" This reverts commit e0ccfb0. * Handle timer overflow message and build timestamp according to the epoch * Fix formating issues * Format with black
1 parent dcc33a7 commit f43bedb

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

can/interfaces/ixxat/canlib_vcinpl.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import functools
1414
import logging
1515
import sys
16+
import time
1617
import warnings
1718
from collections.abc import Sequence
1819
from typing import Callable, Optional, Union
@@ -620,7 +621,15 @@ def __init__(
620621
log.info("Accepting ID: 0x%X MASK: 0x%X", code, mask)
621622

622623
# Start the CAN controller. Messages will be forwarded to the channel
624+
start_begin = time.time()
623625
_canlib.canControlStart(self._control_handle, constants.TRUE)
626+
start_end = time.time()
627+
628+
# Calculate an offset to make them relative to epoch
629+
# Assume that the time offset is in the middle of the start command
630+
self._timeoffset = start_begin + (start_end - start_begin / 2)
631+
self._overrunticks = 0
632+
self._starttickoffset = 0
624633

625634
# For cyclic transmit list. Set when .send_periodic() is first called
626635
self._scheduler = None
@@ -693,6 +702,9 @@ def _recv_internal(self, timeout):
693702
f"Unknown CAN info message code {self._message.abData[0]}",
694703
)
695704
)
705+
# Handle CAN start info message
706+
if self._message.abData[0] == constants.CAN_INFO_START:
707+
self._starttickoffset = self._message.dwTime
696708
elif self._message.uMsgInfo.Bits.type == constants.CAN_MSGTYPE_ERROR:
697709
if self._message.uMsgInfo.Bytes.bFlags & constants.CAN_MSGFLAGS_OVR:
698710
log.warning("CAN error: data overrun")
@@ -709,7 +721,8 @@ def _recv_internal(self, timeout):
709721
self._message.uMsgInfo.Bytes.bFlags,
710722
)
711723
elif self._message.uMsgInfo.Bits.type == constants.CAN_MSGTYPE_TIMEOVR:
712-
pass
724+
# Add the number of timestamp overruns to the high word
725+
self._overrunticks += self._message.dwMsgId << 32
713726
else:
714727
log.warning(
715728
"Unexpected message info type 0x%X",
@@ -741,11 +754,12 @@ def _recv_internal(self, timeout):
741754
# Timed out / can message type is not DATA
742755
return None, True
743756

744-
# The _message.dwTime is a 32bit tick value and will overrun,
745-
# so expect to see the value restarting from 0
746757
rx_msg = Message(
747-
timestamp=self._message.dwTime
748-
/ self._tick_resolution, # Relative time in s
758+
timestamp=(
759+
(self._message.dwTime + self._overrunticks - self._starttickoffset)
760+
/ self._tick_resolution
761+
)
762+
+ self._timeoffset,
749763
is_remote_frame=bool(self._message.uMsgInfo.Bits.rtr),
750764
is_extended_id=bool(self._message.uMsgInfo.Bits.ext),
751765
arbitration_id=self._message.dwMsgId,

can/interfaces/ixxat/canlib_vcinpl2.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,15 @@ def __init__(
727727
log.info("Accepting ID: 0x%X MASK: 0x%X", code, mask)
728728

729729
# Start the CAN controller. Messages will be forwarded to the channel
730+
start_begin = time.time()
730731
_canlib.canControlStart(self._control_handle, constants.TRUE)
732+
start_end = time.time()
733+
734+
# Calculate an offset to make them relative to epoch
735+
# Assume that the time offset is in the middle of the start command
736+
self._timeoffset = start_begin + (start_end - start_begin / 2)
737+
self._overrunticks = 0
738+
self._starttickoffset = 0
731739

732740
# For cyclic transmit list. Set when .send_periodic() is first called
733741
self._scheduler = None
@@ -832,7 +840,9 @@ def _recv_internal(self, timeout):
832840
f"Unknown CAN info message code {self._message.abData[0]}",
833841
)
834842
)
835-
843+
# Handle CAN start info message
844+
elif self._message.abData[0] == constants.CAN_INFO_START:
845+
self._starttickoffset = self._message.dwTime
836846
elif (
837847
self._message.uMsgInfo.Bits.type == constants.CAN_MSGTYPE_ERROR
838848
):
@@ -854,7 +864,8 @@ def _recv_internal(self, timeout):
854864
self._message.uMsgInfo.Bits.type
855865
== constants.CAN_MSGTYPE_TIMEOVR
856866
):
857-
pass
867+
# Add the number of timestamp overruns to the high word
868+
self._overrunticks += self._message.dwMsgId << 32
858869
else:
859870
log.warning("Unexpected message info type")
860871

@@ -868,11 +879,12 @@ def _recv_internal(self, timeout):
868879
return None, True
869880

870881
data_len = dlc2len(self._message.uMsgInfo.Bits.dlc)
871-
# The _message.dwTime is a 32bit tick value and will overrun,
872-
# so expect to see the value restarting from 0
873882
rx_msg = Message(
874-
timestamp=self._message.dwTime
875-
/ self._tick_resolution, # Relative time in s
883+
timestamp=(
884+
(self._message.dwTime + self._overrunticks - self._starttickoffset)
885+
/ self._tick_resolution
886+
)
887+
+ self._timeoffset,
876888
is_remote_frame=bool(self._message.uMsgInfo.Bits.rtr),
877889
is_fd=bool(self._message.uMsgInfo.Bits.edl),
878890
is_rx=True,

0 commit comments

Comments
 (0)