r4776 - developers/charlie/Tests/gsm

charlie at docs.openmoko.org charlie at docs.openmoko.org
Mon Nov 10 11:59:31 CET 2008


Author: charlie
Date: 2008-11-10 11:59:31 +0100 (Mon, 10 Nov 2008)
New Revision: 4776

Added:
   developers/charlie/Tests/gsm/mux.py
Modified:
   developers/charlie/Tests/gsm/test.py
Log:
Updated GSM modem test script


Added: developers/charlie/Tests/gsm/mux.py
===================================================================
--- developers/charlie/Tests/gsm/mux.py	                        (rev 0)
+++ developers/charlie/Tests/gsm/mux.py	2008-11-10 10:59:31 UTC (rev 4776)
@@ -0,0 +1,68 @@
+# GPL licence copyright openmoko
+# charlie at openmoko.org
+
+"""Multiplexer module
+
+This module contains functions that can be used to pass the modem into
+multiplexer mode. It is experimental, not intended to be actually used
+in the factory testing suite.
+"""
+
+
+EA = 0x01
+CR = 0x02
+SABM = 0x2f
+PF = 0x10
+CLD = 0xC1
+
+crc_table = [
+    0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED,
+    0x7C, 0x09, 0x98, 0xEA, 0x7B, 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A,
+    0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, 0x38,
+    0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44,
+    0x31, 0xA0, 0xD2, 0x43, 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0,
+    0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, 0x70, 0xE1,
+    0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79,
+    0xE8, 0x9A, 0x0B, 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19,
+    0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, 0x48, 0xD9, 0xAB,
+    0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0,
+    0xA2, 0x33, 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A,
+    0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, 0xE0, 0x71, 0x03, 0x92,
+    0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A,
+    0x9B, 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63,
+    0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, 0xD8, 0x49, 0x3B, 0xAA, 0xDF,
+    0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,
+    0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29,
+    0xB8, 0xCD, 0x5C, 0x2E, 0xBF, 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06,
+    0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, 0x8C,
+    0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0,
+    0x85, 0x14, 0x66, 0xF7, 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C,
+    0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, 0xB4, 0x25,
+    0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD,
+    0x2C, 0x5E, 0xCF]
+
+
+def calc_crc(msg):
+    fcs = 0xff
+    for c in msg:
+        fcs = crc_table[fcs ^ ord(c)]
+    return 0xff - fcs
+
+
+def format_frame(s):
+    return ''.join(['%02X' % ord(c) for c in s])
+
+
+def send_frame(file, channel, data, type):
+    msg = chr(0xf9) * 2
+    print 'sending "%s"' % format_frame(msg)
+    print file.write(msg)
+    # Then we create the address field
+    address = EA | CR | (channel & 63) << 2
+    # The type field
+    msg = chr(address) + chr(type)
+    # CRC
+    crc = chr(calc_crc(msg))
+    msg = '\x7e' + msg + crc + '\x7e'
+    print 'sending "%s"' % format_frame(msg)
+    print file.write(msg)

Modified: developers/charlie/Tests/gsm/test.py
===================================================================
--- developers/charlie/Tests/gsm/test.py	2008-11-09 19:39:20 UTC (rev 4775)
+++ developers/charlie/Tests/gsm/test.py	2008-11-10 10:59:31 UTC (rev 4776)
@@ -2,120 +2,148 @@
 # GPL licence copyright openmoko
 # charlie at openmoko.org
 
-# This is just a test... Very ugly and un-pythonic structure... Please
-# don't use it. The idea is to find a way to write hadware independant
-# modem intialization, so the user space can start communicating with
-# any GSM modem. I want to cover both TI Calypso and Siemens MC75i.
+"""GSM modem testing script
 
+This script will try to initialize the modem and then communicate with
+it. The goal is to make it work with both the TI calypso and Siemens
+MC75i modems.
+"""
+
 import time
 import sys
+import serial
 
-EA = 0x01
-CR = 0x02
-SABM = 0x2f
-PF = 0x10
-CLD = 0xC1
+import logging
+logger = logging.getLogger('test')
 
