Skip to content

Commit 904f4f9

Browse files
author
Aleksei Fedotov
committed
Add conversion from physical PIN to BCM notation.
On Open() detect the board model and configure how physical PINs are mapped to GPIO pin numbers [1]. Model detection is based on content of /sys/firmware/devicetree/base/model [2] . If you are running a weird or very old system which does not have the file, GetBoardPin() won't work. [1] https://pinout.xyz/ [2] https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
1 parent a36b96d commit 904f4f9

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ pin.Mode(rpio.Output) // Alternative syntax
6161
pin.Write(rpio.High) // Alternative syntax
6262
```
6363

64+
If you prefer using physical pin numbers instead of BCM notation, call GetBoardPin():
65+
66+
```go
67+
// Physical pin 19 is mapped to BCM pin 10, so this two lines are quivalent
68+
69+
pin := rpio.GetBoardPin(19)
70+
pin := rpio.Pin(10)
71+
72+
```
73+
6474
Pull up/down/off can be set using:
6575

6676
```go

rpio.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ import (
7575
"syscall"
7676
"time"
7777
"unsafe"
78+
"io/ioutil"
79+
"fmt"
7880
)
7981

8082
type Mode uint8
@@ -625,6 +627,38 @@ func backupIRQs() {
625627
irqsBackup = uint64(intrMem[irqEnable2])<<32 | uint64(intrMem[irqEnable1])
626628
}
627629

630+
var pin_to_gpio_rev1 = [26]int {-1, -1, 0, -1, 1, -1, 4, 14, -1, 15, 17, 18, 21, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7};
631+
var pin_to_gpio_rev2 = [40]int {-1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
632+
var pin_to_gpio_rev3 = [40]int {-1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, 5, -1, 6, 12, 13, -1, 19, 16, 26, 20, -1, 21 };
633+
634+
var pin_to_gpio []int = nil;
635+
func initGPIOconversion () (error) {
636+
file, err := os.Open("/sys/firmware/devicetree/base/model")
637+
if err != nil {
638+
return err
639+
}
640+
641+
defer file.Close()
642+
643+
model, err := ioutil.ReadAll(file)
644+
if err != nil {
645+
return err
646+
}
647+
648+
switch string(bytes.TrimRight(model, "\000")) {
649+
case "Raspberry Pi Model B Rev 1" :
650+
pin_to_gpio = pin_to_gpio_rev1[0:26];
651+
case "Raspberry Pi Model B Rev 2" :
652+
pin_to_gpio = pin_to_gpio_rev2[0:40];
653+
case "Raspberry Pi Model A Rev 2" :
654+
pin_to_gpio = pin_to_gpio_rev2[0:40];
655+
default :
656+
pin_to_gpio = pin_to_gpio_rev3[0:40];
657+
}
658+
659+
return nil
660+
}
661+
628662
// Open and memory map GPIO memory range from /dev/mem .
629663
// Some reflection magic is used to convert it to a unsafe []uint32 pointer
630664
func Open() (err error) {
@@ -676,6 +710,7 @@ func Open() (err error) {
676710

677711
backupIRQs() // back up enabled IRQs, to restore it later
678712

713+
initGPIOconversion()
679714
return nil
680715
}
681716

@@ -734,3 +769,12 @@ func getBase() (base int64) {
734769
}
735770
return int64(out)
736771
}
772+
773+
// Convert GPIO number from physical PIN to BCM convention
774+
func GetBoardPin(board_pin int) (Pin, error) {
775+
if board_pin < 1 || len(pin_to_gpio) < board_pin || pin_to_gpio[board_pin - 1] == -1 {
776+
return Pin(0xff), fmt.Errorf("Pin %d is not wired", board_pin)
777+
}
778+
779+
return Pin(pin_to_gpio[board_pin - 1]), nil
780+
}

0 commit comments

Comments
 (0)