Skip to content

Commit

Permalink
New BusState members per #736
Browse files Browse the repository at this point in the history
  • Loading branch information
bggardner committed Dec 1, 2024
1 parent 654a02a commit 6b6de04
Show file tree
Hide file tree
Showing 13 changed files with 36 additions and 33 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,4 @@ Felix Nieuwenhuizen
@SWolfSchunk
@belliriccardo
@cssedev
@bggardner
10 changes: 6 additions & 4 deletions can/bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@
class BusState(Enum):
"""The state in which a :class:`can.BusABC` can be."""

ACTIVE = auto()
PASSIVE = auto()
ERROR = auto()
ERROR_ACTIVE = auto()
ERROR_PASSIVE = auto()
BUS_OFF = auto()
STOPPED = auto()
UNKNOWN = auto()


class CanProtocol(Enum):
Expand Down Expand Up @@ -510,7 +512,7 @@ def state(self) -> BusState:
"""
Return the current state of the hardware
"""
return BusState.ACTIVE
return BusState.ERROR_ACTIVE

@state.setter
def state(self, new_state: BusState) -> None:
Expand Down
6 changes: 3 additions & 3 deletions can/interfaces/etas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,14 @@ def state(self) -> can.BusState:
status = OCI_CANControllerStatus()
OCI_GetCANControllerStatus(self.ctrl, ctypes.byref(status))
if status.stateCode & OCI_CAN_STATE_ACTIVE:
return can.BusState.ACTIVE
return can.BusState.ERROR_ACTIVE
elif status.stateCode & OCI_CAN_STATE_PASSIVE:
return can.BusState.PASSIVE
return can.BusState.ERROR_PASSIVE

@state.setter
def state(self, new_state: can.BusState) -> None:
# disabled, OCI_AdaptCANConfiguration does not allow changing the bus mode
# if new_state == can.BusState.ACTIVE:
# if new_state == can.BusState.ERROR_ACTIVE:
# self.ctrlConf.busParticipationMode = OCI_BUSMODE_ACTIVE
# else:
# self.ctrlConf.busParticipationMode = OCI_BUSMODE_PASSIVE
Expand Down
8 changes: 4 additions & 4 deletions can/interfaces/ixxat/canlib_vcinpl.py
Original file line number Diff line number Diff line change
Expand Up @@ -849,19 +849,19 @@ def state(self) -> BusState:
status = structures.CANLINESTATUS()
_canlib.canControlGetStatus(self._control_handle, ctypes.byref(status))
if status.bOpMode == constants.CAN_OPMODE_LISTONLY:
return BusState.PASSIVE
return BusState.ERROR_PASSIVE

error_byte_1 = status.dwStatus & 0x0F
# CAN_STATUS_BUSOFF = 0x08 # bus off status
if error_byte_1 & constants.CAN_STATUS_BUSOFF:
return BusState.ERROR
return BusState.BUS_OFF

error_byte_2 = status.dwStatus & 0xF0
# CAN_STATUS_BUSCERR = 0x20 # bus coupling error
if error_byte_2 & constants.CAN_STATUS_BUSCERR:
return BusState.ERROR
return BusState.STOPPED

return BusState.ACTIVE
return BusState.ERROR_ACTIVE


