Improved Initialize LTE



  • The LTE() constructor causes the modem to reboot when the call occurs after a power up. The reboot does not occur if you reset the chip. This can lead to hard to find bugs in the communication routines. I've added a wait_response('+SHUTDOWN', 4000) call to detect the modem restart and then a call to wait_response('+SYSSTART', 15000) which indicates the modem is ready.

    In the lte.isattached() method, Pycom uses the AT+CFUN? command to test if radios have been turned off. If the radios are off, this indicates the modem has crashed and they try to fix with the AT+CFUN=1 command. The problem with this is all the modem setup has been lost at that point (band setup, user configured modem settings, ...). When we initialize the modem we set the SMS text mode using the at('AT+CMGF=1') command. Since the setting is reset to 0 if the modem restarts, we can use the test AT+CMGF? != 1 to detect any modem crashes so we can do a modem reset and reinitialization.

    I think a better option would be for Pycom to set a python testable flag if the modem crashes.

    lte = None
    
    #####################################################################
    #                     Send AT Command To Modem
    #####################################################################
    def at(cmd):
        try:
            log("modem command: {}".format(cmd))
            util.wait()
            # lte.send_at_cmd(cmd, delay=10000)
            r = lte.send_at_cmd(cmd).split('\r\n')
            task_switch()
            r = list(filter(None, r))
            log("response: {}".format(r))
            task_switch()
    
        except Exception as ex:
            sys.print_exception(ex)
            r = []
    
        return r
    
    #####################################################################
    #                         Initialize LTE
    #####################################################################
    def init_lte():
        global lte
    
        try:
            log('initializing LTE...')
            task_switch()
            lte = LTE()
            task_switch()
    
            # modem will restart on power up situations
            r = wait_response('+SHUTDOWN', 4000)
            if r == True:
                wait_response('+SYSSTART', 15000)
    
        except Exception as ex:
            sys.print_exception(ex)
            util.reset(27, "LTE exception")
    
    #####################################################################
    #                         Initialize Modem
    #####################################################################
    def init_modem():
        try:
            if lte == None:
                init_lte()
    
            g.modem_state = g.MS_INIT_MODEM
            log("initializing modem...")
            
            log("set SMS mode to text")
            at('AT+CMGF=1')     # set SMS mode to text
            
            # if AT+CMFG? returns 0, the modem has crashed/restarted
    
            task_switch()
            lte.init()
            # lte.init(carrier='att')   # no known advantage
            task_switch()
            
            g.oIni.apn = g.oIni.apn_89014
            log("Kore AT&T SIM - APN: {0}".format(g.oIni.apn))
    
        except Exception as ex:
            sys.print_exception(ex)
            util.reset(27, "LTE exception")
            
    #####################################################################
    #               Is Cellular Modem Attached To Base Station
    #####################################################################
    def isattached():
        # returns: True/False
        try:
            task_switch()
            r = lte.isattached()
            # Pycom uses AT+CFUN? to test if radios have been turned off
            # this indicates modem has crashed and they try to fix with AT+CFUN=1
            # the problem is all the modem setup has been lost at that point
            # we will test AT+CMGF? != 1 to detect crash and then restart
            task_switch()
            if r == True:
                g.modem_state = g.MS_REGISTERED
    
        except Exception as ex:
            sys.print_exception(ex)
            r = False
    
        return r
    
    #####################################################################
    #                  Modem Restarted/Crashed Check
    #####################################################################
    def restarted():
        # return True if modem has crashed / restarted
        # if SMS text mode is reset to zero, modem has crashed / restarted
    
        try:
            r = at('AT+CMGF?')
            # response: ['+CMGF: 1', 'OK']
            if len(r) == 0:
                return False     # state unknown
    
            s = r[0]
    
            if (s[0:6] != '+CMGF:'):
                return False     # state unknown
            
            mode = int(s[7])
            if mode != 1:
                return True    # modem has crashed /restarted
    
            return False
    
        except Exception as ex:
            sys.print_exception(ex)
    
        return False     # state unknown
    
    #####################################################################
    #                    Wait For Specific Modem Response          
    #####################################################################
    def wait_response(response, msecs=10000):
        log('wait up to {0} msecs for modem response: {1}'.format(msecs, response))
        t0 = ticks_ms()
        while True:
            try:
                t1 = ticks_ms()
                tx = ticks_diff(t1, t0)
                log('{0} msecs'.format(tx))
    
                r = at('AT')
    
                t1 = ticks_ms()
                tx = ticks_diff(t1, t0)
                log('{0} msecs'.format(tx))
    
                for x in r:
                    if x == response:
                        log('****modem response found****: ' + response)
                        return True
    
                if tx > msecs:
                    log('modem response not found: ' + response)
                    return False
    
                sleep_ms(1000)
    
            except Exception as ex:
                sys.print_exception(ex)
    
    


  • You can check for modem crashes with

    mood=lte.send_at_cmd('at+cpin?').split('\r\n')[1]; print('mood =', mood)
    

    anything other than READY or +SYSSTART means the modem is crashed.


Log in to reply
 

Pycom on Twitter