-crc_table = [
-    0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED,
-    0x7C, 0x09, 0x98, 0xEA, 0x7B, 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A,
-    0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, 0x38,
-    0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44,
-    0x31, 0xA0, 0xD2, 0x43, 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0,
-    0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, 0x70, 0xE1,
-    0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79,
-    0xE8, 0x9A, 0x0B, 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19,
-    0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, 0x48, 0xD9, 0xAB,
-    0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0,
-    0xA2, 0x33, 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A,
-    0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, 0xE0, 0x71, 0x03, 0x92,
-    0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A,
-    0x9B, 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63,
-    0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, 0xD8, 0x49, 0x3B, 0xAA, 0xDF,
-    0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,
-    0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29,
-    0xB8, 0xCD, 0x5C, 0x2E, 0xBF, 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06,
-    0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, 0x8C,
-    0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0,
-    0x85, 0x14, 0x66, 0xF7, 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C,
-    0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, 0xB4, 0x25,
-    0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD,
-    0x2C, 0x5E, 0xCF
-]
 
-def calc_crc(msg):
-    fcs = 0xff
-    for c in msg:
-        fcs = crc_table[fcs ^ ord(c)]
-    return 0xff - fcs
-    
-def format_frame(s):
-    return ''.join(['%02X' % ord(c) for c in s])
-
-def send_frame(file, channel, data, type):
-    msg = chr(0xf9) * 2
-    print 'sending "%s"' % format_frame(msg)
-    print file.write(msg)
-    # Then we create the address field
-    address = EA | CR | (channel & 63) << 2
-    # The type field
-    msg = chr(address) + chr(type)
-    # CRC
-    crc = chr(calc_crc(msg))
-    msg = '\x7e' + msg + crc + '\x7e'
-    print 'sending "%s"' % format_frame(msg)
-    print file.write(msg)
-    
-def chat(file, command):
-    print "sending : %s" % command
-    file.write('%s\n\r' % command)
-    file.flush()
+def chat(modem, command):
+    """Send a command to the modem and wait for a reply
+    """
+    logger.debug("sending : %s", command)
+    modem.write('%s\r' % command)
+    modem.flush()
     ret = ''
     while True:
-        c = file.read(1)
+        c = modem.read(1)
         if not c:
             break
         ret += c
         if ret.endswith('\r\nOK\r\n'):
             break
-    print "got reply : %s" % repr(ret)
+    logger.debug("got reply : %s", repr(ret))
     return ret
 
-# Where do those sleep times come from ? Shouldn't this be done in the
-# kernel anyway ? It there a way to make modem initialization hardware
-# independant ?
-print "turn modem off"
-open('/sys/devices/platform/neo1973-pm-gsm.0/power_on', 'w').write('0')
-time.sleep(1)
-print "turn modem on"
-open('/sys/devices/platform/neo1973-pm-gsm.0/power_on', 'w').write('1')
-time.sleep(1)
-print "reset modem"
-open('/sys/devices/platform/neo1973-pm-gsm.0/reset', 'w').write('1')
-time.sleep(1)
-open('/sys/devices/platform/neo1973-pm-gsm.0/reset', 'w').write('0')
-time.sleep(4)
 
-# Connect to the serial port
-import serial
-modem = serial.Serial('/dev/ttySAC0', 115200, rtscts=1, timeout=1)
-print "waiting for ready msg"
-# The modem should send something after it is initialized...
-rep = modem.read(256)
-if not rep:
-    print "Error no msg"
-    sys.exit(-1)
-print repr(rep)
+def reset_calypso():
+    """Initialize the modem before we can start sending AT commands
 
-# We wake the modem up (?) Do we always have to do this ?
-chat(modem, 'AT')
+    This part of the code is specific to TI calypso modem. Maybe we
+    should modify the kernel so that we don't have to do that in user
+    space.
+    """
+    logger.debug("turn modem off")
+    open('/sys/devices/platform/neo1973-pm-gsm.0/power_on', 'w').write('0')
+    time.sleep(1)
+    logger.debug("turn modem on")
+    open('/sys/devices/platform/neo1973-pm-gsm.0/power_on', 'w').write('1')
+    time.sleep(1)
+    logger.debug("reset modem")
+    open('/sys/devices/platform/neo1973-pm-gsm.0/reset', 'w').write('1')
+    time.sleep(1)
+    open('/sys/devices/platform/neo1973-pm-gsm.0/reset', 'w').write('0')
+    time.sleep(4)
 