# ~class IXXATBus(BusABC): ---------------------------------------------------
Expand Down
8 changes: 4 additions & 4 deletions can/interfaces/pcan/pcan.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def __init__(
self,
channel: str = "PCAN_USBBUS1",
device_id: Optional[int] = None,
state: BusState = BusState.ACTIVE,
state: BusState = BusState.ERROR_ACTIVE,
timing: Optional[Union[BitTiming, BitTimingFd]] = None,
bitrate: int = 500000,
receive_own_messages: bool = False,
Expand Down Expand Up @@ -268,7 +268,7 @@ def __init__(

self.check_api_version()

if state in [BusState.ACTIVE, BusState.PASSIVE]:
if state in [BusState.ERROR_ACTIVE, BusState.ERROR_PASSIVE]:
self.state = state
else:
raise ValueError("BusState must be Active or Passive")
Expand Down Expand Up @@ -699,12 +699,12 @@ def state(self, new_state):
# declare here, which is called by __init__()
self._state = new_state # pylint: disable=attribute-defined-outside-init

if new_state is BusState.ACTIVE:
if new_state is BusState.ERROR_ACTIVE:
self.m_objPCANBasic.SetValue(
self.m_PcanHandle, PCAN_LISTEN_ONLY, PCAN_PARAMETER_OFF
)

elif new_state is BusState.PASSIVE:
elif new_state is BusState.ERROR_PASSIVE:
# When this mode is set, the CAN controller does not take part on active events (eg. transmit CAN messages)
# but stays in a passive mode (CAN monitor), in which it can analyse the traffic on the CAN bus used by a
# PCAN channel. See also the Philips Data Sheet "SJA1000 Stand-alone CAN controller".
Expand Down
12 changes: 6 additions & 6 deletions can/interfaces/systec/ucanbus.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ def __init__(self, channel, can_filters=None, **kwargs):
if bitrate not in self.BITRATES:
raise ValueError(f"Invalid bitrate {bitrate}")

state = kwargs.get("state", BusState.ACTIVE)
if state is BusState.ACTIVE or state is BusState.PASSIVE:
state = kwargs.get("state", BusState.ERROR_ACTIVE)
if state is BusState.ERROR_ACTIVE or state is BusState.ERROR_PASSIVE:
self._state = state
else:
raise ValueError("BusState must be Active or Passive")
Expand All @@ -130,7 +130,7 @@ def __init__(self, channel, can_filters=None, **kwargs):
self._params = {
"mode": Mode.MODE_NORMAL
| (Mode.MODE_TX_ECHO if kwargs.get("receive_own_messages") else 0)
| (Mode.MODE_LISTEN_ONLY if state is BusState.PASSIVE else 0),
| (Mode.MODE_LISTEN_ONLY if state is BusState.ERROR_PASSIVE else 0),
"BTR": self.BITRATES[bitrate],
}
# get extra parameters
Expand Down Expand Up @@ -306,14 +306,14 @@ def state(self):

@state.setter
def state(self, new_state):
if self._state is not BusState.ERROR and (
new_state is BusState.ACTIVE or new_state is BusState.PASSIVE
if self._state is not BusState.STOPPED and (
new_state is BusState.ERROR_ACTIVE or new_state is BusState.ERROR_PASSIVE
):
try:
# close the CAN channel
self._ucan.shutdown(self.channel, False)
# set mode
if new_state is BusState.ACTIVE:
if new_state is BusState.ERROR_ACTIVE:
self._params["mode"] &= ~Mode.MODE_LISTEN_ONLY
else:
self._params["mode"] |= Mode.MODE_LISTEN_ONLY
Expand Down
4 changes: 2 additions & 2 deletions can/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,9 @@ def main() -> None:
bus = _create_bus(results, **additional_config)

if results.active:
bus.state = BusState.ACTIVE
bus.state = BusState.ERROR_ACTIVE
elif results.passive:
bus.state = BusState.PASSIVE
bus.state = BusState.ERROR_PASSIVE

print(f"Connected to {bus.__class__.__name__}: {bus.channel_info}")
print(f"Can Logger (Started on {datetime.now()})")
Expand Down
4 changes: 2 additions & 2 deletions doc/interfaces/pcan.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Here is an example configuration file for using `PCAN-USB <https://www.peak-syst
[default]
interface = pcan
channel = PCAN_USBBUS1
state = can.bus.BusState.PASSIVE
state = can.bus.BusState.ERROR_PASSIVE
bitrate = 500000

``channel`` (default ``"PCAN_USBBUS1"``)
Expand All @@ -31,7 +31,7 @@ Here is an example configuration file for using `PCAN-USB <https://www.peak-syst

Where ``x`` should be replaced with the desired channel number starting at ``1``.

``state`` (default ``can.bus.BusState.ACTIVE``)
``state`` (default ``can.bus.BusState.ERROR_ACTIVE``)
BusState of the channel

``bitrate`` (default ``500000``)
Expand Down
2 changes: 1 addition & 1 deletion doc/interfaces/systec.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Optional parameters:
* ``device_number`` (default first device) The device number of the USB-CAN
* ``rx_buffer_entries`` (default 4096) The maximum number of entries in the receive buffer
* ``tx_buffer_entries`` (default 4096) The maximum number of entries in the transmit buffer
* ``state`` (default BusState.ACTIVE) BusState of the channel
* ``state`` (default BusState.ERROR_ACTIVE) BusState of the channel
* ``receive_own_messages`` (default False) If messages transmitted should also be received back


Expand Down
2 changes: 1 addition & 1 deletion examples/receive_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def receive_all():
with can.Bus() as bus:
# set to read-only, only supported on some interfaces
try:
bus.state = BusState.PASSIVE
bus.state = BusState.ERROR_PASSIVE
except NotImplementedError:
pass

Expand Down
4 changes: 2 additions & 2 deletions test/test_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def test_log_virtual_active(self):
can.logger.main()
self.assertSuccessfullCleanup()
self.mock_logger.assert_called_once()
self.assertEqual(self.mock_virtual_bus.state, can.BusState.ACTIVE)
self.assertEqual(self.mock_virtual_bus.state, can.BusState.ERROR_ACTIVE)

def test_log_virtual_passive(self):
self.mock_virtual_bus.recv = Mock(side_effect=[self.testmsg, KeyboardInterrupt])
Expand All @@ -80,7 +80,7 @@ def test_log_virtual_passive(self):
can.logger.main()
self.assertSuccessfullCleanup()
self.mock_logger.assert_called_once()
self.assertEqual(self.mock_virtual_bus.state, can.BusState.PASSIVE)
self.assertEqual(self.mock_virtual_bus.state, can.BusState.ERROR_PASSIVE)

def test_log_virtual_with_config(self):
self.mock_virtual_bus.recv = Mock(side_effect=[self.testmsg, KeyboardInterrupt])
Expand Down
6 changes: 3 additions & 3 deletions test/test_pcan.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,8 @@ def test_shutdown(self) -> None:

@parameterized.expand(
[
("active", BusState.ACTIVE, PCAN_PARAMETER_OFF),
("passive", BusState.PASSIVE, PCAN_PARAMETER_ON),
("active", BusState.ERROR_ACTIVE, PCAN_PARAMETER_OFF),
("passive", BusState.ERROR_PASSIVE, PCAN_PARAMETER_ON),
]
)
def test_state(self, name, bus_state: BusState, expected_parameter) -> None:
Expand All @@ -384,7 +384,7 @@ def test_state(self, name, bus_state: BusState, expected_parameter) -> None:
)

def test_state_constructor(self):
for state in [BusState.ACTIVE, BusState.PASSIVE]:
for state in [BusState.ERROR_ACTIVE, BusState.ERROR_PASSIVE]:
bus = can.Bus(interface="pcan", state=state)
assert bus.state == state

Expand Down
2 changes: 1 addition & 1 deletion test/test_systec.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ def test_receive_own_messages():
@staticmethod
def test_bus_passive_state():
ucan.UcanInitCanEx2.reset_mock()
bus = can.Bus(interface="systec", channel=0, state=can.BusState.PASSIVE)
bus = can.Bus(interface="systec", channel=0, state=can.BusState.ERROR_PASSIVE)
ucan.UcanInitCanEx2.assert_called_once_with(
bus._ucan._handle,
0,
Expand Down

0 comments on commit 6b6de04

Please sign in to comment.