Recovered from modem failure: OSError: AT+SMSWBOOT=3,0
-
My pyCom gPy device had an unresponsive lte modem.
During a failed firmware upgrade, it spit out this exception:
OSError: AT+SMSWBOOT=3,0 failed!Sending basic AT commands appeared to fail as well..
> import LTE > lte=lTE() > lte.send_at_command('ATI') ''
I recovered the modem by running the script supplied here by @jmarcelino
#!/usr/bin/env python import struct import crc import stp import time import os from machine import UART from machine import SD FFF_FMT = "<4sIIIIIIIHHIHHIHHHH" FFF_SLIM_FMT = "<4sIIIIIIIHHHH" FFF_FEATURES_SLIM = 1 << 0 FFF_MAGIC = "FFF!" SFFF_MAGIC = "SFFF" # Firmware SUFF_MAGIC = "SUFF" # Updater TEST_MAGIC = "TEST" # Test DIFF_MAGIC = "DIFF" # Diff Upgrade UPGR_MAGIC = "UPGR" # Generic raw upgrade RASR_MAGIC = "RASR" # Generic raw rasterize def read_rsp(s, size=None, timeout=-1): if timeout < 0: timeout = 20000 elif timeout is None: timeout = 0 while not s.any() and timeout > 0: time.sleep_ms(1) timeout -= 1 if size is not None: rsp = s.read(size) else: rsp = s.read() if rsp is not None: return rsp else: return b'' def print_pretty_response(rsp): lines = rsp.decode('ascii').split('\r\n') for line in lines: if line: print(line) def wait_for_modem(s, send=True, expected=b'OK'): while True: if send: s.write("AT\r\n") rsp = read_rsp(s, timeout=50) if expected in rsp: print() break else: print('.', end='', flush=True) time.sleep(0.5) def run(file_path, baudrate): abort = False print('<<< Welcome to the SQN3330 firmware updater >>>') if '/sd' in file_path: sd = SD() time.sleep(0.5) os.mount(sd, '/sd') time.sleep(0.5) blobsize = os.stat(file_path)[6] blob = open(file_path, "rb") if 'FiPy' in os.uname().sysname: pins = ('P20', 'P18', 'P19', 'P17') else: pins = ('P5', 'P98', 'P7', 'P99') s = UART(1, baudrate=baudrate, pins=pins, timeout_chars=100) s.read() # disable echo s.write("ATE0\r\n") response = read_rsp(s) # print('Entering recovery mode') # s.write("AT+SMSWBOOT=3,0\r\n") # response = read_rsp(s) # if b'OK' in response: # print('Resetting.', end='', flush=True) # s.write('AT^RESET\r\n') # wait_for_modem(s, send=False, expected=b'+SHUTDOWN') # time.sleep(2) # wait_for_modem(s) # s.write("AT\r\n") # s.write("AT\r\n") # else: # raise OSError('AT+SMSWBOOT=3,0 failed!') # # time.sleep(1) # s.read() print('Starting STP (DO NOT DISCONNECT POWER!!!)') s.write('AT+SMSTPU=\"ON_THE_FLY\"\r\n') response = read_rsp(s, 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() s.read() try: stp.start(blob, blobsize, s, baudrate, AT=False) print('Code download done, returning to user mode') except: blob.close() print('Code download failed, aborting!') abort = True time.sleep(1.5) s.read() s.write("AT+SMSWBOOT=1,0\r\n") response = read_rsp(s) print('Resetting (DO NOT DISCONNECT POWER!!!).', end='', flush=True) time.sleep(1.5) s.write("AT^RESET\r\n") wait_for_modem(s, send=False, expected=b'+SHUTDOWN') time.sleep(2) wait_for_modem(s, send=False, expected=b'+SYSSTART') if not abort: time.sleep(0.5) print('Deploying the upgrade (DO NOT DISCONNECT POWER!!!)...') s.write("AT+SMUPGRADE\r\n") response = read_rsp(s, timeout=120000) print('Resetting (DO NOT DISCONNECT POWER!!!).', end='', flush=True) time.sleep(1.5) s.write("AT^RESET\r\n") wait_for_modem(s, send=False, expected=b'+SHUTDOWN') time.sleep(2) wait_for_modem(s, send=False, expected=b'+SYSSTART') s.write("AT\r\n") s.write("AT\r\n") time.sleep(0.5) s.read() print('Upgrade completed!') print("Here's the current firmware version:") time.sleep(0.5) s.read() s.write("ATI1\r\n") response = read_rsp(s) print_pretty_response(response)
allowing it to run to COMPLETION (even though it appeared to hang for several minutes)
at the end of completion, the script was able to query the modem for firmware version (it was old)
I replaced the sqnsupgrade script with the original, and was able to run it to completion!
>>> import sqnsupgrade >>> sqnsupgrade.run('/sd/FIPY_GPY_CATM1_33988.dup', 921600) <<< Welcome to the SQN3330 firmware updater >>> Entering recovery mode Resetting.. Starting STP (DO NOT DISCONNECT POWER!!!) STP started Session opened: version 1, max transfer 8192 bytes Sending 5665583 bytes: [########################################] 100% Code download done, returning to user mode Resetting (DO NOT DISCONNECT POWER!!!).. ........ Deploying the upgrade (DO NOT DISCONNECT POWER!!!)... Resetting (DO NOT DISCONNECT POWER!!!).. ... Upgrade completed! Here's the current firmware version: UE5.0.0.0c LR5.1.1.0-33988 OK >>>