#!/usr/bin/env python import serial import select import sys, os import termios import time class Replica1Terminal: def __init__(self, portname): self.portname = portname self.port = serial.Serial(self.portname, 115200, timeout = 0, rtscts = 1) self.keyboard_fd = sys.stdin.fileno() self.serial_fd = self.port.fileno() self.terminal_defaults = termios.tcgetattr(self.keyboard_fd) def getkeypress(self): return os.read(self.keyboard_fd, 1) def getserialbyte(self): return self.port.read(1) def terminal_unbuffered(self): # put stdin into single-character mode new = termios.tcgetattr(self.keyboard_fd) new[3] = new[3] & ~termios.ICANON & ~termios.ECHO new[6][termios.VMIN] = 1 new[6][termios.VTIME] = 0 termios.tcsetattr(self.keyboard_fd, termios.TCSANOW, new) def terminal_restore(self): termios.tcsetattr(self.keyboard_fd, termios.TCSAFLUSH, self.terminal_defaults) def run(self): self.terminal_unbuffered() try: while True: iw, ow, ew = select.select([self.serial_fd, self.keyboard_fd], [], [], None) if self.keyboard_fd in iw: keypress = self.getkeypress() self.process_keypress(keypress) if self.serial_fd in iw: inbyte = self.getserialbyte() self.process_terminal(inbyte) finally: self.terminal_restore() def process_keypress(self, key): if key == '\n': key = '\r' elif key == '~': self.terminal_restore() self.do_menu() self.terminal_unbuffered() return # send nothing to the serial port else: key = key.upper() self.port.write(key) def process_terminal(self, byte): if byte == '\r': byte = '\n' sys.stdout.write(byte) sys.stdout.flush() def do_menu(self): sys.stdout.write(" --- \n") sys.stdout.write("[REPLICA1TERM] Enter Filename: ") sys.stdout.flush() filename = sys.stdin.readline().strip() try: datafile = open(filename, 'r') except Exception, e: sys.stdout.write("[REPLICA1TERM] Failed to open file: %s\n" % str(e)) sys.stdout.flush() return lines = list() for line in datafile.readlines(): line = line.strip() + '\r' lines.append(line) dataout = ''.join(lines) bytecount = len(dataout) start = time.time() while len(dataout): iw, ow, ew = select.select([self.serial_fd], [self.serial_fd], [], 1.0) if self.serial_fd in iw: inbyte = self.getserialbyte() self.process_terminal(inbyte) if self.serial_fd in ow: self.port.write(dataout[:10]) dataout = dataout[10:] taken = time.time() - start sys.stdout.write("[REPLICA1TERM] Upload completed, %.1f sec, %.1f chars/sec\n" % (taken, float(bytecount) / taken)) sys.stdout.flush() if len(sys.argv) == 1: print "Syntax: %s [port]" % sys.argv[0] print "eg: %s /dev/ttyUSB0" % sys.argv[0] else: print "Hit Ctrl+C to terminate" print "Hit ~ to initiate file upload" t = Replica1Terminal(sys.argv[1]) try: t.run() except KeyboardInterrupt: pass