def setBitrate(self, bitrate): print('Setting bitrate ' + str(bitrate)) setBitrateResult = self._dll.icsneoSetBitRate(self._neoObject, bitrate, self._icsNetId) if setBitrateResult != 1: raise CANInterface.Error('Setting bitrate failed') else: self._cfgdBitrate = bitrate
def transmitTo(self, data, ident): assert self._cfgdBitrate != None if self._dumpTraffic: print('TX ' + CANInterface.ID(ident).getString() + ' ' + CANInterface.getDataHexString(data)) frame = self._build_frame(data, ident) res = self._dll.icsneoTxMessages(self._neoObject, ctypes.byref(frame), self._icsNetId, 1) if res != 1: raise CANInterface.Error()
def receive(self, timeout): assert self._cfgdBitrate != None if self._slaveAddr.resId.raw == 0xFFFFFFFF: return [] packets = [] if timeout != 0: endTime = time.time() + timeout else: endTime = None while 1: if endTime != None: newTimeout = int((endTime - time.time()) * 1000) if newTimeout > 0: self._dll.icsneoWaitForRxMessagesWithTimeOut( self._neoObject, newTimeout) else: break else: endTime = 0 # allow one pass, then return on the next icsMsgs = (_ICSSpyMessage * 20000)() icsNMsgs = ctypes.c_int() icsNErrors = ctypes.c_int() res = self._dll.icsneoGetMessages(self._neoObject, icsMsgs, ctypes.byref(icsNMsgs), ctypes.byref(icsNErrors)) if res != 1: raise CANInterface.Error() for iMsg in range(icsNMsgs.value): if icsMsgs[iMsg].NetworkID == self._icsNetId: ident, data = self._decode_frame(icsMsgs[iMsg]) if len(data ) > 0 and ident == self._slaveAddr.resId.raw and ( data[0] == 0xFF or data[0] == 0xFE): if self._dumpTraffic: print('RX ' + self._slaveAddr.resId.getString() + ' ' + CANInterface.getDataHexString(data)) packets.append(data) if len(packets) != 0: break return packets
def __init__(self, parsedURL): self._slaveAddr = None self._port = None self._bitrate = None self._txAddrStd = False self._cfgdBitrate = None self._cfgdTxAddrStd = False self._baudDivisor = None self._baud87Mult = None self._hasSetCSM0 = False self._tcpTimeout = 1.0 self._serialTimeout = 0.2 self._dumpTraffic = False self._cfgdHeaderIdent = None self._filter = None self._cfgdFilter = None self._noCsmQuirk = False self._isSt = False self._io = None urlQueryDict = urllib.parse.parse_qs(parsedURL.query) debugLogfile = None if 'debuglog' in urlQueryDict: if urlQueryDict['debuglog'][0] == 'stdout': debugLogfile = sys.stdout else: debugLogfile = open(urlQueryDict['debuglog'][0], 'w') if len(parsedURL.netloc): # If netloc is present, we're using a TCP connection addr = parsedURL.netloc.split(':') if len(addr) == 1: addr.append(35000) # use default port elif len(addr) != 2: raise CANInterface.Error('Interface address invalid') s = socket.socket() s.create_connection(addr, 0) self._port = SocketAsPort(s) self._intfcTimeout = self._tcpTimeout else: if debugLogfile != None: port = LoggingPort(debugLogfile) else: port = serial.Serial() port.port = parsedURL.path port.open() foundBaud = False for baudRate in self._POSSIBLE_BAUDRATES: if DEBUG: print('Trying ' + str(baudRate)) port.baudrate = baudRate port.interCharTimeout = min(10 / baudRate, 0.0001) port.timeout = 0.05 # Try sending a CR, if we get a prompt then it's probably the right baudrate port.flushInput() port.write(b'\r') response = port.read(16384) if len(response) == 0 or response[-1:] != b'>': port.write(b'\r') response = port.read(16384) if len(response) == 0 or response[-1:] != b'>': continue # Turn off echo, this also serves as a test to make sure we didn't randomly get a > at the end of some gibberish port.flushInput() port.write(b'ATE0\r') response = port.read(16) if not b'OK' in response: continue # If we made contact at baudrate 500k, we're done if baudRate == 500000: foundBaud = True break # Not at 500k, try to change ELM to that port.timeout = 1.28 # Maximum possible timeout for ELM327 port.flushInput() port.write(b'ATBRD08\r') response = port.read(2) if response == b'?\r': # Device does not allow baudrate change, but we found its operating baudrate foundBaud = True break elif response == b'OK': # Device allows baudrate change, try to switch to 500k port.baudrate = 500000 port.flushInput() response = port.read(11) if response[0:6] != b'ELM327': # Baudrate switch unsuccessful, try to recover port.baudrate = baudRate port.write(b'\r') port.flushInput() response = port.read(1024) if len(response) == 0 or response[-1:] != b'>': raise UnexpectedResponse('switching baudrate') # Baudrate switched, send a CR to confirm we're on board port.flushInput() port.write(b'\r') response = port.read(2) if response != b'OK': raise UnexpectedResponse('switching baudrate') foundBaud = True if response == b'ELM327 v1.5': self._noCsmQuirk = True break if not foundBaud: raise SerialError('could not find baudrate') port.timeout = 0 self._port = port self._intfcTimeout = self._serialTimeout self._port.flushInput() # Start the I/O thread, which takes over control of the port self._io = ELM327IO(port) self._runCmdWithCheck(b'ATWS', checkOK=False, closeOnFail=True) # Software reset self._runCmdWithCheck(b'ATE0', closeOnFail=True) # Turn off echo self._runCmdWithCheck(b'ATL0', closeOnFail=True) # Turn off newlines self._runCmdWithCheck(b'ATS0', closeOnFail=True) # Turn off spaces self._runCmdWithCheck(b'ATH1', closeOnFail=True) # Turn on headers self._runCmdWithCheck(b'ATAL', closeOnFail=True) # Allow full length messages try: self._runCmdWithCheck( b'STFCP', closeOnFail=False) # See if this is an ST device self._isSt = True except UnexpectedResponse: pass self.setBitrate(CANInterface.URLBitrate(parsedURL)) self._slaveAddr = CANInterface.XCPSlaveCANAddr(0xFFFFFFFF, 0xFFFFFFFF)