From acd8baadbf34b65fafd09091fb56ff13c7a057b9 Mon Sep 17 00:00:00 2001 From: Adam Kramer Date: Sat, 7 Mar 2015 17:57:06 -0800 Subject: [PATCH] Support the new IO port range for raspberry pi 2. --- rpio.go | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/rpio.go b/rpio.go index c02353f..a6eb505 100644 --- a/rpio.go +++ b/rpio.go @@ -56,6 +56,8 @@ http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pd package rpio import ( + "bytes" + "io/ioutil" "os" "reflect" "sync" @@ -72,9 +74,12 @@ type Pull uint8 // Memory offsets for gpio, see the spec for more details const ( bcm2835Base = 0x20000000 - gpioBase = bcm2835Base + 0x200000 + pi1GPIOBase = bcm2835Base + 0x200000 memLength = 4096 + bcm2836Base = 0x3f000000 + pi2GPIOBase = bcm2836Base + 0x200000 + pinMask uint32 = 7 // 0b111 - pinmode is 3 bits ) @@ -277,10 +282,15 @@ func Open() (err error) { memlock.Lock() defer memlock.Unlock() + GPIOBase := int64(pi1GPIOBase) + if detectPiVersion() == 2 { + GPIOBase = pi2GPIOBase + } + // Memory map GPIO registers to byte array mem8, err = syscall.Mmap( int(file.Fd()), - gpioBase, + GPIOBase, memLength, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED) @@ -305,3 +315,21 @@ func Close() error { defer memlock.Unlock() return syscall.Munmap(mem8) } + +// Read /proc/cpuinfo and detect whether we're running on an RPI1 or RPI2. +// Returns 1 or 2 depending on platform. +func detectPiVersion() int { + cpuinfo, err := os.Open("/proc/cpuinfo") + if err != nil { + panic(err) + } + data, err := ioutil.ReadAll(cpuinfo) + if err != nil { + panic(err) + } + if bytes.Contains(data, []byte("BCM2709")) { + return 2 + } else { + return 1 + } +}