Added first draft of documentation
This commit is contained in:
85
doc.go
Normal file
85
doc.go
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2014 Cristian Maglie. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
//
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is a cross-platform serial library for go.
|
||||||
|
|
||||||
|
The canonical import for this library is go.bug.st/serial so the import line
|
||||||
|
is the following:
|
||||||
|
|
||||||
|
import "go.bug.st/serial"
|
||||||
|
|
||||||
|
It is possibile to get the list of available serial ports with the
|
||||||
|
GetPortsList function:
|
||||||
|
|
||||||
|
ports, err := serial.GetPortsList()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(ports) == 0 {
|
||||||
|
log.Fatal("No serial ports found!")
|
||||||
|
}
|
||||||
|
for _, port := range ports {
|
||||||
|
fmt.Printf("Found port: %v\n", port)
|
||||||
|
}
|
||||||
|
|
||||||
|
The serial port can be opened with the OpenPort function:
|
||||||
|
|
||||||
|
mode := &serial.Mode{
|
||||||
|
BaudRate: 115200,
|
||||||
|
}
|
||||||
|
port, err := serial.OpenPort("/dev/ttyUSB0", mode)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
The OpenPort command needs a "mode" parameter that specifies the configuration
|
||||||
|
options for the serial port. If not specified the default options are 9600_N81,
|
||||||
|
in the example above only the speed is changed so the port is opened using 115200_N81.
|
||||||
|
The following snippets shows how to declare a configuration for 57600_E71:
|
||||||
|
|
||||||
|
mode := &serial.Mode{
|
||||||
|
BaudRate: 57600,
|
||||||
|
Parity: serial.PARITY_EVEN,
|
||||||
|
DataBits: 7,
|
||||||
|
StopBits: serial.STOPBITS_ONE,
|
||||||
|
}
|
||||||
|
|
||||||
|
The configuration can be changed at any time with the SetMode function:
|
||||||
|
|
||||||
|
err := port.SetMode(mode)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
The port object implements the io.ReadWriteCloser interface, so we can use
|
||||||
|
the usual Read, Write and Close functions to send and receive data from the
|
||||||
|
serial port:
|
||||||
|
|
||||||
|
n, err := port.Write([]byte("10,20,30\n\r"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Sent %v bytes\n", n)
|
||||||
|
|
||||||
|
buff := make([]byte, 100)
|
||||||
|
for {
|
||||||
|
n, err := port.Read(buff)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
fmt.Println("\nEOF")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fmt.Printf("%v", string(buff[:n]))
|
||||||
|
}
|
||||||
|
|
||||||
|
This library doesn't make use of cgo and "C" package, so it's a pure go library
|
||||||
|
that can be easily cross compiled.
|
||||||
|
*/
|
||||||
|
package serial // import "go.bug.st/serial"
|
||||||
35
serial.go
35
serial.go
@@ -6,39 +6,30 @@
|
|||||||
|
|
||||||
package serial // import "go.bug.st/serial"
|
package serial // import "go.bug.st/serial"
|
||||||
|
|
||||||
import "io"
|
// This structure describes a serial port configuration.
|
||||||
|
|
||||||
// SerialPort object
|
|
||||||
type SerialPort interface {
|
|
||||||
io.ReadWriteCloser
|
|
||||||
|
|
||||||
// Set all parameters together
|
|
||||||
SetMode(mode *Mode) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type Mode struct {
|
type Mode struct {
|
||||||
BaudRate int
|
BaudRate int // The serial port bitrate (aka Baudrate)
|
||||||
DataBits int
|
DataBits int // Size of the character (must be 5, 6, 7 or 8)
|
||||||
Parity Parity
|
Parity Parity // Parity (see Parity type for more info)
|
||||||
StopBits StopBits
|
StopBits StopBits // Stop bits (see StopBits type for more info)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Parity int
|
type Parity int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PARITY_NONE Parity = iota
|
PARITY_NONE Parity = iota // No parity (default)
|
||||||
PARITY_ODD
|
PARITY_ODD // Odd parity
|
||||||
PARITY_EVEN
|
PARITY_EVEN // Even parity
|
||||||
PARITY_MARK
|
PARITY_MARK // Mark parity (always 1)
|
||||||
PARITY_SPACE
|
PARITY_SPACE // Space parity (always 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
type StopBits int
|
type StopBits int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
STOPBITS_ONE StopBits = iota
|
STOPBITS_ONE StopBits = iota // 1 Stop bit
|
||||||
STOPBITS_ONEPOINTFIVE
|
STOPBITS_ONEPOINTFIVE // 1.5 Stop bits
|
||||||
STOPBITS_TWO
|
STOPBITS_TWO // 2 Stop bits
|
||||||
)
|
)
|
||||||
|
|
||||||
// Platform independent error type for serial ports
|
// Platform independent error type for serial ports
|
||||||
|
|||||||
@@ -14,25 +14,35 @@ import "strings"
|
|||||||
import "syscall"
|
import "syscall"
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
// opaque type that implements SerialPort interface for linux
|
// Opaque type that implements SerialPort interface for linux
|
||||||
type unixSerialPort struct {
|
type SerialPort struct {
|
||||||
handle int
|
handle int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (port *unixSerialPort) Close() error {
|
// Close the serial port
|
||||||
|
func (port *SerialPort) Close() error {
|
||||||
port.releaseExclusiveAccess()
|
port.releaseExclusiveAccess()
|
||||||
return syscall.Close(port.handle)
|
return syscall.Close(port.handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (port *unixSerialPort) Read(p []byte) (n int, err error) {
|
// Stores data received from the serial port into the provided byte array
|
||||||
|
// buffer. The function returns the number of bytes read.
|
||||||
|
//
|
||||||
|
// The Read function blocks until (at least) one byte is received from
|
||||||
|
// the serial port or an error occurs.
|
||||||
|
func (port *SerialPort) Read(p []byte) (n int, err error) {
|
||||||
return syscall.Read(port.handle, p)
|
return syscall.Read(port.handle, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (port *unixSerialPort) Write(p []byte) (n int, err error) {
|
// Send the content of the data byte array to the serial port.
|
||||||
|
// Returns the number of bytes written.
|
||||||
|
func (port *SerialPort) Write(p []byte) (n int, err error) {
|
||||||
return syscall.Write(port.handle, p)
|
return syscall.Write(port.handle, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (port *unixSerialPort) SetMode(mode *Mode) error {
|
// Set all parameters of the serial port. See the Mode structure for more
|
||||||
|
// info.
|
||||||
|
func (port *SerialPort) SetMode(mode *Mode) error {
|
||||||
settings, err := port.getTermSettings()
|
settings, err := port.getTermSettings()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -52,7 +62,8 @@ func (port *unixSerialPort) SetMode(mode *Mode) error {
|
|||||||
return port.setTermSettings(settings)
|
return port.setTermSettings(settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OpenPort(portName string, mode *Mode) (SerialPort, error) {
|
// Open the serial port using the specified modes
|
||||||
|
func OpenPort(portName string, mode *Mode) (*SerialPort, error) {
|
||||||
h, err := syscall.Open(portName, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NDELAY, 0)
|
h, err := syscall.Open(portName, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NDELAY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err {
|
switch err {
|
||||||
@@ -63,7 +74,7 @@ func OpenPort(portName string, mode *Mode) (SerialPort, error) {
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
port := &unixSerialPort{
|
port := &SerialPort{
|
||||||
handle: h,
|
handle: h,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,20 +230,20 @@ func setRawMode(settings *syscall.Termios) {
|
|||||||
|
|
||||||
// native syscall wrapper functions
|
// native syscall wrapper functions
|
||||||
|
|
||||||
func (port *unixSerialPort) getTermSettings() (*syscall.Termios, error) {
|
func (port *SerialPort) getTermSettings() (*syscall.Termios, error) {
|
||||||
settings := &syscall.Termios{}
|
settings := &syscall.Termios{}
|
||||||
err := ioctl(port.handle, ioctl_tcgetattr, uintptr(unsafe.Pointer(settings)))
|
err := ioctl(port.handle, ioctl_tcgetattr, uintptr(unsafe.Pointer(settings)))
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (port *unixSerialPort) setTermSettings(settings *syscall.Termios) error {
|
func (port *SerialPort) setTermSettings(settings *syscall.Termios) error {
|
||||||
return ioctl(port.handle, ioctl_tcsetattr, uintptr(unsafe.Pointer(settings)))
|
return ioctl(port.handle, ioctl_tcsetattr, uintptr(unsafe.Pointer(settings)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (port *unixSerialPort) acquireExclusiveAccess() error {
|
func (port *SerialPort) acquireExclusiveAccess() error {
|
||||||
return ioctl(port.handle, syscall.TIOCEXCL, 0)
|
return ioctl(port.handle, syscall.TIOCEXCL, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (port *unixSerialPort) releaseExclusiveAccess() error {
|
func (port *SerialPort) releaseExclusiveAccess() error {
|
||||||
return ioctl(port.handle, syscall.TIOCNXCL, 0)
|
return ioctl(port.handle, syscall.TIOCNXCL, 0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package serial // import "go.bug.st/serial"
|
|||||||
import "syscall"
|
import "syscall"
|
||||||
|
|
||||||
// opaque type that implements SerialPort interface for Windows
|
// opaque type that implements SerialPort interface for Windows
|
||||||
type windowsSerialPort struct {
|
type SerialPort struct {
|
||||||
Handle syscall.Handle
|
Handle syscall.Handle
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,11 +56,11 @@ func GetPortsList() ([]string, error) {
|
|||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (port *windowsSerialPort) Close() error {
|
func (port *SerialPort) Close() error {
|
||||||
return syscall.CloseHandle(port.Handle)
|
return syscall.CloseHandle(port.Handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (port *windowsSerialPort) Read(p []byte) (int, error) {
|
func (port *SerialPort) Read(p []byte) (int, error) {
|
||||||
var readed uint32
|
var readed uint32
|
||||||
params := &DCB{}
|
params := &DCB{}
|
||||||
for {
|
for {
|
||||||
@@ -83,7 +83,7 @@ func (port *windowsSerialPort) Read(p []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (port *windowsSerialPort) Write(p []byte) (int, error) {
|
func (port *SerialPort) Write(p []byte) (int, error) {
|
||||||
var writed uint32
|
var writed uint32
|
||||||
err := syscall.WriteFile(port.Handle, p, &writed, nil)
|
err := syscall.WriteFile(port.Handle, p, &writed, nil)
|
||||||
return int(writed), err
|
return int(writed), err
|
||||||
@@ -171,7 +171,7 @@ const (
|
|||||||
TWOSTOPBITS = 2
|
TWOSTOPBITS = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
func (port *windowsSerialPort) SetMode(mode *Mode) error {
|
func (port *SerialPort) SetMode(mode *Mode) error {
|
||||||
params := DCB{}
|
params := DCB{}
|
||||||
if GetCommState(port.Handle, ¶ms) != nil {
|
if GetCommState(port.Handle, ¶ms) != nil {
|
||||||
port.Close()
|
port.Close()
|
||||||
@@ -196,7 +196,7 @@ func (port *windowsSerialPort) SetMode(mode *Mode) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func OpenPort(portName string, mode *Mode) (SerialPort, error) {
|
func OpenPort(portName string, mode *Mode) (*SerialPort, error) {
|
||||||
portName = "\\\\.\\" + portName
|
portName = "\\\\.\\" + portName
|
||||||
path, err := syscall.UTF16PtrFromString(portName)
|
path, err := syscall.UTF16PtrFromString(portName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -219,7 +219,7 @@ func OpenPort(portName string, mode *Mode) (SerialPort, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Create the serial port
|
// Create the serial port
|
||||||
port := &windowsSerialPort{
|
port := &SerialPort{
|
||||||
Handle: handle,
|
Handle: handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user