forked from google/periph
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gpiotest.go
108 lines (93 loc) · 2.11 KB
/
gpiotest.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2016 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
// Package gpiotest is meant to be used to test drivers using fake Pins.
package gpiotest
import (
"errors"
"fmt"
"sync"
"time"
"periph.io/x/periph/conn/gpio"
)
// Pin implements gpio.Pin.
//
// Modify its members to simulate hardware events.
type Pin struct {
N string // Should be immutable
Num int // Should be immutable
Fn string // Should be immutable
sync.Mutex // Grab the Mutex before modifying the members to keep it concurrent safe
L gpio.Level // Used for both input and output
P gpio.Pull
EdgesChan chan gpio.Level // Use it to fake edges
}
func (p *Pin) String() string {
return fmt.Sprintf("%s(%d)", p.N, p.Num)
}
// Name returns the name of the pin.
func (p *Pin) Name() string {
return p.N
}
// Number returns the pin number.
func (p *Pin) Number() int {
return p.Num
}
// Function return the value of the Fn field of the pin.
func (p *Pin) Function() string {
return p.Fn
}
// In is concurrent safe.
func (p *Pin) In(pull gpio.Pull, edge gpio.Edge) error {
p.Lock()
defer p.Unlock()
p.P = pull
if pull == gpio.PullDown {
p.L = gpio.Low
} else if pull == gpio.PullUp {
p.L = gpio.High
}
if edge != gpio.NoEdge && p.EdgesChan == nil {
return errors.New("gpiotest: please set p.EdgesChan first")
}
// Flush any buffered edges.
for {
select {
case <-p.EdgesChan:
default:
return nil
}
}
}
// Read is concurrent safe.
func (p *Pin) Read() gpio.Level {
p.Lock()
defer p.Unlock()
return p.L
}
// WaitForEdge implements gpio.PinIn.
func (p *Pin) WaitForEdge(timeout time.Duration) bool {
if timeout == -1 {
p.Out(<-p.EdgesChan)
return true
}
select {
case <-time.After(timeout):
return false
case l := <-p.EdgesChan:
p.Out(l)
return true
}
}
// Pull implements gpio.PinIn.
func (p *Pin) Pull() gpio.Pull {
return p.P
}
// Out is concurrent safe.
func (p *Pin) Out(l gpio.Level) error {
p.Lock()
defer p.Unlock()
p.L = l
return nil
}
var _ gpio.PinIO = &Pin{}