Skip to content

Instantly share code, notes, and snippets.

@schlamar
Created April 14, 2019 08:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schlamar/d87637b6eed78c5cf34c1f344ea0ea51 to your computer and use it in GitHub Desktop.
Save schlamar/d87637b6eed78c5cf34c1f344ea0ea51 to your computer and use it in GitHub Desktop.
go GPIO chardev example
package main
import (
"encoding/hex"
"os"
"syscall"
"time"
"unsafe"
"golang.org/x/sys/unix"
)
const (
GPIOHANDLE_REQUEST_INPUT = 0x1
GPIOHANDLE_REQUEST_OUTPUT = 0x2
GPIOEVENT_REQUEST_RISING_EDGE = 0x1
GPIOEVENT_REQUEST_FALLING_EDGE = 0x2
GPIOEVENT_REQUEST_BOTH_EDGES = 0x1 | 0x2
GPIOHANDLE_GET_LINE_VALUES_IOCTL = 0xc040b408
GPIOHANDLE_SET_LINE_VALUES_IOCTL = 0xc040b409
GPIO_GET_CHIPINFO_IOCTL = 0x8044b401
GPIO_GET_LINEINFO_IOCTL = 0xc048b402
GPIO_GET_LINEHANDLE_IOCTL = 0xc16cb403
GPIO_GET_LINEEVENT_IOCTL = 0xc030b404
)
type gpiohandlerequest struct {
Lineoffsets [64]uint32
Flags uint32
DefaultValues [64]uint8
ConsumerLabel [32]byte
Lines uint32
Fd uintptr
}
type gpioeventrequest struct {
Lineoffset uint32
Handleflags uint32
Eventflags uint32
ConsumerLabel [32]byte
Fd uintptr
}
type gpiohandledata struct {
Values [64]uint8
}
type gpioeventdata struct {
Timestamp uint64
ID uint32
}
func main() {
f, err := os.Open("/dev/gpiochip0")
if err != nil {
println("0 Error", err)
}
defer f.Close()
handlereq := gpiohandlerequest{
Lineoffsets: [64]uint32{4},
Flags: GPIOHANDLE_REQUEST_OUTPUT,
DefaultValues: [64]uint8{1},
ConsumerLabel: [32]byte{'h', 'm', 'g', 'o'},
Lines: 1,
}
_, _, errno := syscall.Syscall(
syscall.SYS_IOCTL, uintptr(f.Fd()), GPIO_GET_LINEHANDLE_IOCTL,
uintptr(unsafe.Pointer(&handlereq)))
if errno != 0 {
println("1 Error", errno)
return
}
time.Sleep(500 * time.Millisecond)
_, _, errno = syscall.Syscall(
syscall.SYS_IOCTL, uintptr(handlereq.Fd), GPIOHANDLE_SET_LINE_VALUES_IOCTL,
uintptr(unsafe.Pointer(&gpiohandledata{Values: [64]uint8{0}})))
if errno != 0 {
println("2 Error", errno)
return
}
time.Sleep(time.Millisecond)
err = unix.Close(int(handlereq.Fd))
if err != nil {
println("Error close", err)
return
}
eventreq := gpioeventrequest{
Lineoffset: 4,
Handleflags: GPIOHANDLE_REQUEST_INPUT,
Eventflags: GPIOEVENT_REQUEST_FALLING_EDGE,
ConsumerLabel: [32]byte{'h', 'm', 'g', 'o'},
}
_, _, errno = syscall.Syscall(
syscall.SYS_IOCTL, uintptr(f.Fd()), GPIO_GET_LINEEVENT_IOCTL,
uintptr(unsafe.Pointer(&eventreq)))
if errno != 0 {
println("3 Error", errno)
return
}
// time.Sleep(time.Millisecond)
eventdata := gpioeventdata{}
println("Size 1", unsafe.Sizeof(eventdata))
sizeData := int(unsafe.Sizeof(eventdata))
println("Size", sizeData)
for i := 0; i < 200; i++ {
data := make([]byte, 16)
n, err := syscall.Read(int(eventreq.Fd), data)
if err == nil && n == 16 {
println("Data:", hex.EncodeToString(data))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment