/
main.go
125 lines (112 loc) · 2.7 KB
/
main.go
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
package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
"github.com/jacobsa/go-serial/serial"
"github.com/jessevdk/go-flags"
)
type Options struct {
// required
PortName string `short:"p" long:"port" description:"Serial Port"`
BaudRate uint `short:"b" long:"baud" description:"Baud Rate"`
// optional
DataBits uint `long:"data" description:"Number of Data Bits" default:"8"`
ParityMode string `long:"parity" description:"Parity Mode. none/even/odd" default:"none"`
StopBits uint `long:"stop" description:"Number of Stop Bits" default:"1"`
ListComPorts bool `short:"l" long:"list" description:"List COM Ports"`
TxBin bool `short:"y" long:"txbin" description:"Binary Send Mode"`
RxBin bool `short:"Y" long:"rxbin" description:"Binary Receive Mode"`
}
var opts Options
func main() {
_, err := flags.Parse(&opts)
if err != nil {
os.Exit(1)
}
if opts.ListComPorts {
listComPorts()
os.Exit(0)
}
if opts.PortName == "" || opts.BaudRate == 0 {
fmt.Fprintln(os.Stderr, "the required flags `/b, /baud' and `/p, /port' were not specified")
os.Exit(1)
}
var parityMode serial.ParityMode
switch opts.ParityMode {
case "none":
parityMode = serial.PARITY_NONE
case "odd":
parityMode = serial.PARITY_ODD
case "even":
parityMode = serial.PARITY_EVEN
default:
fmt.Fprintf(os.Stderr, "Invalid ParityMode: %s\n", opts.ParityMode)
fmt.Fprintf(os.Stderr, "`--parity` should be any one of none/odd/even\n")
os.Exit(1)
}
options := serial.OpenOptions{
PortName: opts.PortName,
BaudRate: opts.BaudRate,
DataBits: opts.DataBits,
ParityMode: parityMode,
StopBits: opts.StopBits,
}
port, err := serial.Open(options)
defer port.Close()
if err != nil {
log.Fatal(err)
}
go func() {
buf := make([]byte, 128)
for {
n, err := port.Read(buf)
if err != nil {
log.Fatal(err)
}
if opts.RxBin {
for i := 0; i < n; i++ {
fmt.Fprintf(os.Stdout, "0x%02X ", buf[i])
}
} else {
if n > 0 {
fmt.Fprintf(os.Stdout, "%s", buf[:n])
}
}
}
}()
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
var bytes []byte
if opts.TxBin {
if bytes, err = getBytes(scanner.Text()); err != nil {
log.Println(err)
}
} else {
bytes = []byte(scanner.Text())
}
if _, err := port.Write(bytes); err != nil {
log.Fatal(err)
}
}
}
func getBytes(src string) ([]byte, error) {
var result []byte
var err error
bytes := strings.FieldsFunc(src, func(r rune) bool { return r == ' ' })
var val int64
for i := range bytes {
val, err = strconv.ParseInt(bytes[i], 0, 0)
for {
result = append(result, byte(val&0xFF))
val = val >> 8
if val <= 0 {
break
}
}
}
return result, err
}