31 Commits

Author SHA1 Message Date
Cristian Maglie
f0e4a45720 Merge pull request #202 from ctarsjp/win-port-enum
Fix (non-detailed) port enumeration on Windows
2025-03-28 15:54:19 +01:00
Stepan
bcb0408701 Windows: added a check for \\.\ prefix 2025-03-28 16:42:18 +09:00
Stepan
5069d66aa2 Windows: fixed port enumeration 2025-03-28 16:28:13 +09:00
Cristian Maglie
3449d2e7f6 Merge pull request #200 from cmaglie/CH340_hack
Hack to workaround misbehaving CH340 drivers on Windows
2025-03-17 17:24:34 +01:00
Cristian Maglie
1ff9b6fa9a If the timeout is set to NoTimeout, make Read wait forever.
Otherwise the maximul allowed timeout is 0x7FFFFFFF milliseconds,
equivalent to about 24.85 days.
This patch will make a transparent repeated read in case this long
timeout should ever happen.
2025-03-17 10:57:21 +01:00
Cristian Maglie
7dc6297645 Merge pull request #195 from Dirk007/fix/nilErrorReport
Report the actual error instead of nil...
2025-03-13 01:00:39 +01:00
Cristian Maglie
fb4b111d50 Hack for CH340 support 2025-03-12 20:50:56 +01:00
Dirk007
b7483e31a7 Report the actual error instead of nil 2024-09-07 13:26:01 +02:00
Cristian Maglie
0996f840dd Merge pull request #187 from twpayne/sys-windows
Use Windows serial comm functions from golang.org/x/sys/windows
2024-06-25 23:56:14 +02:00
Cristian Maglie
f5a4685ea0 Fixed examples for docs 2024-06-25 23:52:38 +02:00
Tom Payne
56ac2d4e76 Restore check for no detected serial ports on Windows 2024-06-25 11:02:05 +02:00
Tom Payne
1c72447e64 Fix typos
Co-authored-by: Cristian Maglie <c.maglie@bug.st>
2024-06-25 10:48:18 +02:00
Tom Payne
45e996e1b0 Use Windows serial comm functions from golang.org/x/sys/windows 2024-06-24 18:28:26 +02:00
Andreas Deininger
0b7848559a Fix typos (#183)
Co-authored-by: Cristian Maglie <c.maglie@bug.st>
2024-06-24 17:33:18 +02:00
Cristian Maglie
c18d387887 Merge pull request #184 from deining/gofmt
Go-format source code: fix warning
2024-06-24 17:26:52 +02:00
Cristian Maglie
c768d77847 Merge pull request #188 from twpayne/doc-fixes
Fixed minor documentation typos
2024-06-24 17:25:22 +02:00
Andreas Deininger
1282f62c6e Bump GitHub workflow actions to latest versions (#185)
* Bump GitHub workflow actions to latest versions

* Fixed typo

---------

Co-authored-by: Cristian Maglie <c.maglie@bug.st>
2024-06-24 17:24:35 +02:00
Cristian Maglie
4f7d935be3 Merge pull request #186 from AndreRenaud/enumerator-build
Workflows: Use CGO_ENABLED=1 for MacOS
2024-06-24 17:13:45 +02:00
Andre Renaud
03c961bc8a Workflows: Use CGO_ENABLED=1 for MacOS
Also enable explicit ARM64 builds
2024-05-28 09:27:43 +12:00
Andreas Deininger
671075c6ac Go-format source code 2024-04-01 16:04:53 +02:00
Tom Payne
bac809c5a1 Fixed minor documentation typos 2024-03-18 22:25:55 +01:00
Cristian Maglie
0925f99089 Merge pull request #176 from paralin/fix-wasm
fix: add shims for GOARCH=wasm with GOOS=js and GOOS=wasip1
2024-03-11 19:03:49 +01:00
Christian Stewart
42bc112d18 fix: add shims for GOARCH=wasm with GOOS=js and GOOS=wasip1
Fixes build errors:

GOOS=js GOARCH=wasm go build
GOOS=wasip1 GOARCH=wasm go build

Signed-off-by: Christian Stewart <christian@aperture.us>
2024-03-01 14:26:58 -08:00
Cristian Maglie
259bdeb6c7 Fixed typo 2024-02-20 15:57:58 +01:00
Cristian Maglie
572f392ca9 Updated license year 2024-02-20 15:27:44 +01:00
Cristian Maglie
14e5ea68ce Precompile port-filter regexp 2024-02-20 15:24:37 +01:00
Cristian Maglie
bcd8695df4 Removed deprecated package io/ioutil 2024-02-20 15:13:12 +01:00
Cristian Maglie
92703ecb02 Improved issue template message 2024-02-20 09:55:49 +01:00
Cristian Maglie
674fbae95a Upgraded dependencies 2024-02-20 09:52:27 +01:00
Cristian Maglie
2aa105e32e Improved issue template message 2024-02-20 09:51:06 +01:00
Cristian Maglie
7f490f208a Added issues templates 2024-02-18 19:33:23 +01:00
43 changed files with 401 additions and 471 deletions

78
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@@ -0,0 +1,78 @@
# Source: https://github.com/arduino/tooling-project-assets/blob/main/issue-templates/forms/platform-dependent/bug-report.yml
# See: https://docs.github.com/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms
name: Bug report
description: Report a problem with the code or documentation in this repository.
labels:
- bug
body:
- type: textarea
id: description
attributes:
label: Describe the problem
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: To reproduce
description: |
Provide the specific set of steps we can follow to reproduce the
problem in particular the exact golang source code you used.
validations:
required: true
- type: checkboxes
id: checklist-reproduce
attributes:
label: |
Please double-check that you have reported each of the following
before submitting the issue.
options:
- label: I've provided the FULL source code that causes the problem
required: true
- label: I've provided all the actions required to reproduce the problem
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
description: |
What would you expect to happen after following those instructions?
validations:
required: true
- type: input
id: os
attributes:
label: Operating system and version
description: |
Which operating system(s) version are you using on your computer?
validations:
required: true
- type: textarea
id: boards
attributes:
label: Please describe your hardware setup
description: |
Arduino boards, USB dongles, hubs or embedded devices you are using and how they
are connected together.
- type: textarea
id: additional
attributes:
label: Additional context
description: |
Add here any additional information that you think might be relevant to
the problem.
validations:
required: false
- type: checkboxes
id: checklist
attributes:
label: Issue checklist
description: |
Please double-check that you have done each of the following things before
submitting the issue.
options:
- label: I searched for previous requests in [the issue tracker](https://github.com/bugst/go-serial/issues)
required: true
- label: My request contains all necessary details
required: true

View File

@@ -0,0 +1,29 @@
# Source: https://github.com/arduino/tooling-project-assets/blob/main/issue-templates/forms/platform-dependent/feature-request.yml
# See: https://docs.github.com/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms
name: Feature request
description: Suggest an enhancement to this project.
labels:
- "type: enhancement"
body:
- type: textarea
id: description
attributes:
label: Describe the new feature or change suggestion
validations:
required: true
- type: textarea
id: additional
attributes:
label: Additional context
description: Add any additional information about the feature request here.
- type: checkboxes
id: checklist
attributes:
label: Issue checklist
description: Please double-check that you have done each of the following things before submitting the issue.
options:
- label: I searched for previous requests in [the issue tracker](https://github.com/bugst/go-serial/issues)
required: true
- label: My request contains all necessary details
required: true

View File

@@ -15,13 +15,22 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v1
- uses: actions/setup-go@v1
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.17"
- name: Build native
go-version: "1.22"
- name: Setup CGO Environment
run: |
if [ ${{ matrix.os }} == 'macOS-latest' ] ; then
echo "CGO_ENABLED=1" >> "$GITHUB_ENV"
fi
shell: bash
- name: Build AMD64
run: GOARCH=amd64 go build -v ./...
shell: bash
- name: Build ARM64
run: GOARCH=arm64 go build -v ./...
shell: bash
- name: Install socat
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get install socat
@@ -51,10 +60,10 @@ jobs:
runs-on: "ubuntu-latest"
steps:
- uses: actions/checkout@v1
- uses: actions/setup-go@v1
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.17"
go-version: "1.22"
- name: Cross-build
run: |
set ${{ matrix.go-os-pairs }}

View File

@@ -1,5 +1,5 @@
Copyright (c) 2014-2023, Cristian Maglie.
Copyright (c) 2014-2024, Cristian Maglie.
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -2,17 +2,17 @@
# go.bug.st/serial
A cross-platform serial library for go-lang.
A cross-platform serial port library for Go.
## Documentation and examples
See the godoc here: https://godoc.org/go.bug.st/serial
See the package documentation here: https://pkg.go.dev/go.bug.st/serial
## go.mod transition
This library now support `go.mod` with the import `go.bug.st/serial`.
This library supports `go.mod` with the import `go.bug.st/serial`.
If you came from the pre-`go.mod` era please update your import paths from `go.bug.st/serial.v1` to `go.bug.st/serial` to receive new updates. Anyway, the latest `v1` release should still be avaiable using the old import.
If you came from the pre-`go.mod` era please update your import paths from `go.bug.st/serial.v1` to `go.bug.st/serial` to receive updates. The latest `v1` release is still available using the old import path.
## Credits
@@ -20,7 +20,7 @@ If you came from the pre-`go.mod` era please update your import paths from `go.b
## License
The software is release under a [BSD 3-clause license]
This software is released under the [BSD 3-clause license].
[contributors]: https://github.com/bugst/go-serial/graphs/contributors
[BSD 3-clause license]: https://github.com/bugst/go-serial/blob/master/LICENSE

2
doc.go
View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

11
enumerator/usb_wasm.go Normal file
View File

@@ -0,0 +1,11 @@
//
// Copyright 2014-2024 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.
//
package enumerator
func nativeGetDetailedPortsList() ([]*PortDetails, error) {
return nil, &PortEnumerationError{}
}

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
@@ -98,7 +98,7 @@ const (
spdrpUpperFilters = 0x00000011 // UpperFilters = R/W
spdrpLowerFilters = 0x00000012 // LowerFilters = R/W
spdrpBusTypeGUID = 0x00000013 // BusTypeGUID = R
spdrpLegactBusType = 0x00000014 // LegacyBusType = R
spdrpLegacyBusType = 0x00000014 // LegacyBusType = R
spdrpBusNumber = 0x00000015 // BusNumber = R
spdrpEnumeratorName = 0x00000016 // Enumerator Name = R
spdrpSecurity = 0x00000017 // Security = R/W, binary form

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

15
enumerator_wasm.go Normal file
View File

@@ -0,0 +1,15 @@
//
// Copyright 2014-2024 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.
//
package serial
import (
"errors"
)
func nativeGetPortsList() ([]string, error) {
return nil, errors.New("nativeGetPortsList is not supported on wasm")
}

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
@@ -14,7 +14,7 @@ import (
"go.bug.st/serial"
)
func ExampleGetSetModemBits() {
func ExamplePort_GetModemStatusBits() {
// Open the first serial port detected at 9600bps N81
mode := &serial.Mode{
BaudRate: 9600,

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
@@ -13,7 +13,7 @@ import (
"go.bug.st/serial"
)
func ExampleSerialPort_SetMode() {
func ExamplePort_SetMode() {
port, err := serial.Open("/dev/ttyACM0", &serial.Mode{})
if err != nil {
log.Fatal(err)

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

8
go.mod
View File

@@ -4,12 +4,12 @@ go 1.17
require (
github.com/creack/goselect v0.1.2
github.com/stretchr/testify v1.7.0
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
github.com/stretchr/testify v1.8.4
golang.org/x/sys v0.19.0
)
require (
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

20
go.sum
View File

@@ -1,17 +1,21 @@
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
@@ -12,7 +12,7 @@
// Port: /dev/cu.usbmodemFD121
// USB ID 2341:8053
// USB serial FB7B6060504B5952302E314AFF08191A
//
package main
import (

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
@@ -147,7 +147,7 @@ const (
PortNotFound
// InvalidSerialPort the requested port is not a serial port
InvalidSerialPort
// PermissionDenied the user doesn't have enough priviledges
// PermissionDenied the user doesn't have enough privileges
PermissionDenied
// InvalidSpeed the requested speed is not valid or not supported
InvalidSpeed

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,15 +1,20 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
package serial
import "golang.org/x/sys/unix"
import (
"regexp"
"golang.org/x/sys/unix"
)
const devFolder = "/dev"
const regexFilter = "^(cu|tty)\\..*"
var osPortFilter = regexp.MustCompile("^(cu|tty)\\..*")
const ioctlTcgetattr = unix.TIOCGETA
const ioctlTcsetattr = unix.TIOCSETA

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,15 +1,20 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
package serial
import "golang.org/x/sys/unix"
import (
"regexp"
"golang.org/x/sys/unix"
)
const devFolder = "/dev"
const regexFilter = "^(cu|tty)\\..*"
var osPortFilter = regexp.MustCompile("^(cu|tty)\\..*")
// termios manipulation functions

View File

@@ -1,15 +1,20 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
package serial
import "golang.org/x/sys/unix"
import (
"regexp"
"golang.org/x/sys/unix"
)
const devFolder = "/dev"
const regexFilter = "(ttyS|ttyHS|ttyUSB|ttyACM|ttyAMA|rfcomm|ttyO|ttymxc)[0-9]{1,3}"
var osPortFilter = regexp.MustCompile("(ttyS|ttyHS|ttyUSB|ttyACM|ttyAMA|rfcomm|ttyO|ttymxc)[0-9]{1,3}")
// termios manipulation functions

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,15 +1,20 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
package serial
import "golang.org/x/sys/unix"
import (
"regexp"
"golang.org/x/sys/unix"
)
const devFolder = "/dev"
const regexFilter = "^(cu|tty)\\..*"
var osPortFilter = regexp.MustCompile("^(cu|tty)\\..*")
// termios manipulation functions

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
@@ -10,8 +10,7 @@ package serial
import (
"fmt"
"io/ioutil"
"regexp"
"os"
"strings"
"sync"
"sync/atomic"
@@ -242,7 +241,7 @@ func nativeOpen(portName string, mode *Mode) (*unixPort, error) {
// Explicitly disable RTS/CTS flow control
setTermSettingsCtsRts(false, settings)
if port.setTermSettings(settings) != nil {
if err = port.setTermSettings(settings); err != nil {
port.Close()
return nil, &PortError{code: InvalidSerialPort, causedBy: fmt.Errorf("error setting term settings: %w", err)}
}
@@ -292,16 +291,12 @@ func nativeOpen(portName string, mode *Mode) (*unixPort, error) {
}
func nativeGetPortsList() ([]string, error) {
files, err := ioutil.ReadDir(devFolder)
files, err := os.ReadDir(devFolder)
if err != nil {
return nil, err
}
ports := make([]string, 0, len(files))
regex, err := regexp.Compile(regexFilter)
if err != nil {
return nil, err
}
for _, f := range files {
// Skip folders
if f.IsDir() {
@@ -309,7 +304,7 @@ func nativeGetPortsList() ([]string, error) {
}
// Keep only devices with the correct name
if !regex.MatchString(f.Name()) {
if !osPortFilter.MatchString(f.Name()) {
continue
}

15
serial_wasm.go Normal file
View File

@@ -0,0 +1,15 @@
//
// Copyright 2014-2024 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.
//
package serial
import (
"errors"
)
func nativeOpen(portName string, mode *Mode) (Port, error) {
return nil, errors.New("nativeOpen is not supported on wasm")
}

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
@@ -18,48 +18,50 @@ package serial
*/
import (
"errors"
"strings"
"sync"
"syscall"
"time"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
)
type windowsPort struct {
mu sync.Mutex
handle syscall.Handle
handle windows.Handle
hasTimeout bool
}
func nativeGetPortsList() ([]string, error) {
subKey, err := syscall.UTF16PtrFromString("HARDWARE\\DEVICEMAP\\SERIALCOMM\\")
key, err := registry.OpenKey(windows.HKEY_LOCAL_MACHINE, `HARDWARE\DEVICEMAP\SERIALCOMM\`, windows.KEY_READ)
switch {
case errors.Is(err, syscall.ERROR_FILE_NOT_FOUND):
// On machines with no serial ports the registry key does not exist.
// Return this as no serial ports instead of an error.
return nil, nil
case err != nil:
return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err}
}
defer key.Close()
names, err := key.ReadValueNames(0)
if err != nil {
return nil, &PortError{code: ErrorEnumeratingPorts}
return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err}
}
var h syscall.Handle
if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, subKey, 0, syscall.KEY_READ, &h); err != nil {
if errno, isErrno := err.(syscall.Errno); isErrno && errno == syscall.ERROR_FILE_NOT_FOUND {
return []string{}, nil
}
return nil, &PortError{code: ErrorEnumeratingPorts}
}
defer syscall.RegCloseKey(h)
var valuesCount uint32
if syscall.RegQueryInfoKey(h, nil, nil, nil, nil, nil, nil, &valuesCount, nil, nil, nil, nil) != nil {
return nil, &PortError{code: ErrorEnumeratingPorts}
var values []string
for _, n := range names {
v, _, err := key.GetStringValue(n)
if err != nil || v == "" {
continue
}
list := make([]string, valuesCount)
for i := range list {
var data [1024]uint16
dataSize := uint32(len(data))
var name [1024]uint16
nameSize := uint32(len(name))
if regEnumValue(h, uint32(i), &name[0], &nameSize, nil, nil, &data[0], &dataSize) != nil {
return nil, &PortError{code: ErrorEnumeratingPorts}
values = append(values, v)
}
list[i] = syscall.UTF16ToString(data[:])
}
return list, nil
return values, nil
}
func (port *windowsPort) Close() error {
@@ -71,7 +73,7 @@ func (port *windowsPort) Close() error {
if port.handle == 0 {
return nil
}
return syscall.CloseHandle(port.handle)
return windows.CloseHandle(port.handle)
}
func (port *windowsPort) Read(p []byte) (int, error) {
@@ -80,16 +82,17 @@ func (port *windowsPort) Read(p []byte) (int, error) {
if err != nil {
return 0, err
}
defer syscall.CloseHandle(ev.HEvent)
defer windows.CloseHandle(ev.HEvent)
err = syscall.ReadFile(port.handle, p, &readed, ev)
if err == syscall.ERROR_IO_PENDING {
err = getOverlappedResult(port.handle, ev, &readed, true)
for {
err = windows.ReadFile(port.handle, p, &readed, ev)
if err == windows.ERROR_IO_PENDING {
err = windows.GetOverlappedResult(port.handle, ev, &readed, true)
}
switch err {
case nil:
// operation completed successfully
case syscall.ERROR_OPERATION_ABORTED:
case windows.ERROR_OPERATION_ABORTED:
// port may have been closed
return int(readed), &PortError{code: PortClosed, causedBy: err}
default:
@@ -101,8 +104,14 @@ func (port *windowsPort) Read(p []byte) (int, error) {
}
// Timeout
port.mu.Lock()
hasTimeout := port.hasTimeout
port.mu.Unlock()
if hasTimeout {
return 0, nil
}
}
}
func (port *windowsPort) Write(p []byte) (int, error) {
var writed uint32
@@ -110,32 +119,25 @@ func (port *windowsPort) Write(p []byte) (int, error) {
if err != nil {
return 0, err
}
defer syscall.CloseHandle(ev.HEvent)
err = syscall.WriteFile(port.handle, p, &writed, ev)
if err == syscall.ERROR_IO_PENDING {
defer windows.CloseHandle(ev.HEvent)
err = windows.WriteFile(port.handle, p, &writed, ev)
if err == windows.ERROR_IO_PENDING {
// wait for write to complete
err = getOverlappedResult(port.handle, ev, &writed, true)
err = windows.GetOverlappedResult(port.handle, ev, &writed, true)
}
return int(writed), err
}
func (port *windowsPort) Drain() (err error) {
return syscall.FlushFileBuffers(port.handle)
return windows.FlushFileBuffers(port.handle)
}
const (
purgeRxAbort uint32 = 0x0002
purgeRxClear = 0x0008
purgeTxAbort = 0x0001
purgeTxClear = 0x0004
)
func (port *windowsPort) ResetInputBuffer() error {
return purgeComm(port.handle, purgeRxClear|purgeRxAbort)
return windows.PurgeComm(port.handle, windows.PURGE_RXCLEAR|windows.PURGE_RXABORT)
}
func (port *windowsPort) ResetOutputBuffer() error {
return purgeComm(port.handle, purgeTxClear|purgeTxAbort)
return windows.PurgeComm(port.handle, windows.PURGE_TXCLEAR|windows.PURGE_TXABORT)
}
const (
@@ -152,119 +154,44 @@ const (
dcbInX = 0x00000200
dcbErrorChar = 0x00000400
dcbNull = 0x00000800
dcbRTSControlDisbaleMask = ^uint32(0x00003000)
dcbRTSControlDisableMask = ^uint32(0x00003000)
dcbRTSControlEnable = 0x00001000
dcbRTSControlHandshake = 0x00002000
dcbRTSControlToggle = 0x00003000
dcbAbortOnError = 0x00004000
)
type dcb struct {
DCBlength uint32
BaudRate uint32
// Flags field is a bitfield
// fBinary :1
// fParity :1
// fOutxCtsFlow :1
// fOutxDsrFlow :1
// fDtrControl :2
// fDsrSensitivity :1
// fTXContinueOnXoff :1
// fOutX :1
// fInX :1
// fErrorChar :1
// fNull :1
// fRtsControl :2
// fAbortOnError :1
// fDummy2 :17
Flags uint32
wReserved uint16
XonLim uint16
XoffLim uint16
ByteSize byte
Parity byte
StopBits byte
XonChar byte
XoffChar byte
ErrorChar byte
EOFChar byte
EvtChar byte
wReserved1 uint16
}
type commTimeouts struct {
ReadIntervalTimeout uint32
ReadTotalTimeoutMultiplier uint32
ReadTotalTimeoutConstant uint32
WriteTotalTimeoutMultiplier uint32
WriteTotalTimeoutConstant uint32
}
const (
noParity = 0
oddParity = 1
evenParity = 2
markParity = 3
spaceParity = 4
)
var parityMap = map[Parity]byte{
NoParity: noParity,
OddParity: oddParity,
EvenParity: evenParity,
MarkParity: markParity,
SpaceParity: spaceParity,
NoParity: windows.NOPARITY,
OddParity: windows.ODDPARITY,
EvenParity: windows.EVENPARITY,
MarkParity: windows.MARKPARITY,
SpaceParity: windows.SPACEPARITY,
}
const (
oneStopBit = 0
one5StopBits = 1
twoStopBits = 2
)
var stopBitsMap = map[StopBits]byte{
OneStopBit: oneStopBit,
OnePointFiveStopBits: one5StopBits,
TwoStopBits: twoStopBits,
OneStopBit: windows.ONESTOPBIT,
OnePointFiveStopBits: windows.ONE5STOPBITS,
TwoStopBits: windows.TWOSTOPBITS,
}
const (
commFunctionSetXOFF = 1
commFunctionSetXON = 2
commFunctionSetRTS = 3
commFunctionClrRTS = 4
commFunctionSetDTR = 5
commFunctionClrDTR = 6
commFunctionSetBreak = 8
commFunctionClrBreak = 9
)
const (
msCTSOn = 0x0010
msDSROn = 0x0020
msRingOn = 0x0040
msRLSDOn = 0x0080
)
func (port *windowsPort) SetMode(mode *Mode) error {
params := dcb{}
if getCommState(port.handle, &params) != nil {
params := windows.DCB{}
if windows.GetCommState(port.handle, &params) != nil {
port.Close()
return &PortError{code: InvalidSerialPort}
}
port.setModeParams(mode, &params)
if setCommState(port.handle, &params) != nil {
if windows.SetCommState(port.handle, &params) != nil {
port.Close()
return &PortError{code: InvalidSerialPort}
}
return nil
}
func (port *windowsPort) setModeParams(mode *Mode, params *dcb) {
func (port *windowsPort) setModeParams(mode *Mode, params *windows.DCB) {
if mode.BaudRate == 0 {
params.BaudRate = 9600 // Default to 9600
params.BaudRate = windows.CBR_9600 // Default to 9600
} else {
params.BaudRate = uint32(mode.BaudRate)
}
@@ -278,22 +205,22 @@ func (port *windowsPort) setModeParams(mode *Mode, params *dcb) {
}
func (port *windowsPort) SetDTR(dtr bool) error {
// Like for RTS there are problems with the escapeCommFunction
// Like for RTS there are problems with the windows.EscapeCommFunction
// observed behaviour was that DTR is set from false -> true
// when setting RTS from true -> false
// 1) Connect -> RTS = true (low) DTR = true (low) OKAY
// 2) SetDTR(false) -> RTS = true (low) DTR = false (heigh) OKAY
// 3) SetRTS(false) -> RTS = false (heigh) DTR = true (low) ERROR: DTR toggled
// 2) SetDTR(false) -> RTS = true (low) DTR = false (high) OKAY
// 3) SetRTS(false) -> RTS = false (high) DTR = true (low) ERROR: DTR toggled
//
// In addition this way the CommState Flags are not updated
/*
var res bool
var err error
if dtr {
res = escapeCommFunction(port.handle, commFunctionSetDTR)
err = windows.EscapeCommFunction(port.handle, windows.SETDTR)
} else {
res = escapeCommFunction(port.handle, commFunctionClrDTR)
err = windows.EscapeCommFunction(port.handle, windows.CLTDTR)
}
if !res {
if err != nil {
return &PortError{}
}
return nil
@@ -301,15 +228,15 @@ func (port *windowsPort) SetDTR(dtr bool) error {
// The following seems a more reliable way to do it
params := &dcb{}
if err := getCommState(port.handle, params); err != nil {
params := &windows.DCB{}
if err := windows.GetCommState(port.handle, params); err != nil {
return &PortError{causedBy: err}
}
params.Flags &= dcbDTRControlDisableMask
if dtr {
params.Flags |= dcbDTRControlEnable
params.Flags |= windows.DTR_CONTROL_ENABLE
}
if err := setCommState(port.handle, params); err != nil {
if err := windows.SetCommState(port.handle, params); err != nil {
return &PortError{causedBy: err}
}
@@ -325,13 +252,13 @@ func (port *windowsPort) SetRTS(rts bool) error {
// In addition this way the CommState Flags are not updated
/*
var res bool
var err error
if rts {
res = escapeCommFunction(port.handle, commFunctionSetRTS)
err = windows.EscapeCommFunction(port.handle, windows.SETRTS)
} else {
res = escapeCommFunction(port.handle, commFunctionClrRTS)
err = windows.EscapeCommFunction(port.handle, windows.CLRRTS)
}
if !res {
if err != nil {
return &PortError{}
}
return nil
@@ -339,15 +266,15 @@ func (port *windowsPort) SetRTS(rts bool) error {
// The following seems a more reliable way to do it
params := &dcb{}
if err := getCommState(port.handle, params); err != nil {
params := &windows.DCB{}
if err := windows.GetCommState(port.handle, params); err != nil {
return &PortError{causedBy: err}
}
params.Flags &= dcbRTSControlDisbaleMask
params.Flags &= dcbRTSControlDisableMask
if rts {
params.Flags |= dcbRTSControlEnable
params.Flags |= windows.RTS_CONTROL_ENABLE
}
if err := setCommState(port.handle, params); err != nil {
if err := windows.SetCommState(port.handle, params); err != nil {
return &PortError{causedBy: err}
}
return nil
@@ -355,22 +282,31 @@ func (port *windowsPort) SetRTS(rts bool) error {
func (port *windowsPort) GetModemStatusBits() (*ModemStatusBits, error) {
var bits uint32
if !getCommModemStatus(port.handle, &bits) {
if err := windows.GetCommModemStatus(port.handle, &bits); err != nil {
return nil, &PortError{}
}
return &ModemStatusBits{
CTS: (bits & msCTSOn) != 0,
DCD: (bits & msRLSDOn) != 0,
DSR: (bits & msDSROn) != 0,
RI: (bits & msRingOn) != 0,
CTS: (bits & windows.EV_CTS) != 0,
DCD: (bits & windows.EV_RLSD) != 0,
DSR: (bits & windows.EV_DSR) != 0,
RI: (bits & windows.EV_RING) != 0,
}, nil
}
func (port *windowsPort) SetReadTimeout(timeout time.Duration) error {
commTimeouts := &commTimeouts{
// This is a brutal hack to make the CH340 chipset work properly.
// Normally this value should be 0xFFFFFFFE but, after a lot of
// tinkering, I discovered that any value with the highest
// bit set will make the CH340 driver behave like the timeout is 0,
// in the best cases leading to a spinning loop...
// (could this be a wrong signed vs unsigned conversion in the driver?)
// https://github.com/arduino/serial-monitor/issues/112
const MaxReadTotalTimeoutConstant = 0x7FFFFFFE
commTimeouts := &windows.CommTimeouts{
ReadIntervalTimeout: 0xFFFFFFFF,
ReadTotalTimeoutMultiplier: 0xFFFFFFFF,
ReadTotalTimeoutConstant: 0xFFFFFFFE,
ReadTotalTimeoutConstant: MaxReadTotalTimeoutConstant,
WriteTotalTimeoutConstant: 0,
WriteTotalTimeoutMultiplier: 0,
}
@@ -379,53 +315,63 @@ func (port *windowsPort) SetReadTimeout(timeout time.Duration) error {
if ms > 0xFFFFFFFE || ms < 0 {
return &PortError{code: InvalidTimeoutValue}
}
if ms > MaxReadTotalTimeoutConstant {
ms = MaxReadTotalTimeoutConstant
}
commTimeouts.ReadTotalTimeoutConstant = uint32(ms)
}
if err := setCommTimeouts(port.handle, commTimeouts); err != nil {
port.mu.Lock()
defer port.mu.Unlock()
if err := windows.SetCommTimeouts(port.handle, commTimeouts); err != nil {
return &PortError{code: InvalidTimeoutValue, causedBy: err}
}
port.hasTimeout = (timeout != NoTimeout)
return nil
}
func (port *windowsPort) Break(d time.Duration) error {
if err := setCommBreak(port.handle); err != nil {
if err := windows.SetCommBreak(port.handle); err != nil {
return &PortError{causedBy: err}
}
time.Sleep(d)
if err := clearCommBreak(port.handle); err != nil {
if err := windows.ClearCommBreak(port.handle); err != nil {
return &PortError{causedBy: err}
}
return nil
}
func createOverlappedEvent() (*syscall.Overlapped, error) {
h, err := createEvent(nil, true, false, nil)
return &syscall.Overlapped{HEvent: h}, err
func createOverlappedEvent() (*windows.Overlapped, error) {
h, err := windows.CreateEvent(nil, 1, 0, nil)
return &windows.Overlapped{HEvent: h}, err
}
func nativeOpen(portName string, mode *Mode) (*windowsPort, error) {
portName = "\\\\.\\" + portName
path, err := syscall.UTF16PtrFromString(portName)
if !strings.HasPrefix(portName, `\\.\`) {
portName = `\\.\` + portName
}
path, err := windows.UTF16PtrFromString(portName)
if err != nil {
return nil, err
}
handle, err := syscall.CreateFile(
handle, err := windows.CreateFile(
path,
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
windows.GENERIC_READ|windows.GENERIC_WRITE,
0, nil,
syscall.OPEN_EXISTING,
syscall.FILE_FLAG_OVERLAPPED,
windows.OPEN_EXISTING,
windows.FILE_FLAG_OVERLAPPED,
0)
if err != nil {
switch err {
case syscall.ERROR_ACCESS_DENIED:
case windows.ERROR_ACCESS_DENIED:
return nil, &PortError{code: PortBusy}
case syscall.ERROR_FILE_NOT_FOUND:
case windows.ERROR_FILE_NOT_FOUND:
return nil, &PortError{code: PortNotFound}
}
return nil, err
@@ -436,23 +382,23 @@ func nativeOpen(portName string, mode *Mode) (*windowsPort, error) {
}
// Set port parameters
params := &dcb{}
if getCommState(port.handle, params) != nil {
params := &windows.DCB{}
if windows.GetCommState(port.handle, params) != nil {
port.Close()
return nil, &PortError{code: InvalidSerialPort}
}
port.setModeParams(mode, params)
params.Flags &= dcbDTRControlDisableMask
params.Flags &= dcbRTSControlDisbaleMask
params.Flags &= dcbRTSControlDisableMask
if mode.InitialStatusBits == nil {
params.Flags |= dcbDTRControlEnable
params.Flags |= dcbRTSControlEnable
params.Flags |= windows.DTR_CONTROL_ENABLE
params.Flags |= windows.RTS_CONTROL_ENABLE
} else {
if mode.InitialStatusBits.DTR {
params.Flags |= dcbDTRControlEnable
params.Flags |= windows.DTR_CONTROL_ENABLE
}
if mode.InitialStatusBits.RTS {
params.Flags |= dcbRTSControlEnable
params.Flags |= windows.RTS_CONTROL_ENABLE
}
}
params.Flags &^= dcbOutXCTSFlow
@@ -468,7 +414,7 @@ func nativeOpen(portName string, mode *Mode) (*windowsPort, error) {
params.XoffLim = 512
params.XonChar = 17 // DC1
params.XoffChar = 19 // C3
if setCommState(port.handle, params) != nil {
if windows.SetCommState(port.handle, params) != nil {
port.Close()
return nil, &PortError{code: InvalidSerialPort}
}

View File

@@ -1,31 +0,0 @@
//
// Copyright 2014-2023 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.
//
package serial
//sys regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, value *uint16, valueLen *uint32) (regerrno error) = advapi32.RegEnumValueW
//sys getCommState(handle syscall.Handle, dcb *dcb) (err error) = GetCommState
//sys setCommState(handle syscall.Handle, dcb *dcb) (err error) = SetCommState
//sys setCommTimeouts(handle syscall.Handle, timeouts *commTimeouts) (err error) = SetCommTimeouts
//sys escapeCommFunction(handle syscall.Handle, function uint32) (res bool) = EscapeCommFunction
//sys getCommModemStatus(handle syscall.Handle, bits *uint32) (res bool) = GetCommModemStatus
//sys createEvent(eventAttributes *uint32, manualReset bool, initialState bool, name *uint16) (handle syscall.Handle, err error) = CreateEventW
//sys resetEvent(handle syscall.Handle) (err error) = ResetEvent
//sys getOverlappedResult(handle syscall.Handle, overlapEvent *syscall.Overlapped, n *uint32, wait bool) (err error) = GetOverlappedResult
//sys purgeComm(handle syscall.Handle, flags uint32) (err error) = PurgeComm
//sys setCommBreak(handle syscall.Handle) (err error) = SetCommBreak
//sys clearCommBreak(handle syscall.Handle) (err error) = ClearCommBreak

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//
@@ -40,7 +40,7 @@ func (p *Pipe) ReadFD() int {
return p.rd
}
// WriteFD returns the flie handle for the write side of the pipe.
// WriteFD returns the file handle for the write side of the pipe.
func (p *Pipe) WriteFD() int {
if !p.opened {
return -1
@@ -48,7 +48,7 @@ func (p *Pipe) WriteFD() int {
return p.wr
}
// Write to the pipe the content of data. Returns the numbre of bytes written.
// Write to the pipe the content of data. Returns the number of bytes written.
func (p *Pipe) Write(data []byte) (int, error) {
if !p.opened {
return 0, fmt.Errorf("Pipe not opened")

View File

@@ -1,5 +1,5 @@
//
// Copyright 2014-2023 Cristian Maglie. All rights reserved.
// Copyright 2014-2024 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.
//

View File

@@ -1,161 +0,0 @@
// Code generated by 'go generate'; DO NOT EDIT.
package serial
import (
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
var _ unsafe.Pointer
// Do the interface allocations only once for common
// Errno values.
const (
errnoERROR_IO_PENDING = 997
)
var (
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
errERROR_EINVAL error = syscall.EINVAL
)
// errnoErr returns common boxed Errno values, to prevent
// allocations at runtime.
func errnoErr(e syscall.Errno) error {
switch e {
case 0:
return errERROR_EINVAL
case errnoERROR_IO_PENDING:
return errERROR_IO_PENDING
}
// TODO: add more here, after collecting data on the common
// error values see on Windows. (perhaps when running
// all.bat?)
return e
}
var (
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW")
procClearCommBreak = modkernel32.NewProc("ClearCommBreak")
procCreateEventW = modkernel32.NewProc("CreateEventW")
procEscapeCommFunction = modkernel32.NewProc("EscapeCommFunction")
procGetCommModemStatus = modkernel32.NewProc("GetCommModemStatus")
procGetCommState = modkernel32.NewProc("GetCommState")
procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult")
procPurgeComm = modkernel32.NewProc("PurgeComm")
procResetEvent = modkernel32.NewProc("ResetEvent")
procSetCommBreak = modkernel32.NewProc("SetCommBreak")
procSetCommState = modkernel32.NewProc("SetCommState")
procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts")
)
func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, value *uint16, valueLen *uint32) (regerrno error) {
r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(valueLen)), 0)
if r0 != 0 {
regerrno = syscall.Errno(r0)
}
return
}
func clearCommBreak(handle syscall.Handle) (err error) {
r1, _, e1 := syscall.Syscall(procClearCommBreak.Addr(), 1, uintptr(handle), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func createEvent(eventAttributes *uint32, manualReset bool, initialState bool, name *uint16) (handle syscall.Handle, err error) {
var _p0 uint32
if manualReset {
_p0 = 1
}
var _p1 uint32
if initialState {
_p1 = 1
}
r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttributes)), uintptr(_p0), uintptr(_p1), uintptr(unsafe.Pointer(name)), 0, 0)
handle = syscall.Handle(r0)
if handle == 0 {
err = errnoErr(e1)
}
return
}
func escapeCommFunction(handle syscall.Handle, function uint32) (res bool) {
r0, _, _ := syscall.Syscall(procEscapeCommFunction.Addr(), 2, uintptr(handle), uintptr(function), 0)
res = r0 != 0
return
}
func getCommModemStatus(handle syscall.Handle, bits *uint32) (res bool) {
r0, _, _ := syscall.Syscall(procGetCommModemStatus.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(bits)), 0)
res = r0 != 0
return
}
func getCommState(handle syscall.Handle, dcb *dcb) (err error) {
r1, _, e1 := syscall.Syscall(procGetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(dcb)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func getOverlappedResult(handle syscall.Handle, overlapEvent *syscall.Overlapped, n *uint32, wait bool) (err error) {
var _p0 uint32
if wait {
_p0 = 1
}
r1, _, e1 := syscall.Syscall6(procGetOverlappedResult.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(overlapEvent)), uintptr(unsafe.Pointer(n)), uintptr(_p0), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func purgeComm(handle syscall.Handle, flags uint32) (err error) {
r1, _, e1 := syscall.Syscall(procPurgeComm.Addr(), 2, uintptr(handle), uintptr(flags), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func resetEvent(handle syscall.Handle) (err error) {
r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(handle), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func setCommBreak(handle syscall.Handle) (err error) {
r1, _, e1 := syscall.Syscall(procSetCommBreak.Addr(), 1, uintptr(handle), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func setCommState(handle syscall.Handle, dcb *dcb) (err error) {
r1, _, e1 := syscall.Syscall(procSetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(dcb)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func setCommTimeouts(handle syscall.Handle, timeouts *commTimeouts) (err error) {
r1, _, e1 := syscall.Syscall(procSetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}