-chat(modem, 'ATZ')              # reset
-chat(modem, 'ATE0')             # echo off
-chat(modem, 'AT+CGMR')          # get the firmware version
-ret = chat(modem, 'AT+CLAC')          # get the list of AT commands
 
-print
-print ret
+def basic_tests(modem):
+    """Perform some basic tests that don't need a SIM card"""
+    # TODO: check the return values
+    chat(modem, 'AT+CMUX?')      # Multiplexing mode (error on calypso)
+    chat(modem, 'AT+CGMM')       # Model id
+    chat(modem, 'AT+CGMR')       # Firmware version
+    chat(modem, 'AT+CGMI')       # Manufacturer id
+    chat(modem, 'AT+IPR?')       # Bit rate
+    chat(modem, 'AT+ICF?')       # Character framing
+    chat(modem, 'ATS3?')         # Command line term
+    chat(modem, 'ATS4?')         # Response formating
+    chat(modem, 'ATS5?')         # Command line editing char
+    chat(modem, 'AT+ICF?')       # TE-TA char framing
+    chat(modem, 'AT+IFC?')       # Flow control (calypso != MC75i)
+    chat(modem, 'AT+CSCS?')      # Character set
+    chat(modem, 'AT+CFUN?')      # Phone functionalities
+    chat(modem, 'AT+CLAC')       # List of AT commands
 
+    chat(modem, 'AT+CSQ')       # Signal quality
 
+
+def basic_sim_test(modem):
+    """Some basic tests with the SIM, but not using the GSM network.
+    """
+    chat(modem, 'AT+CIMI')      # IMSI
+    chat(modem, 'AT+CPIN?')     # SIM status (e.g 'READY', 'SIM PIN')
+    chat(modem, 'AT+CPBS?')     # Phonebook memory storage
+    chat(modem, 'AT+CPBS="SM"')
+    chat(modem, 'AT+CPBR=?')    # Phonebook entries range. May return
+                                # error on calypso if phonebook is
+                                # empty
+    # chat(modem, 'AT+CPBW=1,"01234",129,"hello"')
+
+
+def gsm_network_tests(modem):
+    """Some basic GSM network tests
+
+    We need to be allowed to register to a provider.
+    """
+    chat(modem, 'AT+CFUN=1')    # Turn antenna on
+    chat(modem, 'AT+COPS=?')    # Find all providers
+    # On the calypso it returns nothing...
+    # TODO: check that at least one provider is available
+    chat(modem, 'AT+COPS=0')    # Register
+    # On the MC75i is returns OK and then try to register
+    chat(modem, 'AT+COPS?')     # See provider
+
+
+USAGE = "test.py [device]"
+
+if __name__ == '__main__':
+    # The first parameter is the name of the device
+    if len(sys.argv) == 2:
+        device = sys.argv[1]
+    elif len(sys.argv) == 1:
+        device = '/dev/ttySAC0'
+    else:
+        print USAGE
+        sys.exit(-1)
+
+    logging.basicConfig(level=logging.DEBUG,
+                        format='%(name)-8s %(levelname)-8s %(message)s')
+
+    logger.info("using device %s", device)
+
+#    reset_calypso()
+
+    modem = serial.Serial(device, 115200, rtscts=1, timeout=5)
+    logger.debug("waiting for ready msg")
+    # The modem should send something after it is initialized...
+    rep = modem.read(256)
+    if not rep:
+        logger.error("Error no msg")
+        # sys.exit(-1)
+    logger.debug("Ready message: %s", repr(rep))
+
+    # We start by a AT command to wake up the modem
+    # (Probably only needed by TI Calypso)
+    chat(modem, 'AT')
+    chat(modem, 'ATE0')             # echo off
+    chat(modem, 'ATZ')              # reset
+    chat(modem, 'AT+CMEE=2')        # verbose error
+
+
+    # Perform some basic tests
+    basic_tests(modem)
+    basic_sim_test(modem)
+    gsm_network_tests(modem)
+
+    # turn off the modem
+    # XXX: only work with Siemens MC75i
+    # chat(modem, 'AT^SMSO')




More information about the commitlog mailing list