|
29 | 29 | __all__ = [
|
30 | 30 | "VCITimeout",
|
31 | 31 | "VCIError",
|
| 32 | + "VCIBusOffError", |
32 | 33 | "VCIDeviceNotFoundError",
|
33 | 34 | "IXXATBus",
|
34 | 35 | "vciFormatError",
|
@@ -354,6 +355,15 @@ def __check_status(result, function, arguments):
|
354 | 355 | constants.CAN_ERROR_CRC: "CAN CRC error",
|
355 | 356 | constants.CAN_ERROR_OTHER: "Other (unknown) CAN error",
|
356 | 357 | }
|
| 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 | +} |
357 | 367 | # ----------------------------------------------------------------------------
|
358 | 368 |
|
359 | 369 |
|
@@ -644,6 +654,13 @@ def _recv_internal(self, timeout):
|
644 | 654 | )
|
645 | 655 | )
|
646 | 656 |
|
| 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 | + |
647 | 664 | elif (
|
648 | 665 | self._message.uMsgInfo.Bits.type
|
649 | 666 | == constants.CAN_MSGTYPE_TIMEOVR
|
@@ -761,3 +778,25 @@ def stop(self):
|
761 | 778 | # the list with permanently stopped messages
|
762 | 779 | _canlib.canSchedulerRemMessage(self._scheduler, self._index)
|
763 | 780 | 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