blob: 829a4540f159274fa8164eec3cf91f34863b8860 [file] [log] [blame]
cliechti576de252002-02-28 23:54:44 +00001#!/usr/bin/env python
2
3#very simple serial terminal
4#input characters are sent directly, received characters are displays as is
5#baudrate and echo configuartion is done through globals:
cliechti576de252002-02-28 23:54:44 +00006
7
cliechti8b3ad392002-03-03 20:12:21 +00008import sys, os, serial, threading, getopt
9#EXITCHARCTER = '\x1b' #ESC
10EXITCHARCTER = '\x04' #ctrl+d
cliechti576de252002-02-28 23:54:44 +000011
12#first choosea platform dependant way to read single characters from the console
13if os.name == 'nt': #sys.platform == 'win32':
14 import msvcrt
15 def getkey():
16 while 1:
17 if echo:
18 z = msvcrt.getche()
19 else:
20 z = msvcrt.getch()
21 if z == '\0' or z == '\xe0': #functions keys
22 msvcrt.getch()
23 else:
24 return z
25
26elif os.name == 'posix':
27 #XXX: Untested code drrived from the Python FAQ....
28 import termios, TERMIOS, sys, os
29 fd = sys.stdin.fileno()
30 old = termios.tcgetattr(fd)
31 new = termios.tcgetattr(fd)
32 new[3] = new[3] & ~TERMIOS.ICANON & ~TERMIOS.ECHO
33 new[6][TERMIOS.VMIN] = 1
34 new[6][TERMIOS.VTIME] = 0
35 termios.tcsetattr(fd, TERMIOS.TCSANOW, new)
36 s = '' # We'll save the characters typed and add them to the pool.
37 def getkey():
38 c = os.read(fd, 1)
39 if echo: sys.stdout.write(c)
40 return c
41 def clenaup_console():
42 termios.tcsetattr(fd, TERMIOS.TCSAFLUSH, old)
43 sys.exitfunc = clenaup_console #terminal modes have to be restored on exit...
44
45else:
46 raise "Sorry no implementation for your platform (%s) available." % sys.platform
47
48
cliechti576de252002-02-28 23:54:44 +000049def reader():
50 """loop forever and copy serial->console"""
51 while 1:
52 sys.stdout.write(s.read())
53
54def writer():
55 """loop forever and copy console->serial"""
56 while 1:
57 c = getkey()
cliechti8b3ad392002-03-03 20:12:21 +000058 if c == EXITCHARCTER: break #exit on esc
cliechti576de252002-02-28 23:54:44 +000059 s.write(c) #send character
60 if convert_outgoing_cr and c == '\r':
61 s.write('\n')
62 if echo: sys.stdout.write('\n')
63
cliechti576de252002-02-28 23:54:44 +000064
cliechti8b3ad392002-03-03 20:12:21 +000065#print a short help message
66def usage():
67 print >>sys.stderr, """USAGE: %s [options]
68 Simple Terminal Programm for the serial port.
69
70 options:
71 -p, --port=PORT: port, a number, defualt = 0 or a device name
72 -b, --baud=BAUD: baudrate, default 9600
73 -r, --rtscts: enable RTS/CTS flow control (default off)
74 -x, --xonxoff: enable software flow control (default off)
75 -e, --echo: enable local echo (default off)
76 -c, --cr: disable CR -> CR+LF translation
77
78 """ % sys.argv[0]
79
80if __name__ == '__main__':
81 #parse command line options
82 try:
83 opts, args = getopt.getopt(sys.argv[1:],
84 "hp:b:rxec",
85 ["help", "port=", "baud=", "rtscts", "xonxoff", "echo", "cr"])
86 except getopt.GetoptError:
87 # print help information and exit:
88 usage()
89 sys.exit(2)
90
91 port = 0
92 baudrate = 9600
93 echo = 0
94 convert_outgoing_cr = 1
95 rtscts = 0
96 xonxoff = 0
97 for o, a in opts:
98 if o in ("-h", "--help"): #help text
99 usage()
100 sys.exit()
101 elif o in ("-p", "--port"): #specified port
102 try:
103 port = int(a)
104 except ValueError:
105 port = a
106 elif o in ("-b", "--baud"): #specified baudrate
107 try:
108 baudrate = int(a)
109 except ValueError:
110 raise ValueError, "Baudrate must be a integer number"
111 elif o in ("-r", "--rtscts"):
112 rtscts = 1
113 elif o in ("-x", "--xonxoff"):
114 xonxoff = 1
115 elif o in ("-e", "--echo"):
116 echo = 1
117 elif o in ("-c", "--cr"):
118 convert_outgoing_cr = 0
119
120 try:
121 s = serial.Serial(port, baudrate, rtscts=rtscts, xonxoff=xonxoff)
122 except:
123 print "could not open port"
124 sys.exit(1)
125 print "--- Miniterm --- type Ctrl-D to quit"
126 #start serial->console thread
127 r = threading.Thread(target=reader)
128 r.setDaemon(1)
129 r.start()
130 #enter console->serial loop
131 writer()
132
133 print "\n--- exit ---"