Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add SendBreak method #110

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions serial_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,27 @@ func (p *Port) Flush() error {
return errno
}

// SendBreak sends a break (bus low value) for a given duration.
// In POSIX and linux implementations there are two cases for the duration value:
//
// if duration is zero there a break with at least 0.25 seconds
// but not more than 0.5 seconds will be send. If duration is not zero,
// than it's implementaion specific, which unit is used for duration.
// For more information tae a look at tcsendbreak(3) and ioctl_tty(2)
func (p *Port) SendBreak(d time.Duration) error {
_, _, errno := unix.Syscall(
unix.SYS_IOCTL,
uintptr(p.f.Fd()),
uintptr(unix.TCSBRK),
uintptr(d.Milliseconds()),
)

if errno == 0 {
return nil
}
return errno
}

func (p *Port) Close() (err error) {
return p.f.Close()
}
12 changes: 12 additions & 0 deletions serial_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,18 @@ func (p *Port) Flush() error {
return err
}

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

func (p *Port) Close() (err error) {
return p.f.Close()
}
29 changes: 29 additions & 0 deletions serial_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ func (p *Port) Flush() error {
return purgeComm(p.fd)
}

// SendBreak sends a break (bus low value) for a given duration.
// In POSIX and linux implementations the default behavior on zero duration
// is to send at least 0.25 seconds and not more than 0.5 seconds.
// To be compatible to linux and unix behavior we use 0.25 seconds
// as duration if a duration of zero is given.
func (p *Port) SendBreak(d time.Duration) error {
if d.Milliseconds() == 0 {
d = 250 * time.Millisecond
}
return sendCommBread(p.fd, d)
}

var (
nSetCommState,
nSetCommTimeouts,
Expand All @@ -142,6 +154,8 @@ var (
nCreateEvent,
nResetEvent,
nPurgeComm,
nSetCommBreak,
nClearCommBreak,
nFlushFileBuffers uintptr
)

Expand All @@ -160,6 +174,8 @@ func init() {
nCreateEvent = getProcAddr(k32, "CreateEventW")
nResetEvent = getProcAddr(k32, "ResetEvent")
nPurgeComm = getProcAddr(k32, "PurgeComm")
nSetCommBreak = getProcAddr(k32, "SetCommBreak")
nClearCommBreak = getProcAddr(k32, "ClearCommBreak")
nFlushFileBuffers = getProcAddr(k32, "FlushFileBuffers")
}

Expand Down Expand Up @@ -303,6 +319,19 @@ func purgeComm(h syscall.Handle) error {
return nil
}

func sendCommBreak(h syscall.Hande, d time.duration) error {
r, _, err := syscall.Syscall(nSetCommBreak, 1, uintptr(h), 0, 0)
if r == 0 {
return err
}
time.Sleep(d)
r, _, err = syscall.Syscall(nClearCommBreak, 1, uintptr(h), 0, 0)
if r == 0 {
return err
}
return nil
}

func newOverlapped() (*syscall.Overlapped, error) {
var overlapped syscall.Overlapped
r, _, err := syscall.Syscall6(nCreateEvent, 4, 0, 1, 0, 0, 0, 0)
Expand Down