Skip to content

Commit

Permalink
Working nicely on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Tarmigan Casebolt committed Apr 10, 2011
1 parent 0835de4 commit 1709d02
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 14 deletions.
4 changes: 4 additions & 0 deletions serial.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include <windows.h>
static void NullifyParams(struct _DCB *params) {
/* LPCTSTR str = "baud=115200 parity=N data=8 stop=1";
BuildCommDCB(str,params);
*/
params->fBinary = TRUE;
params->fNull = FALSE;
params->fErrorChar = FALSE;
Expand Down
3 changes: 2 additions & 1 deletion serial_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "C"

import (
"os"
"io"
"fmt"
"syscall"
//"unsafe"
Expand All @@ -19,7 +20,7 @@ func (e SError) String() string {
return e.msg
}

func OpenPort(name string, baud int) (f *os.File, err os.Error) {
func OpenPort(name string, baud int) (f io.ReadWriteCloser, err os.Error) {
f, err = os.Open(name, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK, 0666)
if err != nil {
return
Expand Down
74 changes: 61 additions & 13 deletions serial_windows.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package serial

// #include <windows.h>
// #include "serial.h"
import "C"
import (
"os"
"io"
"fmt"
"unsafe"
)

func OpenPort(name string, baud int) (*os.File, os.Error) {
type serialPort struct {
f *os.File
}

const EV_RXCHAR = 0x0001

func OpenPort(name string, baud int) (io.ReadWriteCloser, os.Error) {
f, err := os.Open(name, os.O_RDWR|os.O_NDELAY, 0666)
if err != nil {
return nil, err
Expand All @@ -21,18 +27,16 @@ func OpenPort(name string, baud int) (*os.File, os.Error) {
handle = hp(unsafe.Pointer(&fd))
var params C.struct__DCB
params.DCBlength = C.DWORD(unsafe.Sizeof(params))
/*if ok, err := C.GetCommState(*handle, &params); ok == C.FALSE {
f.Close()
return nil, err
}
*/

params.XonLim = 0
params.XoffLim = 0

params.BaudRate = C.DWORD(baud)
params.ByteSize = 8
params.StopBits = C.ONESTOPBIT
params.Parity = C.NOPARITY
C.NullifyParams(&params)
params.Parity = C.NOPARITY

fmt.Println(params)
//fmt.Printf("%#v %v\n", params, params)

if ok, err := C.SetCommState(*handle, &params); ok == C.FALSE {
f.Close()
Expand All @@ -46,12 +50,56 @@ func OpenPort(name string, baud int) (*os.File, os.Error) {
}

var timeouts C.struct__COMMTIMEOUTS
timeouts.ReadIntervalTimeout = 1
const DWORDMAX = 1<<32 - 1
timeouts.ReadIntervalTimeout = DWORDMAX
timeouts.ReadTotalTimeoutConstant = 0
if ok, err := C.SetCommTimeouts(*handle, &timeouts); ok == C.FALSE {
f.Close()
return nil, err
}
fmt.Println(timeouts)
//fmt.Printf("%#v\n", timeouts)

if ok, err := C.SetCommMask(*handle, EV_RXCHAR); ok == C.FALSE {
f.Close()
return nil, err
}

port := serialPort{f}

return &port, nil
}

func (p *serialPort) Close() os.Error {
return p.f.Close()
}

func (p *serialPort) Write(buf []byte) (int, os.Error) {
return p.f.Write(buf)
}

func (p *serialPort) Read(buf []byte) (int, os.Error) {
type hp *C.HANDLE
var handle *C.HANDLE
fd := p.f.Fd()
handle = hp(unsafe.Pointer(&fd))

var events C.DWORD
var overlapped *C.struct__OVERLAPPED

loop:
if ok, err := C.WaitCommEvent(*handle, &events, overlapped); ok == C.FALSE {
fmt.Printf("%v, 0x%04x\n", err, events)
return 0, err
}
// There is a small race window here between returning from WaitCommEvent and reading from the file.
// If we receive data in this window, we will read that data, but the RXFLAG will still be set
// and next time the WaitCommEvent() will return but we will have already read the data. That's
// why we have the stupid goto loop on EOF.
n, err := p.f.Read(buf)
if err == os.EOF && n == 0 {
//fmt.Printf("%v, %v, %v, 0x%04x\n", err, n, len(buf), events)
goto loop
}

return f, nil
return n, err
}

0 comments on commit 1709d02

Please sign in to comment.