Skip to content

Commit 7f3d9b9

Browse files
committed
Rework GPIO function setting to be a bit nicer. Add functions for setting pins as inputs, outputs, including compulsory specification of pull up/down/none mode for outputs.
1 parent e1935e5 commit 7f3d9b9

File tree

2 files changed

+47
-6
lines changed

2 files changed

+47
-6
lines changed

rpi/gpio.go

+46-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package rpi
33
import (
44
"fmt"
55
"log"
6+
"time"
67
"unsafe"
78
)
89

@@ -35,17 +36,57 @@ type gpioT struct {
3536
test uint32
3637
}
3738

38-
func (rp *RPi) gpioFunctionSet(pin int, alt int) error {
39+
type PullMode uint
40+
41+
const (
42+
// See p101. These are GPPUD values
43+
PullNone = 0
44+
PullDown = 1
45+
PullUp = 2
46+
)
47+
48+
func (rp *RPi) gpioSetPinFunction(pin int, fnc uint32) error {
49+
if pin > 53 { // p94
50+
return fmt.Errorf("pin %d not supported")
51+
}
3952
reg := pin / 10
4053
offset := uint((pin % 10) * 3)
54+
rp.gpio.fsel[reg] &= ^(0x7 << offset)
55+
rp.gpio.fsel[reg] |= fnc << offset
56+
return nil
57+
}
58+
59+
func (rp *RPi) gpioSetInput(pin int) error {
60+
return rp.gpioSetPinFunction(pin, 0)
61+
}
62+
63+
func (rp *RPi) gpioSetOutput(pin int, pm PullMode) error {
64+
if pm > PullUp {
65+
return fmt.Errorf("%d is an invalid pull mode", pm)
66+
}
67+
err := rp.gpioSetPinFunction(pin, 1)
68+
if err != nil {
69+
return fmt.Errorf("couldn't set pin as output: %v", err)
70+
}
71+
72+
// See p101 for the description of this procedure.
73+
rp.gpio.pud = uint32(pm)
74+
time.Sleep(10 * time.Microsecond) // Datasheet says to sleep for 150 cycles after setting pud
75+
reg := pin / 32
76+
offset := uint(pin % 32)
77+
rp.gpio.pudclk[reg] = 1 << offset
78+
time.Sleep(10 * time.Microsecond) // Datasheet says to sleep for 150 cycles after setting pudclk
79+
rp.gpio.pud = 0
80+
rp.gpio.pudclk[reg] = 0
81+
return nil
82+
}
83+
84+
func (rp *RPi) gpioSetAltFunction(pin int, alt int) error {
4185
funcs := []uint32{4, 5, 6, 7, 3, 2} // See p92 in datasheet - these are the alt functions only
4286
if alt >= len(funcs) {
4387
return fmt.Errorf("%d is an invalid alt function", alt)
4488
}
45-
46-
rp.gpio.fsel[reg] &= ^(0x7 << offset)
47-
rp.gpio.fsel[reg] |= (funcs[alt]) << offset
48-
return nil
89+
return rp.gpioSetPinFunction(pin, funcs[alt])
4990
}
5091

5192
func (rp *RPi) InitGPIO() error {

rpi/pwm.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func (rp *RPi) InitPWM(freq uint, buf *DMABuf, bytes uint, pins []int) error {
7474
if !ok {
7575
return fmt.Errorf("invalid pin %d for PWM channel %d", pin, channel)
7676
}
77-
rp.gpioFunctionSet(pin, alt)
77+
rp.gpioSetAltFunction(pin, alt)
7878
}
7979

8080
if rp.pwmBuf == nil {

0 commit comments

Comments
 (0)