From 075ecfd995410f84c275d56e1c09152cbab3a165 Mon Sep 17 00:00:00 2001 From: ssem Date: Wed, 1 Jul 2015 12:11:17 -0400 Subject: [PATCH] ftdi pinout & check euid & setup.py created a tiny menu to display FTDI 232R-3v3-2MM pinout performs a simple geteuid and warns user if they are not root added setup.py for easy install --- .gitignore | 7 + baudrate.py | 324 --------------------------------------- setup.py | 8 + LICENSE => src/LICENSE | 0 src/baudrate | 340 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 355 insertions(+), 324 deletions(-) create mode 100644 .gitignore delete mode 100755 baudrate.py create mode 100755 setup.py rename LICENSE => src/LICENSE (100%) create mode 100755 src/baudrate diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7272da3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.pyc +*.swp +build +.coverage +htmlcov +*.out +*.db diff --git a/baudrate.py b/baudrate.py deleted file mode 100755 index e8f7667..0000000 --- a/baudrate.py +++ /dev/null @@ -1,324 +0,0 @@ -#!/usr/bin/env python - -import sys -import time -import serial -from threading import Thread - -class RawInput: - """Gets a single character from standard input. Does not echo to the screen.""" - def __init__(self): - try: - self.impl = RawInputWindows() - except ImportError: - self.impl = RawInputUnix() - - def __call__(self): return self.impl() - - -class RawInputUnix: - def __init__(self): - import tty, sys - - def __call__(self): - import sys, tty, termios - fd = sys.stdin.fileno() - old_settings = termios.tcgetattr(fd) - try: - tty.setraw(sys.stdin.fileno()) - ch = sys.stdin.read(1) - finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) - return ch - - -class RawInputWindows: - def __init__(self): - import msvcrt - - def __call__(self): - import msvcrt - return msvcrt.getch() - -class Baudrate: - - VERSION = '1.0' - READ_TIMEOUT = 5 - BAUDRATES = [ -# "1200", -# "1800", -# "2400", -# "4800", - "9600", - "38400", - "19200", - "57600", - "115200", - ] - - UPKEYS = ['u', 'U', 'A'] - DOWNKEYS = ['d', 'D', 'B'] - - MIN_CHAR_COUNT = 25 - WHITESPACE = [' ', '\t', '\r', '\n'] - PUNCTUATION = ['.', ',', ':', ';', '?', '!'] - VOWELS = ['a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U'] - - def __init__(self, port=None, threshold=MIN_CHAR_COUNT, timeout=READ_TIMEOUT, name=None, auto=True, verbose=False): - self.port = port - self.threshold = threshold - self.timeout = timeout - self.name = name - self.auto_detect = auto - self.verbose = verbose - self.index = len(self.BAUDRATES) - 1 - self.valid_characters = [] - self.ctlc = False - self.thread = None - - self._gen_char_list() - - def _gen_char_list(self): - c = ' ' - - while c <= '~': - self.valid_characters.append(c) - c = chr(ord(c) + 1) - - for c in self.WHITESPACE: - if c not in self.valid_characters: - self.valid_characters.append(c) - - def _print(self, data): - if self.verbose: - sys.stderr.write(data) - - def Open(self): - self.serial = serial.Serial(self.port, timeout=self.timeout) - self.NextBaudrate(0) - - def NextBaudrate(self, updn): - - self.index += updn - - if self.index >= len(self.BAUDRATES): - self.index = 0 - elif self.index < 0: - self.index = len(self.BAUDRATES) - 1 - - sys.stderr.write('\n\n@@@@@@@@@@@@@@@@@@@@@ Baudrate: %s @@@@@@@@@@@@@@@@@@@@@\n\n' % self.BAUDRATES[self.index]) - - self.serial.flush() - self.serial.baudrate = self.BAUDRATES[self.index] - self.serial.flush() - - def Detect(self): - count = 0 - whitespace = 0 - punctuation = 0 - vowels = 0 - start_time = 0 - timed_out = False - clear_counters = False - - if not self.auto_detect: - self.thread = Thread(None, self.HandleKeypress, None, (self, 1)) - self.thread.start() - - while True: - if start_time == 0: - start_time = time.time() - - byte = self.serial.read(1) - - if byte: - if self.auto_detect and byte in self.valid_characters: - if byte in self.WHITESPACE: - whitespace += 1 - elif byte in self.PUNCTUATION: - punctuation += 1 - elif byte in self.VOWELS: - vowels += 1 - - count += 1 - else: - clear_counters = True - - self._print(byte) - - if count >= self.threshold and whitespace > 0 and punctuation > 0 and vowels > 0: - break - elif (time.time() - start_time) >= self.timeout: - timed_out = True - else: - timed_out = True - - if timed_out and self.auto_detect: - start_time = 0 - self.NextBaudrate(-1) - clear_counters = True - timed_out = False - - if clear_counters: - whitespace = 0 - punctuation = 0 - vowels = 0 - count = 0 - clear_counters = False - - if self.ctlc: - break - - self._print("\n") - return self.BAUDRATES[self.index] - - def HandleKeypress(self, *args): - userinput = RawInput() - - while not self.ctlc: - c = userinput() - if c in self.UPKEYS: - self.NextBaudrate(1) - elif c in self.DOWNKEYS: - self.NextBaudrate(-1) - elif c == '\x03': - self.ctlc = True - - def MinicomConfig(self, name=None): - success = True - - if name is None: - name = self.name - - config = "########################################################################\n" - config += "# Minicom configuration file - use \"minicom -s\" to change parameters.\n" - config += "pu port %s\n" % self.port - config += "pu baudrate %s\n" % self.BAUDRATES[self.index] - config += "pu bits 8\n" - config += "pu parity N\n" - config += "pu stopbits 1\n" - config += "pu rtscts No\n" - config += "########################################################################\n" - - if name is not None and name: - try: - open("/etc/minicom/minirc.%s" % name, "w").write(config) - except Exception, e: - print "Error saving minicom config file:", str(e) - success = False - - return (success, config) - - def Close(self): - self.ctlc = True - self.serial.close() - - - -if __name__ == '__main__': - - import subprocess - from getopt import getopt as GetOpt, GetoptError - - def usage(): - baud = Baudrate() - - print "" - print "Baudrate v%s" % baud.VERSION - print "Craig Heffner, http://www.devttys0.com" - print "" - print "Usage: %s [OPTIONS]" % sys.argv[0] - print "" - print "\t-p Specify the serial port to use [/dev/ttyUSB0]" - print "\t-t Set the timeout period used when switching baudrates in auto detect mode [%d]" % baud.READ_TIMEOUT - print "\t-c Set the minimum ASCII character threshold used during auto detect mode [%d]" % baud.MIN_CHAR_COUNT - print "\t-n Save the resulting serial configuration as and automatically invoke minicom (implies -a)" - print "\t-a Enable auto detect mode" - print "\t-b Display supported baud rates and exit" - print "\t-q Do not display data read from the serial port" - print "\t-h Display help" - print "" - sys.exit(1) - - def main(): - display = False - verbose = True - auto = False - run = False - threshold = 25 - timeout = 5 - name = None - port = '/dev/ttyUSB0' - - try: - (opts, args) = GetOpt(sys.argv[1:], 'p:t:c:n:abqh') - except GetoptError, e: - print e - usage() - - for opt, arg in opts: - if opt == '-t': - timeout = int(arg) - elif opt == '-c': - threshold = int(arg) - elif opt == '-p': - port = arg - elif opt == '-n': - name = arg - auto = True - run = True - elif opt == '-a': - auto = True - elif opt == '-b': - display = True - elif opt == '-q': - verbose = False - else: - usage() - - baud = Baudrate(port, threshold=threshold, timeout=timeout, name=name, verbose=verbose, auto=auto) - - if display: - print "" - for rate in baud.BAUDRATES: - print "\t%s" % rate - print "" - else: - print "" - print "Starting baudrate detection on %s, turn on your serial device now." % port - print "Press Ctl+C to quit." - print "" - - baud.Open() - - try: - rate = baud.Detect() - print "\nDetected baudrate: %s" % rate - - if name is None: - print "\nSave minicom configuration as: ", - name = sys.stdin.readline().strip() - print "" - - (ok, config) = baud.MinicomConfig(name) - if name and name is not None: - if ok: - if not run: - print "Configuration saved. Run minicom now [n/Y]? ", - yn = sys.stdin.readline().strip() - print "" - if yn == "" or yn.lower().startswith('y'): - run = True - - if run: - subprocess.call(["minicom", name]) - else: - print config - else: - print config - except KeyboardInterrupt: - pass - - baud.Close() - - main() diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..a3471e7 --- /dev/null +++ b/setup.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python +from distutils.core import setup + +setup(name='baudrate', + version='0.1', + description='serial baudrate detector', + author='Craig Heffner', + scripts=['src/baudrate']) diff --git a/LICENSE b/src/LICENSE similarity index 100% rename from LICENSE rename to src/LICENSE diff --git a/src/baudrate b/src/baudrate new file mode 100755 index 0000000..cf8a908 --- /dev/null +++ b/src/baudrate @@ -0,0 +1,340 @@ +#!/usr/bin/python2.7 + +import os +import sys +import time +import serial +from threading import Thread + +class RawInput: + """Gets a single character from standard input. Does not echo to the screen.""" + def __init__(self): + try: + self.impl = RawInputWindows() + except ImportError: + self.impl = RawInputUnix() + + def __call__(self): return self.impl() + + +class RawInputUnix: + def __init__(self): + import tty, sys + + def __call__(self): + import sys, tty, termios + fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(fd) + try: + tty.setraw(sys.stdin.fileno()) + ch = sys.stdin.read(1) + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + return ch + + +class RawInputWindows: + def __init__(self): + import msvcrt + + def __call__(self): + import msvcrt + return msvcrt.getch() + +class Baudrate: + + VERSION = '1.0' + READ_TIMEOUT = 5 + BAUDRATES = [ +# "1200", +# "1800", +# "2400", +# "4800", + "9600", + "38400", + "19200", + "57600", + "115200", + ] + + UPKEYS = ['u', 'U', 'A'] + DOWNKEYS = ['d', 'D', 'B'] + + MIN_CHAR_COUNT = 25 + WHITESPACE = [' ', '\t', '\r', '\n'] + PUNCTUATION = ['.', ',', ':', ';', '?', '!'] + VOWELS = ['a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U'] + + def __init__(self, port=None, threshold=MIN_CHAR_COUNT, timeout=READ_TIMEOUT, name=None, auto=True, verbose=False): + self.port = port + self.threshold = threshold + self.timeout = timeout + self.name = name + self.auto_detect = auto + self.verbose = verbose + self.index = len(self.BAUDRATES) - 1 + self.valid_characters = [] + self.ctlc = False + self.thread = None + + self._gen_char_list() + + def _gen_char_list(self): + c = ' ' + + while c <= '~': + self.valid_characters.append(c) + c = chr(ord(c) + 1) + + for c in self.WHITESPACE: + if c not in self.valid_characters: + self.valid_characters.append(c) + + def _print(self, data): + if self.verbose: + sys.stderr.write(data) + + def Open(self): + self.serial = serial.Serial(self.port, timeout=self.timeout) + self.NextBaudrate(0) + + def NextBaudrate(self, updn): + + self.index += updn + + if self.index >= len(self.BAUDRATES): + self.index = 0 + elif self.index < 0: + self.index = len(self.BAUDRATES) - 1 + + sys.stderr.write('\n\n@@@@@@@@@@@@@@@@@@@@@ Baudrate: %s @@@@@@@@@@@@@@@@@@@@@\n\n' % self.BAUDRATES[self.index]) + + self.serial.flush() + self.serial.baudrate = self.BAUDRATES[self.index] + self.serial.flush() + + def Detect(self): + count = 0 + whitespace = 0 + punctuation = 0 + vowels = 0 + start_time = 0 + timed_out = False + clear_counters = False + + if not self.auto_detect: + self.thread = Thread(None, self.HandleKeypress, None, (self, 1)) + self.thread.start() + + while True: + if start_time == 0: + start_time = time.time() + + byte = self.serial.read(1) + + if byte: + if self.auto_detect and byte in self.valid_characters: + if byte in self.WHITESPACE: + whitespace += 1 + elif byte in self.PUNCTUATION: + punctuation += 1 + elif byte in self.VOWELS: + vowels += 1 + + count += 1 + else: + clear_counters = True + + self._print(byte) + + if count >= self.threshold and whitespace > 0 and punctuation > 0 and vowels > 0: + break + elif (time.time() - start_time) >= self.timeout: + timed_out = True + else: + timed_out = True + + if timed_out and self.auto_detect: + start_time = 0 + self.NextBaudrate(-1) + clear_counters = True + timed_out = False + + if clear_counters: + whitespace = 0 + punctuation = 0 + vowels = 0 + count = 0 + clear_counters = False + + if self.ctlc: + break + + self._print("\n") + return self.BAUDRATES[self.index] + + def HandleKeypress(self, *args): + userinput = RawInput() + + while not self.ctlc: + c = userinput() + if c in self.UPKEYS: + self.NextBaudrate(1) + elif c in self.DOWNKEYS: + self.NextBaudrate(-1) + elif c == '\x03': + self.ctlc = True + + def MinicomConfig(self, name=None): + success = True + + if name is None: + name = self.name + + config = "########################################################################\n" + config += "# Minicom configuration file - use \"minicom -s\" to change parameters.\n" + config += "pu port %s\n" % self.port + config += "pu baudrate %s\n" % self.BAUDRATES[self.index] + config += "pu bits 8\n" + config += "pu parity N\n" + config += "pu stopbits 1\n" + config += "pu rtscts No\n" + config += "########################################################################\n" + + if name is not None and name: + try: + open("/etc/minicom/minirc.%s" % name, "w").write(config) + except Exception, e: + print "Error saving minicom config file:", str(e) + success = False + + return (success, config) + + def Close(self): + self.ctlc = True + self.serial.close() + + + +if __name__ == '__main__': + + import subprocess + from getopt import getopt as GetOpt, GetoptError + + def usage(): + baud = Baudrate() + + print "" + print "Baudrate v%s" % baud.VERSION + print "Craig Heffner, http://www.devttys0.com" + print "" + print "Usage: %s [OPTIONS]" % sys.argv[0] + print "" + print "\t-p Specify the serial port to use [/dev/ttyUSB0]" + print "\t-t Set the timeout period used when switching baudrates in auto detect mode [%d]" % baud.READ_TIMEOUT + print "\t-c Set the minimum ASCII character threshold used during auto detect mode [%d]" % baud.MIN_CHAR_COUNT + print "\t-n Save the resulting serial configuration as and automatically invoke minicom (implies -a)" + print "\t-a Enable auto detect mode" + print "\t-b Display supported baud rates and exit" + print "\t-q Do not display data read from the serial port" + print "\t-h Display help" + print "\t-P Display a table of UART to FTDI pin mappings" + print "" + sys.exit(1) + + def main(): + display = False + verbose = True + auto = False + run = False + threshold = 25 + timeout = 5 + name = None + port = '/dev/ttyUSB0' + + try: + (opts, args) = GetOpt(sys.argv[1:], 'p:t:c:n:abqhP') + except GetoptError, e: + print e + usage() + for opt, arg in opts: + if opt == '-P': + print "\n\t Common Pin Mappings for UART" + print "----------------------------------------------------" + print "| Description | Typical voltage | TTL-232R-3V3-2MM |" + print "----------------------------------------------------" + print "| GND | 0.0 | black |" + print "| CTS# | nc | brown |" + print "| VCC | nc | purple |" + print "| TXD | 3.0 - 3.3 | orange |" + print "| RXD | 0.0 - 2.8 | yellow |" + print "| RTS | nc | green |" + print "----------------------------------------------------\n" + exit() + elif opt == '-t': + timeout = int(arg) + elif opt == '-c': + threshold = int(arg) + elif opt == '-p': + port = arg + elif opt == '-n': + name = arg + auto = True + run = True + elif opt == '-a': + auto = True + elif opt == '-b': + display = True + elif opt == '-q': + verbose = False + else: + usage() + + if os.geteuid() != 0: + exit("\n\tMust be root to open %s\n" % port) + baud = Baudrate(port, threshold=threshold, timeout=timeout, name=name, verbose=verbose, auto=auto) + + if display: + print "" + for rate in baud.BAUDRATES: + print "\t%s" % rate + print "" + else: + print "" + print "Starting baudrate detection on %s, turn on your serial device now." % port + print "Press Ctl+C to quit." + print "" + + baud.Open() + + try: + rate = baud.Detect() + print "\nDetected baudrate: %s" % rate + + if name is None: + print "\nSave minicom configuration as: ", + name = sys.stdin.readline().strip() + print "" + + (ok, config) = baud.MinicomConfig(name) + if name and name is not None: + if ok: + if not run: + print "Configuration saved. Run minicom now [n/Y]? ", + yn = sys.stdin.readline().strip() + print "" + if yn == "" or yn.lower().startswith('y'): + run = True + + if run: + subprocess.call(["minicom", name]) + else: + print config + else: + print config + except KeyboardInterrupt: + pass + + baud.Close() + + main()