예제 #1
0
class HondaECU(object):

	def __init__(self, device_id=None):
		super(HondaECU, self).__init__()
		self.device_id = device_id
		self.dev = None
		self.error = 0
		self.resets = 0
		self.reset()

	def reset(self):
		if self.dev != None:
			del self.dev
			self.dev = None
		self.dev = Device(self.device_id)

	def setup(self):
		self.dev.ftdi_fn.ftdi_usb_reset()
		self.dev.ftdi_fn.ftdi_usb_purge_buffers()
		self.dev.ftdi_fn.ftdi_set_line_property(8, 1, 0)
		self.dev.baudrate = 10400

	def _break(self, ms, debug=False):
		self.dev.ftdi_fn.ftdi_set_bitmode(1, 0x01)
		self.dev._write(b'\x00')
		time.sleep(ms)
		self.dev._write(b'\x01')
		self.dev.ftdi_fn.ftdi_set_bitmode(0, 0x00)
		self.dev.flush()

	def init(self, debug=False):
		ret = False
		self._break(.070)
		time.sleep(.130)
		self.dev.flush()
		info = self.send_command([0xfe],[0x72], debug=debug, retries=0) # 0xfe <- KWP2000 fast init all nodes ?
		if info != None and ord(info[0]) > 0:
			if ord(info[2]) == 0x72:
				ret = True
		return ret

	def kline(self):
		b = create_string_buffer(2)
		self.dev.ftdi_fn.ftdi_poll_modem_status(b)
		return b.raw[1] & 16 == 0

	def send(self, buf, ml, timeout=.5):
		self.dev.flush()
		msg = "".join([chr(b) for b in buf]).encode("latin1")
		self.dev._write(msg)
		r = len(msg)
		to = time.time()
		while r > 0:
			r -= len(self.dev._read(r))
			if time.time() - to > timeout: return None
		buf = bytearray()
		r = ml+1
		while r > 0:
			tmp = self.dev._read(r)
			r -= len(tmp)
			buf.extend(tmp)
			if time.time() - to > timeout: return None
		r = buf[-1]-ml-1
		while r > 0:
			tmp = self.dev._read(r)
			r -= len(tmp)
			buf.extend(tmp)
			if time.time() - to > timeout: return None
		return buf

	def send_command(self, mtype, data=[], retries=10, debug=False):
		msg, ml, dl = format_message(mtype, data)
		first = True
		while first or retries > 0:
			first = False
			if debug:
				sys.stderr.write("> [%s]" % ", ".join(["%02x" % m for m in msg]))
			resp = self.send(msg, ml)
			ret = None
			if resp == None:
				if debug:
					sys.stderr.write(" !%d \n" % (retries))
				retries -= 1
				time.sleep(0)
				continue
			else:
				if debug:
					sys.stderr.write("\n")
			if debug:
				sys.stderr.write("< [%s]" % ", ".join(["%02x" % r for r in resp]))
			invalid = (resp[-1] != checksum8bitHonda([r for r in resp[:-1]]))
			if invalid:
				if debug:
					sys.stderr.write(" !%d \n" % (retries))
				retries -= 1
				time.sleep(0)
				continue
			else:
				if debug:
					sys.stderr.write("\n")
			sys.stderr.flush()
			rmtype = resp[:ml]
			rml = resp[ml:(ml+1)]
			rdl = ord(rml) - 2 - len(rmtype)
			rdata = resp[(ml+1):-1]
			return (rmtype, rml, rdata, rdl)

	def do_init_recover(self, debug=False):
		self.send_command([0x7b], [0x00, 0x01, 0x03], debug=debug)
		self.send_command([0x7b], [0x00, 0x01, 0x01], debug=debug)
		self.send_command([0x7b], [0x00, 0x01, 0x02], debug=debug)
		self.send_command([0x7b], [0x00, 0x01, 0x03], debug=debug)
		self.send_command([0x7b], [0x00, 0x02, 0x76, 0x03, 0x17], debug=debug) # seed/key?
		self.send_command([0x7b], [0x00, 0x03, 0x75, 0x05, 0x13], debug=debug) # seed/key?

	def do_init_write(self, debug=False):
		# is this the command to erase the ECU?
		self.send_command([0x7d], [0x01, 0x01, 0x00], debug=debug)
		self.send_command([0x7d], [0x01, 0x01, 0x01], debug=debug)
		self.send_command([0x7d], [0x01, 0x01, 0x02], debug=debug)
		self.send_command([0x7d], [0x01, 0x01, 0x03], debug=debug)
		self.send_command([0x7d], [0x01, 0x02, 0x50, 0x47, 0x4d], debug=debug) # seed/key?
		self.send_command([0x7d], [0x01, 0x03, 0x2d, 0x46, 0x49], debug=debug) # seed/key?

	def do_pre_write(self, debug=False):
		self.send_command([0x7e], [0x01, 0x01, 0x00], debug=debug)
		time.sleep(11)
		self.send_command([0x7e], [0x01, 0x02], debug=debug)
		self.send_command([0x7e], [0x01, 0x03, 0x00, 0x00], debug=debug)
		self.send_command([0x7e], [0x01, 0x01, 0x00], debug=debug)
		self.send_command([0x7e], [0x01, 0x0b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff], debug=debug) # password?
		self.send_command([0x7e], [0x01, 0x01, 0x00], debug=debug)
		self.send_command([0x7e], [0x01, 0x0e, 0x01, 0x90], debug=debug)
		self.send_command([0x7e], [0x01, 0x01, 0x01], debug=debug)
		self.send_command([0x7e], [0x01, 0x04, 0xff], debug=debug)
		self.send_command([0x7e], [0x01, 0x01, 0x00], debug=debug)

	def do_pre_write_wait(self, debug=False):
		while True:
			info = self.send_command([0x7e], [0x01, 0x05], debug=debug)
			if info[2][1] == 0x00:
				break
		self.send_command([0x7e], [0x01, 0x01, 0x00], debug=debug)
