|
19 | 19 | except: |
20 | 20 | boottimeEpoch = 0 |
21 | 21 |
|
| 22 | +try: |
| 23 | + import win32event |
| 24 | +except ImportError: |
| 25 | + win32event = None |
| 26 | + |
22 | 27 | if sys.version_info >= (3, 3): |
23 | 28 | # new in 3.3 |
24 | 29 | timeout_clock = time.perf_counter |
|
27 | 32 | timeout_clock = time.clock |
28 | 33 |
|
29 | 34 | # Set up logging |
30 | | -logging.basicConfig(level=logging.WARNING) |
31 | 35 | log = logging.getLogger('can.pcan') |
32 | 36 |
|
33 | 37 |
|
@@ -83,6 +87,13 @@ def __init__(self, channel, *args, **kwargs): |
83 | 87 | if result != PCAN_ERROR_OK: |
84 | 88 | raise PcanError(self._get_formatted_error(result)) |
85 | 89 |
|
| 90 | + if win32event is not None: |
| 91 | + self._recv_event = win32event.CreateEvent(None, 0, 0, None) |
| 92 | + result = self.m_objPCANBasic.SetValue( |
| 93 | + self.m_PcanHandle, PCAN_RECEIVE_EVENT, self._recv_event) |
| 94 | + if result != PCAN_ERROR_OK: |
| 95 | + raise PcanError(self._get_formatted_error(result)) |
| 96 | + |
86 | 97 | super(PcanBus, self).__init__(*args, **kwargs) |
87 | 98 |
|
88 | 99 | def _get_formatted_error(self, error): |
@@ -142,24 +153,35 @@ def reset(self): |
142 | 153 | return status == PCAN_ERROR_OK |
143 | 154 |
|
144 | 155 | def recv(self, timeout=None): |
145 | | - start_time = timeout_clock() |
146 | | - |
147 | | - if timeout is None: |
148 | | - timeout = 0 |
149 | | - |
150 | | - rx_msg = Message() |
| 156 | + if win32event is not None: |
| 157 | + # We will utilize events for the timeout handling |
| 158 | + timeout_ms = int(timeout * 1000) if timeout is not None else win32event.INFINITE |
| 159 | + elif timeout is not None: |
| 160 | + # Calculate max time |
| 161 | + end_time = timeout_clock() + timeout |
| 162 | + else: |
| 163 | + # Skip timeout handling |
| 164 | + end_time = 0 |
151 | 165 |
|
152 | 166 | log.debug("Trying to read a msg") |
153 | 167 |
|
154 | 168 | result = None |
155 | 169 | while result is None: |
156 | 170 | result = self.m_objPCANBasic.Read(self.m_PcanHandle) |
157 | | - if result[0] == PCAN_ERROR_QRCVEMPTY or result[0] == PCAN_ERROR_BUSLIGHT or result[0] == PCAN_ERROR_BUSHEAVY: |
158 | | - if timeout_clock() - start_time >= timeout: |
| 171 | + if result[0] == PCAN_ERROR_QRCVEMPTY: |
| 172 | + if win32event is not None: |
| 173 | + result = None |
| 174 | + val = win32event.WaitForSingleObject(self._recv_event, timeout_ms) |
| 175 | + if val != win32event.WAIT_OBJECT_0: |
| 176 | + return None |
| 177 | + elif timeout_clock() >= end_time: |
159 | 178 | return None |
160 | 179 | else: |
161 | 180 | result = None |
162 | 181 | time.sleep(0.001) |
| 182 | + elif result[0] & (PCAN_ERROR_BUSLIGHT | PCAN_ERROR_BUSHEAVY): |
| 183 | + log.warning(self._get_formatted_error(result[0])) |
| 184 | + return None |
163 | 185 | elif result[0] != PCAN_ERROR_OK: |
164 | 186 | raise PcanError(self._get_formatted_error(result[0])) |
165 | 187 |
|
|
0 commit comments