def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_ffh=False, mirror=False, switch_ffh=False, bootrom=False, rgbled=0x050505, debug=False, pkgdebug=False, atneg=True, max_try=10, direct=True, atneg_only=False, version_only=False): mirror = True if atneg_only else mirror recover = True if atneg_only else load_ffh resume = True if mirror or recover or atneg_only or version_only else resume if debug: print( 'mirror? {} recover? {} resume? {} direct? {} atneg_only? {} bootrom? {} ' .format(mirror, recover, resume, direct, atneg_only, bootrom)) abort = True external = False self.__serial = None if 'FiPy' in self.__sysname or 'GPy' in self.__sysname: if 'GPy' in self.__sysname: self.__pins = ('P5', 'P98', 'P7', 'P99') else: self.__pins = ('P20', 'P18', 'P19', 'P17') self.__serial = UART(1, baudrate=115200 if recover else baudrate, pins=self.__pins, timeout_chars=100) self.__serial.read() else: if port is None: raise ValueError('serial port not specified') if debug: print('Setting port {}'.format(port)) external = True br = 115200 if recover and not direct else baudrate if debug: print('Setting baudrate to {}'.format(br)) self.__serial = serial.Serial(port, br, bytesize=serial.EIGHTBITS, timeout=1 if version_only else 0.1) self.__serial.reset_input_buffer() self.__serial.reset_output_buffer() if debug: print('Initial prepartion complete...') if version_only: self.__serial.read() self.__serial.write(b"AT!=\"showver\"\r\n") time.sleep(.5) shver = self.read_rsp(2000) if shver is not None: self.print_pretty_response(shver) return True if not mirror: if bootrom: if debug: print('Loading built-in recovery bootrom') from sqnsbr import bootrom blob = bootrom() blobsize = blob.get_size() else: if debug: print('Loading {}'.format(file_path)) blobsize = os.stat(file_path)[6] blob = open(file_path, "rb") if not load_ffh: if not self.wakeup_modem(baudrate, port, 10, 1, debug): return False if not resume: # disable echo self.__serial.write(b"ATE0\r\n") response = self.read_rsp(size=6) self.__serial.read(100) if debug: print('Entering recovery mode') self.__serial.write(b"AT+SMOD?\r\n") response = self.return_pretty_response(self.read_rsp(size=7)) self.__serial.read(100) if debug: print("AT+SMOD? returned {}".format(response)) if not bootrom: self.__serial.write(b"AT+SMSWBOOT=3,1\r\n") time.sleep(2) self.wait_for_modem() self.__serial.write(b"AT\r\n") self.__serial.write(b"AT\r\n") else: self.__serial.read(100) if debug: print('Entering recovery mode') self.__serial.write(b"AT+SMOD?\r\n") response = self.return_pretty_response(self.read_rsp(size=7)) self.__serial.read(100) if debug: print("AT+SMOD? returned {}".format(response)) time.sleep(1) self.__serial.read() if (not recover) and (not direct): if mirror: time.sleep(.5) self.__serial.read(100) print( 'Going into MIRROR mode... please close this terminal to resume the upgrade via UART' ) self.uart_mirror(rgbled) elif bootrom: print('Starting STP (DO NOT DISCONNECT POWER!!!)') else: print('Starting STP ON_THE_FLY') self.__serial.read(100) self.__serial.write(b'AT+SMSTPU=\"ON_THE_FLY\"\r\n') response = self.read_rsp(size=4) if response != b'OK\r\n' and response != b'\r\nOK' and response != b'\nOK': raise OSError("Invalid answer '%s' from the device" % response) blob.close() self.__serial.read() elif recover and (not direct): if atneg: result = self.at_negotiation(baudrate, port, max_try, mirror, atneg_only, debug) if result: if atneg_only: return True if mirror: time.sleep(.5) self.__serial.read(100) print( 'Going into MIRROR mode... please close this terminal to resume the upgrade via UART' ) self.uart_mirror(rgbled) else: self.__serial.write(b"AT+STP\n") response = self.read_rsp(size=6) if not b'OK' in response: print('Failed to start STP mode!') sys.exit(1) else: print('AT auto-negotiation failed! Exiting.') return False else: if debug: print('Starting STP mode...') self.__serial.write(b"AT+STP\n") response = self.read_rsp(size=6) if not b'OK' in response: print('Failed to start STP mode!') sys.exit(1) try: if debug: print('Starting STP code upload') if stp.start(blob, blobsize, self.__serial, baudrate, AT=False, debug=debug, pkgdebug=pkgdebug): blob.close() if switch_ffh: print( 'Bootrom updated successfully, switching to upgrade mode' ) abort = False elif load_ffh: if not self.wakeup_modem(baudrate, port, 100, 1, debug): return False print( 'Upgrader loaded successfully, modem is in upgrade mode' ) return True else: print('Code download done, returning to user mode') abort = recover else: blob.close() print('Code download failed, aborting!') return False except: blob.close() print('Code download failed, aborting!') abort = True time.sleep(1.5) if not abort: self.__serial.read() if switch_ffh: self.__serial.write(b"AT+SMSWBOOT=0,1\r\n") return True else: self.special_print('Resetting (DO NOT DISCONNECT POWER!!!).', end='', flush=True) self.__serial.write(b"AT+SMSWBOOT=1,1\r\n") self.wait_for_modem(send=False, expected=b'+SYSSTART') self.__serial.write(b"AT\r\n") self.__serial.write(b"AT\r\n") time.sleep(0.5) self.__serial.read() print('Upgrade completed!') print("Here's the current firmware version:") time.sleep(0.5) self.__serial.read() self.__serial.write(b"AT!=\"showver\"\r\n") time.sleep(.5) shver = self.read_rsp(2000) if shver is not None: self.print_pretty_response(shver) return True return False
def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_ffh=False, mirror=False, switch_ffh=False, bootrom=False, rgbled=0x050505, debug=False, pkgdebug=False, atneg=True, max_try=10, direct=True, atneg_only=False, version_only=False, expected_smod=None, verbose=False, load_fff=False): self.__wait_msg = False mirror = True if atneg_only else mirror recover = True if atneg_only else load_ffh resume = True if mirror or recover or atneg_only or version_only else resume verbose = True if debug else verbose load_fff = False if bootrom and switch_ffh else load_fff if debug: print( 'mirror? {} recover? {} resume? {} direct? {} atneg_only? {} bootrom? {} load_fff? {}' .format(mirror, recover, resume, direct, atneg_only, bootrom, load_fff)) abort = True external = False self.__serial = None if 'FiPy' in self.__sysname or 'GPy' in self.__sysname: self.__serial = UART(1, baudrate=115200 if recover else baudrate, pins=self.__pins, timeout_chars=100) self.__serial.read() else: if port is None: raise ValueError('serial port not specified') if debug: print('Setting port {}'.format(port)) external = True br = 115200 if recover and not direct else baudrate if debug: print('Setting baudrate to {}'.format(br)) self.__serial = serial.Serial(port, br, bytesize=serial.EIGHTBITS, timeout=1 if version_only else 0.1) self.__serial.reset_input_buffer() self.__serial.reset_output_buffer() if version_only: self.__serial.read() self.__serial.write(b'AT\r\n') self.__serial.write(b'AT\r\n') self.__serial.read() if verbose: self.__serial.write(b"AT!=\"showver\"\r\n") else: self.__serial.write(b"ATI1\r\n") time.sleep(.5) shver = self.read_rsp(2000) if shver is not None: self.print_pretty_response(shver) return True if debug: print('Initial prepartion complete...') if not mirror: if bootrom: if debug: print('Loading built-in recovery bootrom...') try: # try compressed bootrom first from sqnsbrz import bootrom except: # fallback to uncompressed from sqnsbr import bootrom blob = bootrom() blobsize = blob.get_size() else: if debug: print('Loading {}'.format(file_path)) blobsize = os.stat(file_path)[6] if blobsize < 128: print('Firmware file is too small!') reconnect_uart() sys.exit(1) if blobsize > 4194304: if load_fff: print( "Firmware file is too big to load via FFF method. Using ON_THE_FLY" ) load_fff = False blob = open(file_path, "rb") if not load_ffh: if not self.wakeup_modem(baudrate, port, 10, 1, debug): return False if not resume: # disable echo self.__serial.write(b"ATE0\r\n") response = self.read_rsp(size=6) self.__serial.read(100) if debug: print('Entering upgrade mode...') self.__serial.write(b"AT+SMOD?\r\n") response = self.return_pretty_response(self.read_rsp(size=7)) self.__serial.read(100) if debug: print("AT+SMOD? returned {}".format(response)) self.__serial.write(b"AT+SQNSUPGRADENTF=\"started\"\r\n") self.wait_for_modem() if not load_fff: self.__serial.write(b"AT+SMSWBOOT=3,1\r\n") resp = self.read_rsp(100) if debug: print('AT+SMSWBOOT=3,1 returned: {}'.format(resp)) if b'ERROR' in resp: time.sleep(5) self.__serial.write(b"AT+SMSWBOOT=3,0\r\n") resp = self.read_rsp(100) if debug: print('AT+SMSWBOOT=3,0 returned: {}'.format(resp)) if b'OK' in resp: self.__serial.write(b"AT^RESET\r\n") resp = self.read_rsp(100) if debug: print('AT^RESET returned: {}'.format(resp)) else: print('Received ERROR from AT+SMSWBOOT=3,1! Aborting!') reconnect_uart() sys.exit(1) time.sleep(3) resp = self.__serial.read() if debug: print("Response after reset: {}".format(resp)) self.wait_for_modem() self.__serial.write(b"AT\r\n") else: self.__serial.read(100) if debug: print('Entering recovery mode') self.__serial.write(b"AT+SMOD?\r\n") response = self.return_pretty_response(self.read_rsp(size=7)) self.__serial.read(100) if debug: print("AT+SMOD? returned {}".format(response)) time.sleep(1) self.__serial.read() if (not recover) and (not direct): if mirror: time.sleep(.5) self.__serial.read(100) print( 'Going into MIRROR mode... please close this terminal to resume the upgrade via UART' ) self.uart_mirror(rgbled) elif bootrom: if verbose: print('Starting STP') else: if verbose: if load_fff: print('Starting STP [FFF]') else: print('Starting STP ON_THE_FLY') self.__serial.read(100) if verbose: print("Sending AT+CFUN=4") resonse = self.__serial.write(b'AT+CFUN=4\r\n') if verbose: print("AT+CFUN=4 returned {}".format(response)) self.__serial.read(100) if load_fff: if debug: print("Sending AT+SMSTPU") self.__serial.write(b'AT+SMSTPU\r\n') else: if debug: print("Sending AT+SMSTPU=\"ON_THE_FLY\"") self.__serial.write(b'AT+SMSTPU=\"ON_THE_FLY\"\r\n') response = self.read_rsp(size=4) if response != b'OK\r\n' and response != b'\r\nOK' and response != b'\nOK': raise OSError("Invalid answer '%s' from the device" % response) blob.close() self.__serial.read() elif recover and (not direct): if atneg: result = self.at_negotiation(baudrate, port, max_try, mirror, atneg_only, debug) if result: if atneg_only: return True if mirror: time.sleep(.5) self.__serial.read(100) print( 'Going into MIRROR mode... please close this terminal to resume the upgrade via UART' ) self.uart_mirror(rgbled) else: self.__serial.write(b"AT+STP\n") response = self.read_rsp(size=6) if not b'OK' in response: print('Failed to start STP mode!') reconnect_uart() sys.exit(1) else: print('AT auto-negotiation failed! Exiting.') return False else: if debug: print('Starting STP mode...') self.__serial.write(b"AT+STP\n") response = self.read_rsp(size=6) if not b'OK' in response: print('Failed to start STP mode!') reconnect_uart() sys.exit(1) try: if debug: if verbose: print('Starting STP code upload') if stp.start(blob, blobsize, self.__serial, baudrate, AT=False, debug=debug, pkgdebug=pkgdebug): blob.close() self.__serial.read() if switch_ffh: if verbose: print( 'Bootrom updated successfully, switching to recovery mode' ) abort = False elif load_ffh: if not self.wakeup_modem(baudrate, port, 100, 1, debug, 'Waiting for updater to load...'): return False if verbose: print( 'Upgrader loaded successfully, modem is in update mode' ) return True else: if verbose: print('Code download done, returning to user mode') abort = recover else: blob.close() print('Code download failed, aborting!') return False except: blob.close() print('Code download failed, aborting!') abort = True time.sleep(1.5) if not abort: self.__serial.read() if switch_ffh: self.__serial.write(b"AT+SMSWBOOT=0,1\r\n") resp = self.read_rsp(100) if debug: print("AT+SMSWBOOT=0,1 returned {}".format(resp)) if b"ERROR" in resp: time.sleep(5) self.__serial.write(b"AT+SMSWBOOT=0,0\r\n") resp = self.read_rsp(100) if debug: print('AT+SMSWBOOT=0,0 returned: {}'.format(resp)) if b'OK' in resp: self.__serial.write(b"AT^RESET\r\n") resp = self.read_rsp(100) if debug: print('AT^RESET returned: {}'.format(resp)) return True else: print('Received ERROR from AT+SMSWBOOT=0,0! Aborting!') return False return True else: if load_fff: self.__serial.write(b"AT+SMUPGRADE\r\n") if not self.wakeup_modem( baudrate, port, 100, 1, debug, self.__get_wait_msg(load_fff=load_fff)): print( "Timeout while waiting for modem to finish updating!") reconnect_uart() sys.exit(1) start = time.time() while True: self.__serial.read() self.__serial.write(b"AT+SMUPGRADE?\r\n") resp = self.read_rsp(1024) if debug: print("AT+SMUPGRADE? returned {} [timeout: {}]".format( resp, time.time() - start)) if resp == b'\x00' or resp == b'': time.sleep(2) if b'No report' in resp or b'on-going' in resp: time.sleep(1) if b'success' in resp or b'fail' in resp: break if time.time() - start >= 300: raise OSError('Timeout waiting for modem to respond!') self.__serial.write(b"AT+SMSWBOOT?\r\n") resp = self.read_rsp(100) if debug: print("AT+SMSWBOOT? returned {}".format(resp)) start = time.time() while (b"RECOVERY" not in resp) and (b"FFH" not in resp) and (b"FFF" not in resp): if debug: print("Timeout: {}".format(time.time() - start)) if time.time() - start >= 300: reconnect_uart() raise OSError('Timeout waiting for modem to respond!') time.sleep(2) if not self.wakeup_modem( baudrate, port, 100, 1, debug, self.__get_wait_msg(load_fff=load_fff)): reconnect_uart() raise OSError( 'Timeout while waiting for modem to finish updating!' ) self.__serial.read() self.__serial.write(b"AT+SMSWBOOT?\r\n") resp = self.read_rsp(100) if debug: print("AT+SMSWBOOT? returned {}".format(resp)) self.__serial.read() self.__serial.write(b"AT+SMUPGRADE?\r\n") resp = self.read_rsp(1024) if debug: print("AT+SMUPGRADE? returned {}".format(resp)) sqnup_result = self.return_upgrade_response(resp) if debug: print('This is my result: {}'.format(sqnup_result)) if 'success' in sqnup_result: if not load_fff: self.special_print('Resetting.', end='', flush=True) self.__serial.write(b"AT+SMSWBOOT=1,1\r\n") if debug: print("AT+SMSWBOOT=1,1 returned {}".format(resp)) if b"ERROR" in resp: time.sleep(5) self.__serial.write(b"AT+SMSWBOOT=1,0\r\n") resp = self.read_rsp(100) if debug: print('AT+SMSWBOOT=1,0 returned: {}'.format( resp)) if b'OK' in resp: self.__serial.write(b"AT^RESET\r\n") resp = self.read_rsp(100) if debug: print('AT^RESET returned: {}'.format(resp)) return True else: print( 'Received ERROR from AT+SMSWBOOT=1,0! Aborting!' ) return False self.wait_for_modem(send=False, echo_char='.', expected=b'+SYSSTART') elif sqnup_result is not None: print( 'Upgrade failed with result {}!'.format(sqnup_result)) print('Please check your firmware file(s)') else: print("Invalid response after upgrade... aborting.") reconnect_uart() sys.exit(1) self.__serial.write(b"AT\r\n") self.__serial.write(b"AT\r\n") time.sleep(0.5) if 'success' in sqnup_result: self.__serial.write(b"AT+SQNSUPGRADENTF=\"success\"\r\n") self.__serial.read() return True elif sqnup_result is None: print( 'Modem upgrade was unsucessfull. Please check your firmware file(s)' ) return False