aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/tarm/serial/serial_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tarm/serial/serial_windows.go')
-rw-r--r--vendor/github.com/tarm/serial/serial_windows.go327
1 files changed, 0 insertions, 327 deletions
diff --git a/vendor/github.com/tarm/serial/serial_windows.go b/vendor/github.com/tarm/serial/serial_windows.go
deleted file mode 100644
index 2a9c004..0000000
--- a/vendor/github.com/tarm/serial/serial_windows.go
+++ /dev/null
@@ -1,327 +0,0 @@
-// +build windows
-
-package serial
-
-import (
- "fmt"
- "os"
- "sync"
- "syscall"
- "time"
- "unsafe"
-)
-
-type Port struct {
- f *os.File
- fd syscall.Handle
- rl sync.Mutex
- wl sync.Mutex
- ro *syscall.Overlapped
- wo *syscall.Overlapped
-}
-
-type structDCB struct {
- DCBlength, BaudRate uint32
- flags [4]byte
- wReserved, XonLim, XoffLim uint16
- ByteSize, Parity, StopBits byte
- XonChar, XoffChar, ErrorChar, EofChar, EvtChar byte
- wReserved1 uint16
-}
-
-type structTimeouts struct {
- ReadIntervalTimeout uint32
- ReadTotalTimeoutMultiplier uint32
- ReadTotalTimeoutConstant uint32
- WriteTotalTimeoutMultiplier uint32
- WriteTotalTimeoutConstant uint32
-}
-
-func openPort(name string, baud int, databits byte, parity Parity, stopbits StopBits, readTimeout time.Duration) (p *Port, err error) {
- if len(name) > 0 && name[0] != '\\' {
- name = "\\\\.\\" + name
- }
-
- h, err := syscall.CreateFile(syscall.StringToUTF16Ptr(name),
- syscall.GENERIC_READ|syscall.GENERIC_WRITE,
- 0,
- nil,
- syscall.OPEN_EXISTING,
- syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED,
- 0)
- if err != nil {
- return nil, err
- }
- f := os.NewFile(uintptr(h), name)
- defer func() {
- if err != nil {
- f.Close()
- }
- }()
-
- if err = setCommState(h, baud, databits, parity, stopbits); err != nil {
- return nil, err
- }
- if err = setupComm(h, 64, 64); err != nil {
- return nil, err
- }
- if err = setCommTimeouts(h, readTimeout); err != nil {
- return nil, err
- }
- if err = setCommMask(h); err != nil {
- return nil, err
- }
-
- ro, err := newOverlapped()
- if err != nil {
- return nil, err
- }
- wo, err := newOverlapped()
- if err != nil {
- return nil, err
- }
- port := new(Port)
- port.f = f
- port.fd = h
- port.ro = ro
- port.wo = wo
-
- return port, nil
-}
-
-func (p *Port) Close() error {
- return p.f.Close()
-}
-
-func (p *Port) Write(buf []byte) (int, error) {
- p.wl.Lock()
- defer p.wl.Unlock()
-
- if err := resetEvent(p.wo.HEvent); err != nil {
- return 0, err
- }
- var n uint32
- err := syscall.WriteFile(p.fd, buf, &n, p.wo)
- if err != nil && err != syscall.ERROR_IO_PENDING {
- return int(n), err
- }
- return getOverlappedResult(p.fd, p.wo)
-}
-
-func (p *Port) Read(buf []byte) (int, error) {
- if p == nil || p.f == nil {
- return 0, fmt.Errorf("Invalid port on read")
- }
-
- p.rl.Lock()
- defer p.rl.Unlock()
-
- if err := resetEvent(p.ro.HEvent); err != nil {
- return 0, err
- }
- var done uint32
- err := syscall.ReadFile(p.fd, buf, &done, p.ro)
- if err != nil && err != syscall.ERROR_IO_PENDING {
- return int(done), err
- }
- return getOverlappedResult(p.fd, p.ro)
-}
-
-// Discards data written to the port but not transmitted,
-// or data received but not read
-func (p *Port) Flush() error {
- return purgeComm(p.fd)
-}
-
-var (
- nSetCommState,
- nSetCommTimeouts,
- nSetCommMask,
- nSetupComm,
- nGetOverlappedResult,
- nCreateEvent,
- nResetEvent,
- nPurgeComm,
- nFlushFileBuffers uintptr
-)
-
-func init() {
- k32, err := syscall.LoadLibrary("kernel32.dll")
- if err != nil {
- panic("LoadLibrary " + err.Error())
- }
- defer syscall.FreeLibrary(k32)
-
- nSetCommState = getProcAddr(k32, "SetCommState")
- nSetCommTimeouts = getProcAddr(k32, "SetCommTimeouts")
- nSetCommMask = getProcAddr(k32, "SetCommMask")
- nSetupComm = getProcAddr(k32, "SetupComm")
- nGetOverlappedResult = getProcAddr(k32, "GetOverlappedResult")
- nCreateEvent = getProcAddr(k32, "CreateEventW")
- nResetEvent = getProcAddr(k32, "ResetEvent")
- nPurgeComm = getProcAddr(k32, "PurgeComm")
- nFlushFileBuffers = getProcAddr(k32, "FlushFileBuffers")
-}
-
-func getProcAddr(lib syscall.Handle, name string) uintptr {
- addr, err := syscall.GetProcAddress(lib, name)
- if err != nil {
- panic(name + " " + err.Error())
- }
- return addr
-}
-
-func setCommState(h syscall.Handle, baud int, databits byte, parity Parity, stopbits StopBits) error {
- var params structDCB
- params.DCBlength = uint32(unsafe.Sizeof(params))
-
- params.flags[0] = 0x01 // fBinary
- params.flags[0] |= 0x10 // Assert DSR
-
- params.BaudRate = uint32(baud)
-
- params.ByteSize = databits
-
- switch parity {
- case ParityNone:
- params.Parity = 0
- case ParityOdd:
- params.Parity = 1
- case ParityEven:
- params.Parity = 2
- case ParityMark:
- params.Parity = 3
- case ParitySpace:
- params.Parity = 4
- default:
- return ErrBadParity
- }
-
- switch stopbits {
- case Stop1:
- params.StopBits = 0
- case Stop1Half:
- params.StopBits = 1
- case Stop2:
- params.StopBits = 2
- default:
- return ErrBadStopBits
- }
-
- r, _, err := syscall.Syscall(nSetCommState, 2, uintptr(h), uintptr(unsafe.Pointer(&params)), 0)
- if r == 0 {
- return err
- }
- return nil
-}
-
-func setCommTimeouts(h syscall.Handle, readTimeout time.Duration) error {
- var timeouts structTimeouts
- const MAXDWORD = 1<<32 - 1
-
- // blocking read by default
- var timeoutMs int64 = MAXDWORD - 1
-
- if readTimeout > 0 {
- // non-blocking read
- timeoutMs = readTimeout.Nanoseconds() / 1e6
- if timeoutMs < 1 {
- timeoutMs = 1
- } else if timeoutMs > MAXDWORD-1 {
- timeoutMs = MAXDWORD - 1
- }
- }
-
- /* From http://msdn.microsoft.com/en-us/library/aa363190(v=VS.85).aspx
-
- For blocking I/O see below:
-
- Remarks:
-
- If an application sets ReadIntervalTimeout and
- ReadTotalTimeoutMultiplier to MAXDWORD and sets
- ReadTotalTimeoutConstant to a value greater than zero and
- less than MAXDWORD, one of the following occurs when the
- ReadFile function is called:
-
- If there are any bytes in the input buffer, ReadFile returns
- immediately with the bytes in the buffer.
-
- If there are no bytes in the input buffer, ReadFile waits
- until a byte arrives and then returns immediately.
-
- If no bytes arrive within the time specified by
- ReadTotalTimeoutConstant, ReadFile times out.
- */
-
- timeouts.ReadIntervalTimeout = MAXDWORD
- timeouts.ReadTotalTimeoutMultiplier = MAXDWORD
- timeouts.ReadTotalTimeoutConstant = uint32(timeoutMs)
-
- r, _, err := syscall.Syscall(nSetCommTimeouts, 2, uintptr(h), uintptr(unsafe.Pointer(&timeouts)), 0)
- if r == 0 {
- return err
- }
- return nil
-}
-
-func setupComm(h syscall.Handle, in, out int) error {
- r, _, err := syscall.Syscall(nSetupComm, 3, uintptr(h), uintptr(in), uintptr(out))
- if r == 0 {
- return err
- }
- return nil
-}
-
-func setCommMask(h syscall.Handle) error {
- const EV_RXCHAR = 0x0001
- r, _, err := syscall.Syscall(nSetCommMask, 2, uintptr(h), EV_RXCHAR, 0)
- if r == 0 {
- return err
- }
- return nil
-}
-
-func resetEvent(h syscall.Handle) error {
- r, _, err := syscall.Syscall(nResetEvent, 1, uintptr(h), 0, 0)
- if r == 0 {
- return err
- }
- return nil
-}
-
-func purgeComm(h syscall.Handle) error {
- const PURGE_TXABORT = 0x0001
- const PURGE_RXABORT = 0x0002
- const PURGE_TXCLEAR = 0x0004
- const PURGE_RXCLEAR = 0x0008
- r, _, err := syscall.Syscall(nPurgeComm, 2, uintptr(h),
- PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR, 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)
- if r == 0 {
- return nil, err
- }
- overlapped.HEvent = syscall.Handle(r)
- return &overlapped, nil
-}
-
-func getOverlappedResult(h syscall.Handle, overlapped *syscall.Overlapped) (int, error) {
- var n int
- r, _, err := syscall.Syscall6(nGetOverlappedResult, 4,
- uintptr(h),
- uintptr(unsafe.Pointer(overlapped)),
- uintptr(unsafe.Pointer(&n)), 1, 0, 0)
- if r == 0 {
- return n, err
- }
-
- return n, nil
-}