Skip to content

Add conversion from physical PIN to BCM notation. #59

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ pin.Mode(rpio.Output) // Alternative syntax
pin.Write(rpio.High) // Alternative syntax
```

If you prefer using physical pin numbers instead of BCM notation, call GetBoardPin():

```go
// Physical pin 19 is mapped to BCM pin 10, so this two lines are quivalent

pin := rpio.GetBoardPin(19)
pin := rpio.Pin(10)

```

Pull up/down/off can be set using:

```go
Expand Down
12 changes: 7 additions & 5 deletions examples/blinker/blinker.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ import (
"time"
)

var (
// Use mcu pin 10, corresponds to physical pin 19 on the pi
pin = rpio.Pin(10)
)

func main() {
// Open and map memory to access gpio, check for errors
if err := rpio.Open(); err != nil {
Expand All @@ -32,6 +27,13 @@ func main() {
// Unmap gpio memory when done
defer rpio.Close()

// Use physical pin 19, mappings to GPIO numers are done internally
pin, err := rpio.GetBoardPin(19)
if err != nil {
fmt.Println(err)
os.Exit(1)
}

// Set pin to output mode
pin.Output()

Expand Down
44 changes: 44 additions & 0 deletions rpio.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ import (
"syscall"
"time"
"unsafe"
"io/ioutil"
"fmt"
)

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

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};
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 };
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 };

var pin_to_gpio []int = nil;
func initGPIOconversion () (error) {
file, err := os.Open("/sys/firmware/devicetree/base/model")
if err != nil {
return err
}

defer file.Close()

model, err := ioutil.ReadAll(file)
if err != nil {
return err
}

switch string(bytes.TrimRight(model, "\000")) {
case "Raspberry Pi Model B Rev 1" :
pin_to_gpio = pin_to_gpio_rev1[0:26];
case "Raspberry Pi Model B Rev 2" :
pin_to_gpio = pin_to_gpio_rev2[0:40];
case "Raspberry Pi Model A Rev 2" :
pin_to_gpio = pin_to_gpio_rev2[0:40];
default :
pin_to_gpio = pin_to_gpio_rev3[0:40];
}

return nil
}

// Open and memory map GPIO memory range from /dev/mem .
// Some reflection magic is used to convert it to a unsafe []uint32 pointer
func Open() (err error) {
Expand Down Expand Up @@ -676,6 +710,7 @@ func Open() (err error) {

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

initGPIOconversion()
return nil
}

Expand Down Expand Up @@ -734,3 +769,12 @@ func getBase() (base int64) {
}
return int64(out)
}

// Convert GPIO number from physical PIN to BCM convention
func GetBoardPin(board_pin int) (Pin, error) {
if board_pin < 1 || len(pin_to_gpio) < board_pin || pin_to_gpio[board_pin - 1] == -1 {
return Pin(0xff), fmt.Errorf("Pin %d is not wired", board_pin)
}

return Pin(pin_to_gpio[board_pin - 1]), nil
}