mirror of
https://github.com/stianeikeland/go-rpio.git
synced 2025-01-23 02:31:05 +01:00
Merge pull request #29 from Drahoslav7/perf/gpio-write
Perf/gpio - faster write and toggle
This commit is contained in:
commit
2c2ef096f8
27
rpio.go
27
rpio.go
|
@ -284,19 +284,19 @@ func PinMode(pin Pin, mode Mode) {
|
|||
func WritePin(pin Pin, state State) {
|
||||
p := uint8(pin)
|
||||
|
||||
// Clear register, 10 / 11 depending on bank
|
||||
// Set register, 7 / 8 depending on bank
|
||||
clearReg := p/32 + 10
|
||||
// Clear register, 10 / 11 depending on bank
|
||||
setReg := p/32 + 7
|
||||
clearReg := p/32 + 10
|
||||
|
||||
memlock.Lock()
|
||||
defer memlock.Unlock()
|
||||
|
||||
if state == Low {
|
||||
gpioMem[clearReg] = 1 << (p & 31)
|
||||
} else {
|
||||
gpioMem[setReg] = 1 << (p & 31)
|
||||
}
|
||||
memlock.Unlock() // not deferring saves ~600ns
|
||||
}
|
||||
|
||||
// Read the state of a pin
|
||||
|
@ -312,14 +312,23 @@ func ReadPin(pin Pin) State {
|
|||
}
|
||||
|
||||
// Toggle a pin state (high -> low -> high)
|
||||
// TODO: probably possible to do this much faster without read
|
||||
func TogglePin(pin Pin) {
|
||||
switch ReadPin(pin) {
|
||||
case Low:
|
||||
pin.High()
|
||||
case High:
|
||||
pin.Low()
|
||||
p := uint8(pin)
|
||||
|
||||
setReg := p/32 + 7
|
||||
clearReg := p/32 + 10
|
||||
levelReg := p/32 + 13
|
||||
|
||||
bit := uint32(1 << (p & 31))
|
||||
|
||||
memlock.Lock()
|
||||
|
||||
if (gpioMem[levelReg] & bit) != 0 {
|
||||
gpioMem[clearReg] = bit
|
||||
} else {
|
||||
gpioMem[setReg] = bit
|
||||
}
|
||||
memlock.Unlock()
|
||||
}
|
||||
|
||||
// Enable edge event detection on pin.
|
||||
|
|
73
rpio_test.go
73
rpio_test.go
|
@ -117,4 +117,77 @@ func TestEvent(t *testing.T) {
|
|||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkGpio(b *testing.B) {
|
||||
src := Pin(3)
|
||||
src.Mode(Output)
|
||||
src.Low()
|
||||
|
||||
pin := Pin(2)
|
||||
pin.Mode(Input)
|
||||
pin.PullDown()
|
||||
|
||||
oldWrite := func(pin Pin, state State) {
|
||||
p := uint8(pin)
|
||||
|
||||
setReg := p/32 + 7
|
||||
clearReg := p/32 + 10
|
||||
|
||||
memlock.Lock()
|
||||
defer memlock.Unlock()
|
||||
|
||||
if state == Low {
|
||||
gpioMem[clearReg] = 1 << (p & 31)
|
||||
} else {
|
||||
gpioMem[setReg] = 1 << (p & 31)
|
||||
}
|
||||
}
|
||||
|
||||
oldToggle := func(pin Pin) {
|
||||
switch ReadPin(pin) {
|
||||
case Low:
|
||||
oldWrite(pin, High)
|
||||
case High:
|
||||
oldWrite(pin, Low)
|
||||
}
|
||||
}
|
||||
|
||||
b.Run("write", func(b *testing.B) {
|
||||
b.Run("old", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
if i%2 == 0 {
|
||||
oldWrite(src, High)
|
||||
} else {
|
||||
oldWrite(src, Low)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("new", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
if i%2 == 0 {
|
||||
WritePin(src, High)
|
||||
} else {
|
||||
WritePin(src, Low)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("toggle", func(b *testing.B) {
|
||||
b.Run("old", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
oldToggle(src)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("new", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
TogglePin(src)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user