예제 #2
0
파일: ecu.py 프로젝트: SancheZ911/HondaECU
class HondaECU(object):
    def __init__(self, device_id=None, latency=None, baudrate=10400):
        super(HondaECU, self).__init__()
        self.device_id = device_id
        self.dev = None
        self.error = 0
        self.resets = 0
        self.latency = latency
        self.baudrate = baudrate
        self.reset()

    def reset(self):
        if self.dev != None:
            del self.dev
            self.dev = None

        self.dev = Device(self.device_id,
                          auto_detach=(platform.system() != "Windows"))
        self.setup()

    def setup(self):
        self.dev.ftdi_fn.ftdi_usb_reset()
        self.dev.ftdi_fn.ftdi_usb_purge_buffers()
        self.dev.ftdi_fn.ftdi_set_line_property(8, 1, 0)
        self.dev.baudrate = self.baudrate
        if self.latency:
            self.dev.ftdi_fn.ftdi_set_latency_timer(self.latency)
        latency = c_ubyte()
        self.dev.ftdi_fn.ftdi_get_latency_timer(byref(latency))

    def _break(self, ms):
        self.dev.ftdi_fn.ftdi_set_bitmode(1, 0x01)
        self.dev._write(b'\x00')
        time.sleep(ms)
        self.dev._write(b'\x01')
        self.dev.ftdi_fn.ftdi_set_bitmode(0, 0x00)
        self.dev.flush()

    def wakeup(self):
        self._break(.070)
        time.sleep(.130)

    def ping(self):
        return self.send_command([0xfe], [0x72], retries=0) != None

    def probe_tables(self, tables=None):
        if not tables:
            tables = [
                0x10, 0x11, 0x17, 0x20, 0x21, 0x60, 0x61, 0x67, 0x70, 0x71,
                0xd0, 0xd1
            ]
        ret = {}
        for t in tables:
            info = self.send_command([0x72], [0x71, t])
            if info:
                if info[3] > 2:
                    ret[t] = [info[3], info[2]]
            else:
                return {}
        return ret

    def init(self):
        self.wakeup()
        return self.ping()

    def kline_new(self):
        pin_byte = c_ubyte()
        self.dev.ftdi_fn.ftdi_read_pins(byref(pin_byte))
        return (pin_byte.value == 0xff)

    def kline(self, timeout=.05):
        self.dev.flush()
        self.dev._write(b"\x00")
        to = time.time()
        while time.time() - to < timeout:
            tmp = self.dev._read(1)
            if len(tmp) == 1:
                return tmp == b"\x00"
        return False

    def kline_alt(self):
        self.dev.flush()
        self.dev._write(b"\xff")
        return self.dev._read(1) == b"\xff"

    def kline_old(self):
        b = create_string_buffer(2)
        self.dev.ftdi_fn.ftdi_poll_modem_status(b)
        return b.raw[1] & 16 == 0

    def send(self, buf, ml, timeout=.001):
        self.dev.flush()
        msg = "".join([chr(b) for b in buf]).encode("latin1")
        self.dev._write(msg)
        r = len(msg)
        timeout = .05 + timeout * r
        to = time.time()
        while r > 0:
            r -= len(self.dev._read(r))
            if time.time() - to > timeout: return None
        buf = bytearray()
        r = ml + 1
        while r > 0:
            tmp = self.dev._read(r)
            r -= len(tmp)
            buf.extend(tmp)
            if time.time() - to > timeout: return None
        r = buf[-1] - ml - 1
        while r > 0:
            tmp = self.dev._read(r)
            r -= len(tmp)
            buf.extend(tmp)
            if time.time() - to > timeout: return None
        return buf

    def send_command(self, mtype, data=[], retries=1):
        msg, ml, dl = format_message(mtype, data)
        r = 0
        while r <= retries:
            dispatcher.send(signal="ecu.debug",
                            sender=self,
                            msg="%d > [%s]" %
                            (r, ", ".join(["%02x" % m for m in msg])))
            resp = self.send(msg, ml)
            if resp:
                if checksum8bitHonda(resp[:-1]) == resp[-1]:
                    dispatcher.send(signal="ecu.debug",
                                    sender=self,
                                    msg="%d < [%s]" %
                                    (r, ", ".join(["%02x" % r for r in resp])))
                    rmtype = resp[:ml]
                    valid = False
                    if ml == 3:
                        valid = (rmtype[:2] == bytearray(
                            map(lambda x: x | 0x10, mtype[:2])))
                    elif ml == 1:
                        valid = (rmtype == bytearray(
                            map(lambda x: x & 0xf, mtype)))
                    if valid:
                        rml = resp[ml:(ml + 1)]
                        rdl = ord(rml) - 2 - len(rmtype)
                        rdata = resp[(ml + 1):-1]
                        return (rmtype, rml, rdata, rdl)
                    else:
                        return None
            r += 1

    def detect_ecu_state_new(self):
        t0 = self.send_command([0x72], [0x71, 0x00], retries=0)
        if t0 is None:
            self.wakeup()
            self.ping()
            t0 = self.send_command([0x72], [0x71, 0x00], retries=0)
        if not t0 is None:
            if bytes(t0[2][5:7]) != b"\x00\x00":
                return ECUSTATE.OK
            else:
                if self.send_command([0x7d], [0x01, 0x01, 0x00], retries=0):
                    return ECUSTATE.RECOVER_OLD
                if self.send_command([0x7b], [0x00, 0x01, 0x01], retries=0):
                    return ECUSTATE.RECOVER_NEW
        else:
            writestatus = self.send_command([0x7e], [0x01, 0x01, 0x00],
                                            retries=0)
            if not writestatus is None:
                if writestatus[2][1] == 0x0f:
                    return ECUSTATE.WRITE_GOOD
                elif writestatus[2][1] == 0x10:
                    return ECUSTATE.WRITE_INIT_OLD
                elif writestatus[2][1] == 0x20:
                    return ECUSTATE.WRITE_INIT_NEW
                elif writestatus[2][1] == 0x30:
                    return ECUSTATE.ERASE
                elif writestatus[2][1] == 0x40:
                    return ECUSTATE.WRITE
                elif writestatus[2][1] == 0x0:
                    return ECUSTATE.WRITE_UNKNOWN1
                else:
                    return ECUSTATE.ERROR
            else:
                readinfo = self.send_command([0x82, 0x82, 0x00],
                                             [0x00, 0x00, 0x00, 0x08],
                                             retries=0)
                if not readinfo is None:
                    return ECUSTATE.READ
        return ECUSTATE.OFF if not self.kline() else ECUSTATE.UNKNOWN

    def do_init_recover(self):
        self.send_command([0x7b], [0x00, 0x01, 0x01])
        self.send_command([0x7b], [0x00, 0x01, 0x02])
        self.send_command([0x7b], [0x00, 0x01, 0x03])
        self.send_command([0x7b], [0x00, 0x02, 0x76, 0x03, 0x17])
        self.send_command([0x7b], [0x00, 0x03, 0x75, 0x05, 0x13])

    def do_init_write(self):
        self.send_command([0x7d], [0x01, 0x01, 0x01])
        self.send_command([0x7d], [0x01, 0x01, 0x02])
        self.send_command([0x7d], [0x01, 0x01, 0x03])
        self.send_command([0x7d], [0x01, 0x02, 0x50, 0x47, 0x4d])
        self.send_command([0x7d], [0x01, 0x03, 0x2d, 0x46, 0x49])

    def do_erase(self):
        self.send_command([0x7e], [0x01, 0x02])
        self.send_command([0x7e], [0x01, 0x03, 0x00, 0x00])
        self.send_command([0x7e],
                          [0x01, 0x0b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff])
        self.send_command([0x7e], [0x01, 0x0e, 0x01, 0x90])
        self.send_command([0x7e], [0x01, 0x01, 0x01])
        self.send_command([0x7e], [0x01, 0x04, 0xff])

    def do_erase_wait(self):
        cont = 1
        while cont:
            info = self.send_command([0x7e], [0x01, 0x05])
            if info:
                if info[2][1] == 0x00:
                    cont = 0
            else:
                cont = -1
        if cont == 0:
            into = self.send_command([0x7e], [0x01, 0x01, 0x00])

    def do_post_write(self):
        self.send_command([0x7e], [0x01, 0x09])
        time.sleep(.5)
        self.send_command([0x7e], [0x01, 0x0a])
        time.sleep(.5)
        self.send_command([0x7e], [0x01, 0x0c])
        time.sleep(.5)
        info = self.send_command([0x7e], [0x01, 0x0d])
        if info: return (info[2][1] == 0x0f)

    def get_faults(self):
        faults = {'past': [], 'current': []}
        for i in range(1, 0x0c):
            info_current = self.send_command([0x72], [0x74, i])[2]
            for j in [3, 5, 7]:
                if info_current[j] != 0:
                    faults['current'].append(
                        "%02d-%02d" % (info_current[j], info_current[j + 1]))
            if info_current[2] == 0:
                break
        for i in range(1, 0x0c):
            info_past = self.send_command([0x72], [0x73, i])[2]
            for j in [3, 5, 7]:
                if info_past[j] != 0:
                    faults['past'].append("%02d-%02d" %
                                          (info_past[j], info_past[j + 1]))
            if info_past[2] == 0:
                break
        return faults
