Skip to content

Commit 869acb1

Browse files
committed
Add break support by JulianJacobi from tarm#110
1 parent 98f6abe commit 869acb1

File tree

4 files changed

+62
-4
lines changed

4 files changed

+62
-4
lines changed

serial.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,3 @@ func posixTimeoutValues(readTimeout time.Duration) (vmin uint8, vtime uint8) {
161161
}
162162
return minBytesToRead, uint8(readTimeoutInDeci)
163163
}
164-
165-
// func SendBreak()
166-
167-
// func RegisterBreakHandler(func())

serial_linux.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,27 @@ func (p *Port) Flush() error {
159159
return errno
160160
}
161161

162+
// SendBreak sends a break (bus low value) for a given duration.
163+
// In POSIX and linux implementations there are two cases for the duration value:
164+
//
165+
// if duration is zero there a break with at least 0.25 seconds
166+
// but not more than 0.5 seconds will be send. If duration is not zero,
167+
// than it's implementaion specific, which unit is used for duration.
168+
// For more information tae a look at tcsendbreak(3) and ioctl_tty(2)
169+
func (p *Port) SendBreak(d time.Duration) error {
170+
_, _, errno := unix.Syscall(
171+
unix.SYS_IOCTL,
172+
uintptr(p.f.Fd()),
173+
uintptr(unix.TCSBRK),
174+
uintptr(d.Milliseconds()),
175+
)
176+
177+
if errno == 0 {
178+
return nil
179+
}
180+
return errno
181+
}
182+
162183
func (p *Port) Close() (err error) {
163184
return p.f.Close()
164185
}

serial_posix.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,18 @@ func (p *Port) Flush() error {
192192
return err
193193
}
194194

195+
// SendBreak sends a break (bus low value) for a given duration.
196+
// In POSIX and linux implementations there are two cases for the duration value:
197+
//
198+
// if duration is zero there a break with at least 0.25 seconds
199+
// but not more than 0.5 seconds will be send. If duration is not zero,
200+
// than it's implementaion specific, which unit is used for duration.
201+
// For more information tae a look at tcsendbreak(3) and ioctl_tty(2)
202+
func (p *Port) SendBreak(d time.Duration) error {
203+
_, err := C.tcsendbreak(C.int(p.f.Fd()), C.int(d.Milliseconds()))
204+
return err
205+
}
206+
195207
func (p *Port) Close() (err error) {
196208
return p.f.Close()
197209
}

serial_windows.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,18 @@ func (p *Port) Flush() error {
133133
return purgeComm(p.fd)
134134
}
135135

136+
// SendBreak sends a break (bus low value) for a given duration.
137+
// In POSIX and linux implementations the default behavior on zero duration
138+
// is to send at least 0.25 seconds and not more than 0.5 seconds.
139+
// To be compatible to linux and unix behavior we use 0.25 seconds
140+
// as duration if a duration of zero is given.
141+
func (p *Port) SendBreak(d time.Duration) error {
142+
if d.Milliseconds() == 0 {
143+
d = 250 * time.Millisecond
144+
}
145+
return sendCommBread(p.fd, d)
146+
}
147+
136148
var (
137149
nSetCommState,
138150
nSetCommTimeouts,
@@ -142,6 +154,8 @@ var (
142154
nCreateEvent,
143155
nResetEvent,
144156
nPurgeComm,
157+
nSetCommBreak,
158+
nClearCommBreak,
145159
nFlushFileBuffers uintptr
146160
)
147161

@@ -160,6 +174,8 @@ func init() {
160174
nCreateEvent = getProcAddr(k32, "CreateEventW")
161175
nResetEvent = getProcAddr(k32, "ResetEvent")
162176
nPurgeComm = getProcAddr(k32, "PurgeComm")
177+
nSetCommBreak = getProcAddr(k32, "SetCommBreak")
178+
nClearCommBreak = getProcAddr(k32, "ClearCommBreak")
163179
nFlushFileBuffers = getProcAddr(k32, "FlushFileBuffers")
164180
}
165181

@@ -303,6 +319,19 @@ func purgeComm(h syscall.Handle) error {
303319
return nil
304320
}
305321

322+
func sendCommBreak(h syscall.Hande, d time.duration) error {
323+
r, _, err := syscall.Syscall(nSetCommBreak, 1, uintptr(h), 0, 0)
324+
if r == 0 {
325+
return err
326+
}
327+
time.Sleep(d)
328+
r, _, err = syscall.Syscall(nClearCommBreak, 1, uintptr(h), 0, 0)
329+
if r == 0 {
330+
return err
331+
}
332+
return nil
333+
}
334+
306335
func newOverlapped() (*syscall.Overlapped, error) {
307336
var overlapped syscall.Overlapped
308337
r, _, err := syscall.Syscall6(nCreateEvent, 4, 0, 1, 0, 0, 0, 0)

0 commit comments

Comments
 (0)