-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathhandler.go
153 lines (129 loc) · 3.91 KB
/
handler.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
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
package scpi
import (
"context"
"fmt"
"regexp"
"strconv"
"time"
)
// Handler is a handler for a device controlled using SCPI commands.
type Handler struct {
Client
}
// NewHandler returns a new handler for a device controlled using SCPI commands.
func NewHandler(client Client) *Handler {
return &Handler{
Client: client,
}
}
// Reset resets the instrument to a factory pre-defined condition and clears the error log.
func (h *Handler) Reset() error {
return h.BulkExec("*RST", "CLS")
}
// WaitForComplete waits for all queued operations to complete up to the specified timeout.
func (h *Handler) WaitForComplete(ctx context.Context, timeout time.Duration) error {
subCtx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
ch := make(chan error, 1)
go func() {
_, err := h.QueryContext(subCtx, "*WAI;*OPC?")
ch <- err
}()
select {
case err := <-ch:
return err
case <-subCtx.Done():
// TODO(scizorman): Refactor the error
return subCtx.Err()
}
}
// Trigger triggers the device if, and only if,
// Bus Triggering is the type of trigger event selected.
// Otherwise, this command is ignored.
func (h *Handler) Trigger(ctx context.Context) error {
return h.ExecContext(ctx, "*TRG")
}
// Identify returns the identification data.
//
// The standards order is follows:
// Manufacturer
// Model number
// Serial number (or 0)
// Firmware version
func (h *Handler) Identify(ctx context.Context) (id string, err error) {
res, err := h.QueryContext(ctx, "*IDN?")
if err != nil {
return "", nil
}
id = string(res)
return id, nil
}
// SetEventStatusEnable sets the value in the enable register for the Standard Event Status group.
// The selected bits are then reported to bit 5 of the Status Byte.
func (h *Handler) SetEventStatusEnable(ctx context.Context, bit uint8) error {
cmd := fmt.Sprintf("*ESE %d", bit)
return h.Exec(cmd)
}
// QueryEventStatusEnable queries the event status enable.
func (h *Handler) QueryEventStatusEnable(ctx context.Context) (bit uint8, err error) {
res, err := h.QueryContext(ctx, "*ESE?")
if err != nil {
return 0, err
}
return parseBit(res)
}
// QueryEventStatusRegister queries the event status register.
// The register is cleared when it is executed.
func (h *Handler) QueryEventStatusRegister(ctx context.Context) (bit uint8, err error) {
res, err := h.QueryContext(ctx, "*ESR?")
if err != nil {
return 0, err
}
return parseBit(res)
}
// SetServiceRequestEnable sets the value of the Service Request Enable register.
func (h *Handler) SetServiceRequestEnable(ctx context.Context, bit uint8) error {
cmd := fmt.Sprintf("*SRE %d", bit)
return h.ExecContext(ctx, cmd)
}
// QueryServiceRequestEnable queries the Service Request Enable.
func (h *Handler) QueryServiceRequestEnable(ctx context.Context) (bit uint8, err error) {
res, err := h.QueryContext(ctx, "*SRE?")
if err != nil {
return 0, err
}
return parseBit(res)
}
// QueryStatusByteRegister queries the Status Byte Register.
func (h *Handler) QueryStatusByteRegister(ctx context.Context) (bit uint8, err error) {
res, err := h.QueryContext(ctx, "*STB?")
if err != nil {
return 0, err
}
return parseBit(res)
}
// Recall restored the instrument to a state that was previously stored
// in locations 0 through 9 with the Save.
func (h *Handler) Recall(ctx context.Context, mem uint8) error {
cmd := fmt.Sprintf("*RCL %d", mem)
return h.ExecContext(ctx, cmd)
}
// Save saves the instrument setting to one of the ten non-volatile memory locations.
func (h *Handler) Save(ctx context.Context, mem uint8) error {
cmd := fmt.Sprintf("*SAV %d", mem)
return h.ExecContext(ctx, cmd)
}
var bitRegexp = regexp.MustCompile(`\+(\d+)`)
func parseBit(s string) (bit uint8, err error) {
re := bitRegexp.Copy()
g := re.FindStringSubmatch(s)
if g == nil {
return 0, fmt.Errorf("invalid bit format: %s", s)
}
n, err := strconv.ParseUint(g[1], 10, 8)
if err != nil {
return 0, err
}
bit = uint8(n)
return bit, nil
}