diff --git a/can/interfaces/pcan/pcan.py b/can/interfaces/pcan/pcan.py index 2fea74e77..e5b877762 100644 --- a/can/interfaces/pcan/pcan.py +++ b/can/interfaces/pcan/pcan.py @@ -56,6 +56,7 @@ PCAN_CHANNEL_FEATURES, FEATURE_FD_CAPABLE, PCAN_DICT_STATUS, + PCAN_BUSOFF_AUTORESET, ) @@ -206,6 +207,10 @@ def __init__( In the range (1..16). Ignored if not using CAN-FD. + :param bool auto_reset: + Enable automatic recovery in bus off scenario. + Resetting the driver takes ~500ms during which + it will not be responsive. """ self.m_objPCANBasic = PCANBasic() @@ -276,6 +281,14 @@ def __init__( "Ignoring error. PCAN_ALLOW_ERROR_FRAMES is still unsupported by OSX Library PCANUSB v0.10" ) + if kwargs.get("auto_reset", False): + result = self.m_objPCANBasic.SetValue( + self.m_PcanHandle, PCAN_BUSOFF_AUTORESET, PCAN_PARAMETER_ON + ) + + if result != PCAN_ERROR_OK: + raise PcanCanInitializationError(self._get_formatted_error(result)) + if HAS_EVENTS: self._recv_event = CreateEvent(None, 0, 0, None) result = self.m_objPCANBasic.SetValue( diff --git a/test/test_pcan.py b/test/test_pcan.py index eba42d7e1..0a680fea0 100644 --- a/test/test_pcan.py +++ b/test/test_pcan.py @@ -363,6 +363,16 @@ def get_value_side_effect(handle, param): self.bus = can.Bus(bustype="pcan", device_id=dev_id) self.assertEqual(expected_result, self.bus.channel_info) + def test_bus_creation_auto_reset(self): + self.bus = can.Bus(bustype="pcan", auto_reset=True) + self.assertIsInstance(self.bus, PcanBus) + self.MockPCANBasic.assert_called_once() + + def test_auto_reset_init_fault(self): + self.mock_pcan.SetValue = Mock(return_value=PCAN_ERROR_INITIALIZE) + with self.assertRaises(CanInitializationError): + self.bus = can.Bus(bustype="pcan", auto_reset=True) + if __name__ == "__main__": unittest.main()