def update_mbfw(cls): cls.reset_mainboard() sleep(1.0) storage = Storage("update_fw") tty = cls.get_mainboard_port() if not storage.exists("mainboard.bin"): raise RuntimeWarning("mainboard.bin not found") if os.system("stty -F %s 1200" % tty) != 0: raise RuntimeWarning("stty exec failed") sleep(2.0) fw_path = storage.get_path("mainboard.bin") if os.system("bossac -p %s -e -w -v -b %s" % (tty.split("/")[-1], fw_path)) != 0: raise RuntimeWarning("bossac exec failed") os.rename(fw_path, fw_path + ".updated") os.system("sync") sleep(0.75) cls.reset_mainboard() sleep(0.75)
def update_hbfw(self, stage_cb=lambda m: None): raspi_uart = Serial(port="/dev/ttyAMA0", baudrate=115200, stopbits=1, xonxoff=0, rtscts=0, timeout=0) def wait_ack(stage): t = time() while time() - t < 5.0: rl = select((raspi_uart, ), (), (), 5.0)[0] if rl: ret = raspi_uart.read(1) if ret == 'y': return elif ret == '\x1f': raise RuntimeError(SUBSYSTEM_ERROR, "HEAD RETURN 0x1f") else: raise RuntimeError(UNKNOWN_ERROR, "HEAD RETURN %s" % repr(ret)) raise RuntimeError(NO_RESPONSE, stage) def send_cmd(cmd, stage): raspi_uart.write(chr(cmd)) raspi_uart.write(chr(cmd ^ 0xFF)) wait_ack(stage) sleep(0.1) def crc8(msg, init=0): crc = init for c in msg: crc = crc ^ ord(c) return chr(crc) def bootloader_hello(): raspi_uart.write('\x7f') wait_ack("HELLO") logger.debug("Update head fw") storage = Storage("update_fw") if not storage.exists("head.bin"): raise RuntimeError(NOT_FOUND) with storage.open("head.bin", "rb") as f: fw = f.read() size = len(fw) pages = size // 2048 if size % 2048 > 0: pages += 1 logger.debug("Fw size=%i, use page=%i", size, pages) try: # Bootstrap stage_cb(b"B") raspi_uart.parity = PARITY_EVEN GPIO.output(self.TOOLHEAD_POWER, self.TOOLHEAD_POWER_OFF) GPIO.output(self.TOOLHEAD_BOOT, GPIO.HIGH) sleep(0.5) GPIO.output(self.TOOLHEAD_POWER, self.TOOLHEAD_POWER_ON) sleep(0.5) raspi_uart.setRTS(0) raspi_uart.setDTR(0) sleep(0.1) raspi_uart.setDTR(1) sleep(0.5) # Hello stage_cb(b"H") try: bootloader_hello() except Exception: sleep(0.5) bootloader_hello() send_cmd(0x00, "G_VR") l = ord(raspi_uart.read()) version = raspi_uart.read(1) a = raspi_uart.read(l) logger.debug("VER %s", repr(a)) wait_ack("G_VRL") logger.debug("Update head: bootloader ver=%s", version) if version != '1': raise RuntimeError(NOT_SUPPORT) # Earse stage_cb(b"E") send_cmd(0x44, "G_ERASE") cmd = struct.pack(">H", pages - 1) cmd += "".join([struct.pack(">H", i) for i in xrange(pages)]) raspi_uart.write(cmd) raspi_uart.write(crc8(cmd)) wait_ack("G_E") # Write stage_cb(b"W") offset = 0 while offset < size: stage_cb(("%07x" % (size - offset)).encode()) l = min(size - offset, 128) send_cmd(0x31, "G_WINIT") addr = struct.pack(">I", 0x08000000 + offset) raspi_uart.write(addr) raspi_uart.write(crc8(addr)) wait_ack("G_WREADY") payload = chr(l - 1) + fw[offset:offset + l] raspi_uart.write(payload) raspi_uart.write(crc8(payload)) wait_ack("G_WDONE") offset += l stage_cb("00000000") finally: GPIO.output(self.TOOLHEAD_BOOT, GPIO.LOW) GPIO.output(self.TOOLHEAD_POWER, self.TOOLHEAD_POWER_OFF) sleep(0.5) GPIO.output(self.TOOLHEAD_POWER, self._head_power_stat) raspi_uart.parity = PARITY_NONE raspi_uart.close() logger.debug("Update fw end")