-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvisa.go
More file actions
155 lines (134 loc) · 3.92 KB
/
visa.go
File metadata and controls
155 lines (134 loc) · 3.92 KB
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
// Copyright (c) 2017-2026 The asrl developers. All rights reserved.
// Project site: https://github.com/gotmc/asrl
// Use of this source code is governed by a MIT-style license that
// can be found in the LICENSE.txt file for the project.
package asrl
import (
"errors"
"fmt"
"regexp"
"strconv"
"go.bug.st/serial"
)
// Sentinel errors returned by NewVisaResource.
var (
ErrInvalidResource = errors.New("visa: invalid VISA resource string")
ErrInvalidInterfaceType = errors.New("visa: interface type was not ASRL")
ErrInvalidResourceClass = errors.New("visa: resource class was not INSTR")
ErrInvalidBaud = errors.New("visa: invalid baud")
ErrUnsupportedDataflow = errors.New("visa: unsupported dataflow")
)
var visaResourceRE = regexp.MustCompile(
`^(?P<interfaceType>ASRL)(?P<boardIndex>\d*)::` +
`(?P<address>[^\s]+)::` +
`(?P<baud>\d+)::` +
`(?P<dataflow>\d{1}\w{1}\d{1})::` +
`(?P<resourceClass>INSTR)$`,
)
// VisaResource represents a VISA enabled piece of test equipment.
type VisaResource struct {
resourceString string
interfaceType string
address string
baud int
dataBits int
parity serial.Parity
stopBits serial.StopBits
resourceClass string
}
// NewVisaResource creates a new VisaResource using the given VISA
// resourceString. If the dataflow isn't provided as part of the VISA resource
// string, the dataflow will default to 8N1.
func NewVisaResource(resourceString string) (*VisaResource, error) {
res := visaResourceRE.FindStringSubmatch(resourceString)
if res == nil {
return nil, ErrInvalidResource
}
subexpNames := visaResourceRE.SubexpNames()
matchMap := map[string]string{}
for i, n := range res {
matchMap[subexpNames[i]] = n
}
if matchMap["interfaceType"] != "ASRL" {
return nil, ErrInvalidInterfaceType
}
if matchMap["resourceClass"] != "INSTR" {
return nil, ErrInvalidResourceClass
}
visa := &VisaResource{
resourceString: resourceString,
interfaceType: "ASRL",
resourceClass: "INSTR",
address: matchMap["address"],
}
if matchMap["baud"] != "" {
baud, err := strconv.Atoi(matchMap["baud"])
if err != nil {
return nil, fmt.Errorf("%w %q: %w", ErrInvalidBaud, matchMap["baud"], err)
}
visa.baud = baud
}
if matchMap["dataflow"] != "" {
switch matchMap["dataflow"] {
case "8N1":
visa.dataBits = 8
visa.parity = serial.NoParity
visa.stopBits = serial.OneStopBit
case "8N2":
visa.dataBits = 8
visa.parity = serial.NoParity
visa.stopBits = serial.TwoStopBits
case "7E2":
visa.dataBits = 7
visa.parity = serial.EvenParity
visa.stopBits = serial.TwoStopBits
case "7E1":
visa.dataBits = 7
visa.parity = serial.EvenParity
visa.stopBits = serial.OneStopBit
case "7O1":
visa.dataBits = 7
visa.parity = serial.OddParity
visa.stopBits = serial.OneStopBit
default:
return nil, fmt.Errorf("%w %q", ErrUnsupportedDataflow, matchMap["dataflow"])
}
} else {
visa.dataBits = 8
visa.parity = serial.NoParity
visa.stopBits = serial.OneStopBit
}
return visa, nil
}
// String returns the original VISA resource string.
func (v *VisaResource) String() string {
return v.resourceString
}
// InterfaceType returns the VISA interface type (e.g., "ASRL").
func (v *VisaResource) InterfaceType() string {
return v.interfaceType
}
// Address returns the serial port address.
func (v *VisaResource) Address() string {
return v.address
}
// Baud returns the baud rate.
func (v *VisaResource) Baud() int {
return v.baud
}
// DataBits returns the number of data bits.
func (v *VisaResource) DataBits() int {
return v.dataBits
}
// Parity returns the parity setting.
func (v *VisaResource) Parity() serial.Parity {
return v.parity
}
// StopBits returns the stop bits setting.
func (v *VisaResource) StopBits() serial.StopBits {
return v.stopBits
}
// ResourceClass returns the VISA resource class (e.g., "INSTR").
func (v *VisaResource) ResourceClass() string {
return v.resourceClass
}