예제 #3
0
파일: ecu.py 프로젝트: macsboost/HondaECU
class HondaECU(object):
    def __init__(self,
                 device_id=None,
                 dprint=None,
                 latency=None,
                 baudrate=10400):
        super(HondaECU, self).__init__()
        self.device_id = device_id
        self.dev = None
        self.error = 0
        self.resets = 0
        self.latency = latency
        self.baudrate = baudrate
        if not dprint:
            self.dprint = self.__dprint
        else:
            self.dprint = dprint
        self.reset()

    def __dprint(self, msg):
        sys.stderr.write(msg)
        sys.stderr.write("\n")
        sys.stderr.flush()

    def reset(self):
        if self.dev != None:
            del self.dev
            self.dev = None

        self.dev = Device(self.device_id,
                          auto_detach=(platform.system() != "Windows"))
        self.setup()
        self.starttime = time.time()

    def time(self):
        return time.time() - self.starttime

    def setup(self):
        self.dev.ftdi_fn.ftdi_usb_reset()
        self.dev.ftdi_fn.ftdi_usb_purge_buffers()
        self.dev.ftdi_fn.ftdi_set_line_property(8, 1, 0)
        self.dev.baudrate = self.baudrate
        if self.latency:
            self.dev.ftdi_fn.ftdi_set_latency_timer(self.latency)
        latency = c_ubyte()
        self.dev.ftdi_fn.ftdi_get_latency_timer(byref(latency))

    def _break(self, ms, debug=False):
        self.dev.ftdi_fn.ftdi_set_bitmode(1, 0x01)
        self.dev._write(b'\x00')
        time.sleep(ms)
        self.dev._write(b'\x01')
        self.dev.ftdi_fn.ftdi_set_bitmode(0, 0x00)
        self.dev.flush()

    def wakeup(self):
        self._break(.070)
        time.sleep(.130)

    def ping(self, debug=False):
        return self.send_command([0xfe], [0x72]) != None

    def probe_tables(self, tables=None):
        if not tables:
            tables = [
                0x10, 0x11, 0x17, 0x20, 0x21, 0x60, 0x61, 0x67, 0x70, 0x71,
                0xd0, 0xd1
            ]
        ret = {}
        for t in tables:
            info = self.send_command([0x72], [0x71, t])
            if info:
                if info[3] > 2:
                    ret[t] = [info[3], info[2]]
            else:
                return {}
        return ret

    def init(self, debug=False):
        self.wakeup()
        return self.ping(debug)

    def kline_new(self):
        pin_byte = c_ubyte()
        self.dev.ftdi_fn.ftdi_read_pins(byref(pin_byte))
        return (pin_byte.value == 0xff)

    def kline(self, timeout=.05):
        self.dev.flush()
        self.dev._write(b"\x00")
        to = time.time()
        while time.time() - to < timeout:
            tmp = self.dev._read(1)
            if len(tmp) == 1:
                return tmp == b"\x00"
        return False

    def kline_alt(self):
        self.dev.flush()
        self.dev._write(b"\xff")
        return self.dev._read(1) == b"\xff"

    def kline_old(self):
        b = create_string_buffer(2)
        self.dev.ftdi_fn.ftdi_poll_modem_status(b)
        return b.raw[1] & 16 == 0

    def send(self, buf, ml, timeout=.001):
        self.dev.flush()
        msg = "".join([chr(b) for b in buf]).encode("latin1")
        self.dev._write(msg)
        r = len(msg)
        timeout = .05 + timeout * r
        to = time.time()
        while r > 0:
            r -= len(self.dev._read(r))
            if time.time() - to > timeout: return None
        buf = bytearray()
        r = ml + 1
        while r > 0:
            tmp = self.dev._read(r)
            r -= len(tmp)
            buf.extend(tmp)
            if time.time() - to > timeout: return None
        r = buf[-1] - ml - 1
        while r > 0:
            tmp = self.dev._read(r)
            r -= len(tmp)
            buf.extend(tmp)
            if time.time() - to > timeout: return None
        return buf

    def send_command(self, mtype, data=[], debug=False, retries=1):
        msg, ml, dl = format_message(mtype, data)
        r = 0
        while r <= retries:
            self.dprint("%d > [%s]" % (r, ", ".join(["%02x" % m
                                                     for m in msg])))
            resp = self.send(msg, ml)
            if resp:
                if checksum8bitHonda(resp[:-1]) == resp[-1]:
                    self.dprint("%d < [%s]" %
                                (r, ", ".join(["%02x" % r for r in resp])))
                    rmtype = resp[:ml]
                    valid = False
                    if ml == 3:
                        valid = (rmtype[:2] == bytearray(
                            map(lambda x: x | 0x10, mtype[:2])))
                    elif ml == 1:
                        valid = (rmtype == bytearray(
                            map(lambda x: x & 0xf, mtype)))
                    if valid:
                        rml = resp[ml:(ml + 1)]
                        rdl = ord(rml) - 2 - len(rmtype)
                        rdata = resp[(ml + 1):-1]
                        return (rmtype, rml, rdata, rdl)
                    else:
                        print("shit")
            r += 1

    def detect_ecu_state(self, wakeup=False):
        states = [
            "unknown",  # 0
            "ok",  # 1
            "recover",  # 2
            "recover (old)",  # 3
            "init",  # 4
            "unlock",  # 5
            "erase",  # 6
            "write",  # 7
            "finalize",  # 8
            "incomplete",  # 9
            "reset",  # 10
            "error",  # 11
            "read",  # 12
            "off",  # 13
        ]
        state = 0
        if wakeup:
            self.wakeup()
        if self.ping():
            rinfo = self.send_command([0x7b], [0x00, 0x01, 0x01])
            winfo = self.send_command([0x7d], [0x01, 0x01, 0x01])
            if winfo:
                state = 1
            else:
                state = 2
        else:
            einfo = self.send_command([0x7e], [0x01, 0x01, 0x00])
            if einfo:
                if einfo[2][1] == 0x00:
                    state = 3
                elif einfo[2][1] == 0x10:
                    state = 4
                elif einfo[2][1] == 0x20:
                    state = 5
                elif einfo[2][1] == 0x30:
                    state = 6
                elif einfo[2][1] == 0x40:
                    state = 7
                elif einfo[2][1] == 0x50:
                    state = 8
                elif einfo[2][1] == 0x0d:
                    state = 9
                elif einfo[2][1] == 0x0f:
                    state = 10
                elif einfo[2][1] == 0xfa:
                    state = 11
                else:
                    print(hex(einfo[2][1]))
            else:
                dinfo = self.send_command([0x82, 0x82, 0x00],
                                          [0x00, 0x00, 0x00, 0x08])
                if dinfo:
                    state = 12
        if state == 0:
            if not wakeup:
                state, _ = self.detect_ecu_state(wakeup=True)
            elif not self.kline():
                state = 13
        return state, states[state]

    def do_init_recover(self, debug=False):
        self.send_command([0x7b], [0x00, 0x01, 0x01])
        self.send_command([0x7b], [0x00, 0x01, 0x02])
        self.send_command([0x7b], [0x00, 0x01, 0x03])
        self.send_command([0x7b], [0x00, 0x02, 0x76, 0x03, 0x17])
        self.send_command([0x7b], [0x00, 0x03, 0x75, 0x05, 0x13])

    def do_init_write(self, debug=False):
        self.send_command([0x7d], [0x01, 0x01, 0x01])
        self.send_command([0x7d], [0x01, 0x01, 0x02])
        self.send_command([0x7d], [0x01, 0x01, 0x03])
        self.send_command([0x7d], [0x01, 0x02, 0x50, 0x47, 0x4d])
        self.send_command([0x7d], [0x01, 0x03, 0x2d, 0x46, 0x49])

    def do_erase(self, debug=False):
        self.send_command([0x7e], [0x01, 0x02])
        self.send_command([0x7e], [0x01, 0x03, 0x00, 0x00])
        self.send_command([0x7e],
                          [0x01, 0x0b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff])
        self.send_command([0x7e], [0x01, 0x0e, 0x01, 0x90])
        self.send_command([0x7e], [0x01, 0x01, 0x01])
        self.send_command([0x7e], [0x01, 0x04, 0xff])

    def do_erase_wait(self, debug=False):
        cont = 1
        while cont:
            info = self.send_command([0x7e], [0x01, 0x05])
            if info:
                if info[2][1] == 0x00:
                    cont = 0
            else:
                cont = -1
        if cont == 0:
            into = self.send_command([0x7e], [0x01, 0x01, 0x00])

    def do_post_write(self, debug=False):
        self.send_command([0x7e], [0x01, 0x09])
        time.sleep(.5)
        self.send_command([0x7e], [0x01, 0x0a])
        time.sleep(.5)
        self.send_command([0x7e], [0x01, 0x0c])
        time.sleep(.5)
        info = self.send_command([0x7e], [0x01, 0x0d])
        if info: return (info[2][1] == 0x0f)

    def get_faults(self, debug=False):
        faults = {'past': [], 'current': []}
        for i in range(1, 0x0c):
            info_current = self.send_command([0x72], [0x74, i])[2]
            for j in [3, 5, 7]:
                if info_current[j] != 0:
                    faults['current'].append(
                        "%02d-%02d" % (info_current[j], info_current[j + 1]))
            if info_current[2] == 0:
                break
        for i in range(1, 0x0c):
            info_past = self.send_command([0x72], [0x73, i])[2]
            for j in [3, 5, 7]:
                if info_past[j] != 0:
                    faults['past'].append("%02d-%02d" %
                                          (info_past[j], info_past[j + 1]))
            if info_past[2] == 0:
                break
        return faults

    def do_read_flash(self, binfile):
        readsize = 12
        location = 0
        nl = False
        with open(binfile, "wb") as fbin:
            while True:
                info = self.send_command([0x82, 0x82, 0x00],
                                         format_read(location) + [readsize])
                if not info:
                    readsize -= 1
                    if readsize < 1:
                        break
                else:
                    fbin.write(info[2])
                    fbin.flush()
                    location += readsize
        with open(binfile, "rb") as fbin:
            nbyts = os.path.getsize(binfile)
            byts = bytearray(fbin.read(nbyts))
            _, status = do_validation(byts)
            return status == "good"

    def do_write_flash(self, byts, offset=0):
        print("write start")
        writesize = 128
        maxi = len(byts) / 128
        i = 0
        while i < maxi:
            w = (i * writesize)
            bytstart = [s for s in struct.pack(">H", offset + (8 * i))]
            if i + 1 == maxi:
                bytend = [s for s in struct.pack(">H", offset)]
            else:
                bytend = [s for s in struct.pack(">H", offset + (8 * (i + 1)))]
            d = list(byts[((i + 0) * 128):((i + 1) * 128)])
            x = bytstart + d + bytend
            c1 = checksum8bit(x)
            c2 = checksum8bitHonda(x)
            x = [0x01, 0x06] + x + [c1, c2]
            info = self.send_command([0x7e], x)
            if not info or ord(info[1]) != 5:
                return False
            i += 1
            if i % 2 == 0:
                self.send_command([0x7e], [0x01, 0x08])
        return True