Skip to content

Commit

Permalink
Add break support by JulianJacobi from tarm#110
Browse files Browse the repository at this point in the history
  • Loading branch information
wwijkander committed Jan 3, 2023
1 parent 98f6abe commit 869acb1
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
4 changes: 0 additions & 4 deletions serial.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,3 @@ func posixTimeoutValues(readTimeout time.Duration) (vmin uint8, vtime uint8) {
}
return minBytesToRead, uint8(readTimeoutInDeci)
}

// func SendBreak()

// func RegisterBreakHandler(func())
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

0 comments on commit 869acb1

Please sign in to comment.