blob: fc6990cd7aea6f79006f6f984f257cc329e34e68 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
#!/usr/bin/env jimsh
# tip.tcl is like a simple version of cu, written in pure Jim Tcl
# It makes use of the new aio tty support
# Note: On Mac OS X, be sure to open /dev/cu.* devices, not /dev/tty.* devices
set USAGE \
{Usage: tip ?settings? device
or tip help
Where settings are as follows:
1|2 stop bits (default 1)
5|6|7|8 data bits (default 8)
even|odd parity (default none)
xonxoff|rtscts handshaking (default none)
<number> baud rate (default 115200)
e.g. tip 9600 8 1 rtscts /dev/ttyUSB0}
set settings {
baud 115200
stop 1
data 8
parity none
handshake none
input raw
output raw
vmin 1
vtime 1
}
set showhelp 0
foreach i $argv {
if {[string match -h* $i] || [string match help* $i]} {
puts $USAGE
return 0
}
if {$i in {even odd}} {
set settings(parity) $i
continue
}
if {$i in {ixonixoff rtscts}} {
set settings(handshake) $i
continue
}
if {$i in {1 2}} {
set settings(stop) $i
continue
}
if {$i in {5 6 7 8}} {
set settings(data) $i
continue
}
if {[string is integer -strict $i]} {
set settings(baud) $i
continue
}
if {[file exists $i]} {
set device $i
continue
}
puts "Warning: unrecognised setting $i"
}
if {![exists device]} {
puts $USAGE
exit 1
}
# save stdin and stdout tty settings
# note that stdin and stdout are probably the same file descriptor,
# but it doesn't hurt to treat them independently
set stdin_save [stdin tty]
set stdout_save [stdout tty]
try {
set f [open $device r+]
} on error msg {
puts "Failed to open $device"
return 1
}
if {[$f lock] == 0} {
puts "Device is in use: $device"
return 1
}
try {
$f tty {*}$settings
} on error msg {
puts "$device: $msg"
return 1
}
puts "\[$device\] Use ~. to exit"
$f ndelay 1
$f buffering none
stdin tty input raw
stdin ndelay 1
stdout tty output raw
stdout buffering none
set status ""
set tilde 0
proc bgerror {args} {
set status $args
incr ::done
}
# I/O loop
$f readable {
set c [$f read]
#stdout puts "<serial:$c([string bytelength $c]>"
#stdout flush
if {[$f eof]} {
set status "$device: disconnected"
incr done
}
stdout puts -nonewline $c
}
proc tilde_timeout {} {
global tilde f
if {$tilde} {
$f puts -nonewline ~
set tilde 0
}
}
stdin readable {
set c [stdin read]
# may receive more than one char here, but only need to consider
# ~. processing if we receive them as separate chars
if {$tilde == 0 && $c eq "~"} {
incr tilde
# Need ~. within 1 second of each other
after 1000 tilde_timeout
} else {
if {$tilde} {
after cancel tilde_timeout
set tilde 0
if {$c eq "."} {
incr done
return
}
$f puts -nonewline ~
}
$f puts -nonewline $c
}
}
vwait done
# restore previous settings
stdin tty {*}$stdin_save
stdout tty {*}$stdout_save
puts $status
|