From 761483bcb03d0fbe732cf06e1550aca1e02ff7b8 Mon Sep 17 00:00:00 2001 From: heffnercj Date: Thu, 23 Aug 2012 13:40:49 +0000 Subject: [PATCH] Added proper support for specifying an alternate serial port to all Gumbi subclasses. Also added auto-detection code to find the appropriate serial port if none is specified. --- docs/INSTALL | 33 +++++++++++++++++++++++++++++++ src/python/Makefile.in | 6 ++++++ src/python/bin/flashbin.py | 13 +++++++++--- src/python/gumbi/configuration.py | 4 ++-- src/python/gumbi/gpio.py | 2 +- src/python/gumbi/gumbi.py | 26 +++++++++++++++++++----- src/python/gumbi/parallel.py | 2 +- 7 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 docs/INSTALL diff --git a/docs/INSTALL b/docs/INSTALL new file mode 100644 index 0000000..327fa9f --- /dev/null +++ b/docs/INSTALL @@ -0,0 +1,33 @@ +PREREQUISITES + + The Gumbi API is written in Python, and requires no additional modules + outside of those included with the standard Python installation. + + The firmware is written in C, and must be built for the AVR architecture; + thus, you must have the AVR cross-compiler and toolchain installed on + your system in order to build the firmware. + + To install the firmware via the Makefile, you must also have the dfu-programmer + utility installed. Alternately, you can install the firmware using the + Atmel Flip utility. + + The majority of the API code is platform independant, and should work on + most systems; currently however, it has only been tested under Linux. + +INSTALLATION PROCEDURES + + To install the Gumbi API modules and associated Gumbi utilities: + + $ cd src/python + $ ./configure + # make + + To install the firmware onto the Gumbi board: + + $ cd src/avr + $ make + # make install + + Note that prior to installing the Gumbi board firmware, you must first + put the board into programming mode, by shorting the two RESET pins while + also shorting the two PROGRAM pins together. diff --git a/src/python/Makefile.in b/src/python/Makefile.in index 0280c84..46f9878 100644 --- a/src/python/Makefile.in +++ b/src/python/Makefile.in @@ -18,5 +18,11 @@ data: cp bin/config/* $(FLASHCONFDIR)/ clean: + rm -f gumbi/*.pyc rm -rf *.cache config.* build rm -f Makefile + +uninstall: + rm -f $(BINDIR)/gumbictl + rm -f $(BINDIR)/flashbin + rm -rf $(FLASHCONFDIR) diff --git a/src/python/bin/flashbin.py b/src/python/bin/flashbin.py index 6441d38..b1e0b51 100755 --- a/src/python/bin/flashbin.py +++ b/src/python/bin/flashbin.py @@ -76,7 +76,6 @@ def EraseChip(self): CONFIG_PATH = "bin/config/" CONF_EXT = '.conf' - PORT = None def wordflip(data): """ @@ -125,6 +124,7 @@ def usage(): print "\t-a, --address= Specify the starting address [0]" print "\t-s, --size= Specify the number of bytes to read/write" print "\t-f, --word-flip= Word-flip the contents of the specified file" + print "\t-P, --port= Set the Gumbi board's virtual serial port [/dev/ttyACM0]" print "\t-p, --path= Set the path to the chip configuration files [%s]" % CONFIG_PATH print "\t-v, --verbose Enabled verbose output" print "\t-h, --help Show help" @@ -145,13 +145,14 @@ def usage(): doerase = False verbose = False chip = None + port = None infile = None config = None outfile = None flipfile = None try: - opts, args = GetOpt(sys.argv[1:], "iela:s:r:w:c:f:p:vh", ["id", "erase", "list", "address=", "size=", "read=", "write=", "chip=", "word-flip=", "--path=", "help"]) + opts, args = GetOpt(sys.argv[1:], "iela:s:r:w:c:f:P:p:vh", ["id", "erase", "list", "address=", "size=", "read=", "write=", "chip=", "word-flip=", "port=", "path=", "verbose", "help"]) except GetoptError, e: print e usage() @@ -179,6 +180,8 @@ def usage(): open("%s.flip" % flipfile, "wb").write(wordflip(open(arg, "rb").read())) print "File saved to: %s.flip" % arg sys.exit(0) + elif opt in ('-P', '--port'): + port = arg elif opt in ('-p', '--path'): CONFIG_PATH = arg + '/' elif opt in ('-v', '--verbose'): @@ -193,6 +196,10 @@ def usage(): print "Please specify the chip type!" usage() + if len(ACTIONS) == 0: + print "Please specify an action (id, read, write, etc)!" + usage() + for action in ACTION_LIST: if ACTIONS.has_key(action): @@ -202,7 +209,7 @@ def usage(): sys.stdout.write("Connecting to Gumbi board...") sys.stdout.flush() - flash = NORFlash(config=config, port=PORT) + flash = NORFlash(config=config, port=port) if verbose: print "connected." diff --git a/src/python/gumbi/configuration.py b/src/python/gumbi/configuration.py index 51b5ca3..5e66d6f 100755 --- a/src/python/gumbi/configuration.py +++ b/src/python/gumbi/configuration.py @@ -129,7 +129,7 @@ class Configuration(Gumbi): "VOLTAGE" : [None] } - def __init__(self, config, mode): + def __init__(self, config, mode, port=None): """ Class initializer. Must be called BEFORE Gumbi.SetMode so that it can retrieve the current pin count from the Gumbi board. @@ -143,7 +143,7 @@ def __init__(self, config, mode): self.package_pins = 0 self.pins_shifted = False - Gumbi.__init__(self) + Gumbi.__init__(self, port=port) # Get the number of available pins on the Gumbi board self.num_pins = self.PinCount() diff --git a/src/python/gumbi/gpio.py b/src/python/gumbi/gpio.py index ce8ef6d..f081fb3 100755 --- a/src/python/gumbi/gpio.py +++ b/src/python/gumbi/gpio.py @@ -16,7 +16,7 @@ def __init__(self, config=None, voltage=None, port=None): Returns None. """ - self.config = Configuration(config, self.MODE) + self.config = Configuration(config, self.MODE, port) Gumbi.__init__(self, port=port) if voltage is not None: self.SetVoltage(voltage) diff --git a/src/python/gumbi/gumbi.py b/src/python/gumbi/gumbi.py index 7370112..8bcc481 100755 --- a/src/python/gumbi/gumbi.py +++ b/src/python/gumbi/gumbi.py @@ -30,7 +30,7 @@ class Gumbi: NULL = "\x00" DUMMY_BYTE = "\xFF" SERIAL_PORT = "/dev/ttyACM0" - + TBP_DEFAULT = 25 TOE_DEFAULT = 0 @@ -81,9 +81,6 @@ def __init__(self, port=None, new=True): self.port = port self.num_pins = 0 - if self.port is None: - self.port = self.SERIAL_PORT - if new: self._open() @@ -91,7 +88,26 @@ def _open(self): """ Opens a connection to the Gumbi board. For internal use only. """ - self.serial = serial.Serial(self.port) + + if self.port is not None: + self.serial = serial.Serial(self.port) + else: + n = 0 + last_error = '' + prefix = self.SERIAL_PORT[:-1] + + while n < 10: + try: + self.port = prefix + str(n) + self.serial = serial.Serial(self.port) + break + except Exception, e: + last_error = str(e) + n += 1 + self.port = None + + if self.port is None: + raise Exception(last_error) def _exit(self): """ diff --git a/src/python/gumbi/parallel.py b/src/python/gumbi/parallel.py index 9464dd0..f216e5d 100755 --- a/src/python/gumbi/parallel.py +++ b/src/python/gumbi/parallel.py @@ -16,7 +16,7 @@ def __init__(self, config=None, voltage=None, port=None): Returns None. """ - self.config = Configuration(config, self.MODE) + self.config = Configuration(config, self.MODE, port) Gumbi.__init__(self, port=port) if voltage is not None: self.SetVoltage(voltage)