2929__all__ = [
3030 "VCITimeout" ,
3131 "VCIError" ,
32+ "VCIBusOffError" ,
3233 "VCIDeviceNotFoundError" ,
3334 "IXXATBus" ,
3435 "vciFormatError" ,
@@ -354,6 +355,15 @@ def __check_status(result, function, arguments):
354355 constants .CAN_ERROR_CRC : "CAN CRC error" ,
355356 constants .CAN_ERROR_OTHER : "Other (unknown) CAN error" ,
356357}
358+
359+ CAN_STATUS_FLAGS = {
360+ constants .CAN_STATUS_TXPEND : "transmission pending" ,
361+ constants .CAN_STATUS_OVRRUN : "data overrun occurred" ,
362+ constants .CAN_STATUS_ERRLIM : "error warning limit exceeded" ,
363+ constants .CAN_STATUS_BUSOFF : "bus off" ,
364+ constants .CAN_STATUS_ININIT : "init mode active" ,
365+ constants .CAN_STATUS_BUSCERR : "bus coupling error" ,
366+ }
357367# ----------------------------------------------------------------------------
358368
359369
@@ -378,6 +388,10 @@ class IXXATBus(BusABC):
378388 125000 : constants .CAN_BT0_125KB ,
379389 250000 : constants .CAN_BT0_250KB ,
380390 500000 : constants .CAN_BT0_500KB ,
391+ 666000 : constants .CAN_BT0_667KB ,
392+ 666666 : constants .CAN_BT0_667KB ,
393+ 666667 : constants .CAN_BT0_667KB ,
394+ 667000 : constants .CAN_BT0_667KB ,
381395 800000 : constants .CAN_BT0_800KB ,
382396 1000000 : constants .CAN_BT0_1000KB ,
383397 },
@@ -389,6 +403,10 @@ class IXXATBus(BusABC):
389403 125000 : constants .CAN_BT1_125KB ,
390404 250000 : constants .CAN_BT1_250KB ,
391405 500000 : constants .CAN_BT1_500KB ,
406+ 666000 : constants .CAN_BT1_667KB ,
407+ 666666 : constants .CAN_BT1_667KB ,
408+ 666667 : constants .CAN_BT1_667KB ,
409+ 667000 : constants .CAN_BT1_667KB ,
392410 800000 : constants .CAN_BT1_800KB ,
393411 1000000 : constants .CAN_BT1_1000KB ,
394412 },
@@ -636,6 +654,13 @@ def _recv_internal(self, timeout):
636654 )
637655 )
638656
657+ elif (
658+ self ._message .uMsgInfo .Bits .type == constants .CAN_MSGTYPE_STATUS
659+ ):
660+ log .info (_format_can_status (self ._message .abData [0 ]))
661+ if self ._message .abData [0 ] & constants .CAN_STATUS_BUSOFF :
662+ raise VCIBusOffError ()
663+
639664 elif (
640665 self ._message .uMsgInfo .Bits .type
641666 == constants .CAN_MSGTYPE_TIMEOVR
@@ -753,3 +778,25 @@ def stop(self):
753778 # the list with permanently stopped messages
754779 _canlib .canSchedulerRemMessage (self ._scheduler , self ._index )
755780 self ._index = None
781+
782+
783+ def _format_can_status (status_flags : int ):
784+ """
785+ Format a status bitfield found in CAN_MSGTYPE_STATUS messages or in dwStatus
786+ field in CANLINESTATUS.
787+
788+ Valid states are defined in the CAN_STATUS_* constants in cantype.h
789+ """
790+ states = []
791+ for flag , description in CAN_STATUS_FLAGS .items ():
792+ if status_flags & flag :
793+ states .append (description )
794+ status_flags &= ~ flag
795+
796+ if status_flags :
797+ states .append ("unknown state 0x{:02x}" .format (status_flags ))
798+
799+ if states :
800+ return "CAN status message: {}" .format (", " .join (states ))
801+ else :
802+ return "Empty CAN status message"
0 commit comments