From eaaa985fb1dcdd5db850a2e8d9d593ecc847b502 Mon Sep 17 00:00:00 2001 From: Karl Walters Date: Sun, 17 May 2015 01:21:13 -0400 Subject: [PATCH 1/3] Added DTR / RTS control functions for windows Added GetStatus so we can monitor status of CTS, DSR, RING, RLSD/CD, Should update this to return the status of each instead. --- serial_windows.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/serial_windows.go b/serial_windows.go index 3c747bc..32c1e6e 100644 --- a/serial_windows.go +++ b/serial_windows.go @@ -142,9 +142,12 @@ var ( nCreateEvent, nResetEvent, nPurgeComm, + nEscapeCommFunction, + nGetCommModemStatus, nFlushFileBuffers uintptr ) + func init() { k32, err := syscall.LoadLibrary("kernel32.dll") if err != nil { @@ -161,6 +164,53 @@ func init() { nResetEvent = getProcAddr(k32, "ResetEvent") nPurgeComm = getProcAddr(k32, "PurgeComm") nFlushFileBuffers = getProcAddr(k32, "FlushFileBuffers") + nEscapeCommFunction = getProcAddr(k32, "EscapeCommFunction") + nGetCommModemStatus = getProcAddr(k32, "GetCommModemStatus") +} + +func (p *Port) SetDtrOn() error { + const SETDTR = 0x0005 + + r, _, err := syscall.Syscall(nEscapeCommFunction, 2, uintptr(p.fd), SETDTR, 0) + if r == 0 { + return err + } + return nil +} +func (p *Port) SetDtrOff() error { + const CLRDTR = 0x0006 + r, _, err := syscall.Syscall(nEscapeCommFunction, 2, uintptr(p.fd), CLRDTR, 0) + if r == 0 { + return err + } + return nil +} + +func (p *Port) SetRtsOff() error { + const CLRRTS = 0x0004 + r, _, err := syscall.Syscall(nEscapeCommFunction, 2, uintptr(p.fd), CLRRTS, 0) + if r == 0 { + return err + } + return nil +} + +func (p *Port) SetRtsOn() error { + const SETRTS = 0x0003 + r, _, err := syscall.Syscall(nEscapeCommFunction, 2, uintptr(p.fd), SETRTS, 0) + if r == 0 { + return err + } + return nil +} + +func (p *Port) GetStatus() (error, byte) { + var statusval byte; + r, _, err := syscall.Syscall(nGetCommModemStatus, 2, uintptr(p.fd), uintptr(unsafe.Pointer(&statusval)), 0) + if r == 0 { + return err, 0x0 + } + return nil, statusval } func getProcAddr(lib syscall.Handle, name string) uintptr { From ffe5f56c94993eb75cd280c7448fb67b5d798022 Mon Sep 17 00:00:00 2001 From: Karl Walters Date: Sun, 17 May 2015 22:45:20 -0400 Subject: [PATCH 2/3] Updated GetCommModemStatus to return state of comport signals --- serial_windows.go | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/serial_windows.go b/serial_windows.go index 32c1e6e..a70636a 100644 --- a/serial_windows.go +++ b/serial_windows.go @@ -204,13 +204,40 @@ func (p *Port) SetRtsOn() error { return nil } -func (p *Port) GetStatus() (error, byte) { +func (p *Port) GetCommModemStatus() (err error, cts_on, dsr_on, ring_on, rlsd_on bool) { + + // The CTS (clear-to-send) signal is on. + const MS_CTS_ON = 0x0010 + // The DSR (data-set-ready) signal is on. + const MS_DSR_ON = 0x0020 + // The ring indicator signal is on. + const MS_RING_ON = 0x0040 + // The RLSD (receive-line-signal-detect) signal is on. + const MS_RLSD_ON = 0x0080 + var statusval byte; + + cts_on, dsr_on, ring_on, rlsd_on = false, false, false, false; + r, _, err := syscall.Syscall(nGetCommModemStatus, 2, uintptr(p.fd), uintptr(unsafe.Pointer(&statusval)), 0) if r == 0 { - return err, 0x0 + return err, cts_on, dsr_on, ring_on, rlsd_on } - return nil, statusval + + if statusval & MS_CTS_ON != 0 { + cts_on = true + } + if statusval & MS_DSR_ON != 0 { + dsr_on = true + } + if statusval & MS_RING_ON != 0 { + ring_on = true + } + if statusval & MS_RLSD_ON != 0 { + rlsd_on = true + } + + return nil, cts_on, dsr_on, ring_on, rlsd_on } func getProcAddr(lib syscall.Handle, name string) uintptr { From efdef1f1cff8af168ee489c8362d0a660c17b18a Mon Sep 17 00:00:00 2001 From: Karl Walters Date: Sun, 17 May 2015 23:03:27 -0400 Subject: [PATCH 3/3] Remember to use gofmt to correct spacing --- serial_windows.go | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/serial_windows.go b/serial_windows.go index a70636a..ff06d87 100644 --- a/serial_windows.go +++ b/serial_windows.go @@ -143,11 +143,10 @@ var ( nResetEvent, nPurgeComm, nEscapeCommFunction, - nGetCommModemStatus, + nGetCommModemStatus, nFlushFileBuffers uintptr ) - func init() { k32, err := syscall.LoadLibrary("kernel32.dll") if err != nil { @@ -206,36 +205,36 @@ func (p *Port) SetRtsOn() error { func (p *Port) GetCommModemStatus() (err error, cts_on, dsr_on, ring_on, rlsd_on bool) { - // The CTS (clear-to-send) signal is on. - const MS_CTS_ON = 0x0010 - // The DSR (data-set-ready) signal is on. - const MS_DSR_ON = 0x0020 - // The ring indicator signal is on. - const MS_RING_ON = 0x0040 - // The RLSD (receive-line-signal-detect) signal is on. - const MS_RLSD_ON = 0x0080 + // The CTS (clear-to-send) signal is on. + const MS_CTS_ON = 0x0010 + // The DSR (data-set-ready) signal is on. + const MS_DSR_ON = 0x0020 + // The ring indicator signal is on. + const MS_RING_ON = 0x0040 + // The RLSD (receive-line-signal-detect) signal is on. + const MS_RLSD_ON = 0x0080 - var statusval byte; + var statusval byte - cts_on, dsr_on, ring_on, rlsd_on = false, false, false, false; + cts_on, dsr_on, ring_on, rlsd_on = false, false, false, false r, _, err := syscall.Syscall(nGetCommModemStatus, 2, uintptr(p.fd), uintptr(unsafe.Pointer(&statusval)), 0) if r == 0 { return err, cts_on, dsr_on, ring_on, rlsd_on } - if statusval & MS_CTS_ON != 0 { - cts_on = true - } - if statusval & MS_DSR_ON != 0 { - dsr_on = true - } - if statusval & MS_RING_ON != 0 { - ring_on = true - } - if statusval & MS_RLSD_ON != 0 { - rlsd_on = true - } + if statusval&MS_CTS_ON != 0 { + cts_on = true + } + if statusval&MS_DSR_ON != 0 { + dsr_on = true + } + if statusval&MS_RING_ON != 0 { + ring_on = true + } + if statusval&MS_RLSD_ON != 0 { + rlsd_on = true + } return nil, cts_on, dsr_on, ring_on, rlsd_on }