|
28 | 28 | from . import constants, structures |
29 | 29 | from .exceptions import * |
30 | 30 |
|
31 | | -__all__ = ["VCITimeout", "VCIError", "VCIDeviceNotFoundError", "IXXATBus", "vciFormatError"] |
| 31 | +__all__ = [ |
| 32 | + "VCITimeout", |
| 33 | + "VCIError", |
| 34 | + "VCIBusOffError", |
| 35 | + "VCIDeviceNotFoundError", |
| 36 | + "IXXATBus", |
| 37 | + "vciFormatError", |
| 38 | +] |
32 | 39 |
|
33 | 40 | log = logging.getLogger('can.ixxat') |
34 | 41 |
|
@@ -232,6 +239,15 @@ def __check_status(result, function, arguments): |
232 | 239 | constants.CAN_ERROR_CRC: "CAN CRC error", |
233 | 240 | constants.CAN_ERROR_OTHER: "Other (unknown) CAN error", |
234 | 241 | } |
| 242 | + |
| 243 | +CAN_STATUS_FLAGS = { |
| 244 | + constants.CAN_STATUS_TXPEND: "transmission pending", |
| 245 | + constants.CAN_STATUS_OVRRUN: "data overrun occurred", |
| 246 | + constants.CAN_STATUS_ERRLIM: "error warning limit exceeded", |
| 247 | + constants.CAN_STATUS_BUSOFF: "bus off", |
| 248 | + constants.CAN_STATUS_ININIT: "init mode active", |
| 249 | + constants.CAN_STATUS_BUSCERR: "bus coupling error", |
| 250 | +} |
235 | 251 | #---------------------------------------------------------------------------- |
236 | 252 |
|
237 | 253 |
|
@@ -455,6 +471,11 @@ def _recv_internal(self, timeout): |
455 | 471 |
|
456 | 472 | elif self._message.uMsgInfo.Bits.type == constants.CAN_MSGTYPE_TIMEOVR: |
457 | 473 | pass |
| 474 | + |
| 475 | + elif self._message.uMsgInfo.Bits.type == constants.CAN_MSGTYPE_STATUS: |
| 476 | + log.info(_format_can_status(self._message.abData[0])) |
| 477 | + if self._message.abData[0] & constants.CAN_STATUS_BUSOFF: |
| 478 | + raise VCIBusOffError() |
458 | 479 | else: |
459 | 480 | log.warn("Unexpected message info type") |
460 | 481 |
|
@@ -575,3 +596,25 @@ def stop(self): |
575 | 596 | # the list with permanently stopped messages |
576 | 597 | _canlib.canSchedulerRemMessage(self._scheduler, self._index) |
577 | 598 | self._index = None |
| 599 | + |
| 600 | + |
| 601 | +def _format_can_status(status_flags: int): |
| 602 | + """ |
| 603 | + Format a status bitfield found in CAN_MSGTYPE_STATUS messages or in dwStatus |
| 604 | + field in CANLINESTATUS. |
| 605 | +
|
| 606 | + Valid states are defined in the CAN_STATUS_* constants in cantype.h |
| 607 | + """ |
| 608 | + states = [] |
| 609 | + for flag, description in CAN_STATUS_FLAGS.items(): |
| 610 | + if status_flags & flag: |
| 611 | + states.append(description) |
| 612 | + status_flags &= ~flag |
| 613 | + |
| 614 | + if status_flags: |
| 615 | + states.append("unknown state 0x{:02x}".format(status_flags)) |
| 616 | + |
| 617 | + if states: |
| 618 | + return "CAN status message: {}".format(", ".join(states)) |
| 619 | + else: |
| 620 | + return "Empty CAN status message" |
0 commit comments