How to turn on/off GPIOs in BBB

Hi,

I got a BBB.

I connected a LED to its GPIO1_16 pin, which I tried to turn on and off using the GPIO configuration in the code below.

For some reason the LED does not turn ON.

When I use the same GPIO pin, but using the Virtual File System code to turn on the LED, it works.

Therefore I guess i’m missing something with the below code.

Do you spot any problem?

Thanks a lot.

`
#define GPIO1_BASE 0x4804C000 // Start Address
#define GPIO1_END 0x4804D000 // End Address
#define GPIO1_SIZE GPIO_END - GPIO_BASE
#define GPIO_OE 0x0134 // Offset
#define GPIO_DATAOUT 0x013C // Offset
#define GPIO1_16 16

int main(int argc, char** argv)
{
volatile unsigned int *reg_base, *reg_oe, *reg_out;
unsigned int value;
int fd;

//open mem file for Read and Write
fd = open("/dev/mem", O_RDWR);
if (fd == -1)
{
perror(“Unable to open /dev/mem”);
exit(EXIT_FAILURE);
}

/* LED Setup and Turn-on */
reg_base = mmap(0, GPIO1_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE);

//Set GPIO to Output
reg_oe = (volatile unsigned int*)(reg_base + GPIO_OE);
value = *(reg_oe);
value &= ~(1 << GPIO1_16);
*(reg_oe) = value;

//turn on GPIO
reg_out = (volatile unsigned int*)(GPIO1_16 + GPIO_DATAOUT);
value = *(reg_out);
value |= (1 << GPIO1_16);
*(reg_out) = value;

return 0;
}
`

you should watch this video => https://www.youtube.com/watch?v=wui_wU1AeQc
Enjoy,

Hi,
Thanks!
it was said there to change the Pad Control Register,

However, it didn’t see how one changes this Register.

How is it accessed please?

Thank you.

Pad control registers can only be changed in kernel space. You could write a kernel driver or do it the right way and use device tree.

See

https://github.com/nomel/beaglebone/tree/master/gpio-header

If you don't want to use it directly, you can use the generated files as an example.

I am using C++ and mmap to access GPIO. Following is the code I am using.

----------------------------------------------gpio.h --------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include “gpio.h”

using namespace std;

// The number is indicating which GPIO Module(0-3) of
// each pin belongs to.
//
const int BeagleGPIO::pinBank =
{
-1, -1, 1, 1, 1, // P8_1 → P8_5
1, 2, 2, 2, 2, // P8_6 → P8_10
1, 1, 0, 0, 1, // P8_11 → P8_15
1, 0, 2, 0, 1, // P8_16 → P8_20
1, 1, 1, 1, 1, // P8_21 → P8_25
1, 2, 2, 2, 2, // P8_26 → P8_30
0, 0, 0, 2, 0, // P8_31 → P9_35
2, 2, 2, 2, 2, // P8_36 → P8_40
2, 2, 2, 2, 2, // P8_41 → P8_45
2, // P8_46
-1, -1, -1, -1, -1, // P9_1 → P9_5
-1, -1, -1, -1, -1, // P9_6 → P9_10
0, 1, 0, 1, 1, // P9_11 → P9_15
1, 0, 0, 0, 0, // P9_16 → P9_20
0, 0, 1, 0, 3, // P9_21 → P9_25
0, 3, 3, 3, 3, // P9_26 → P9_30
3, -1, -1, -1, -1, // P9_31 → P9_35
-1, -1, -1, -1, -1, // P9_36 → P9_40
0, 0, -1, -1, -1, // P9_41 → P9_45
-1 // P9_46
};

// Pin ID: if it is -1, it means that it is not a GPIO pin
// If it is a GPIO Pin, the number is indicating the position
// of GPIO_DATAIN and GPIO_DATAOUT registers.
const int BeagleGPIO::pinId =
{
-1, -1, 6, 7, 2, // P8_1 → P8_5
3, 2, 3, 5, 4, // P8_6 → P8_10
13, 12, 23, 26, 15, // P8_11 → P8_15
14, 27, 1, 22, 31, // P8_16 → P8_20
30, 5, 4, 1, 0, // P8_21 → P8_25
29, 22, 24, 23, 25, // P8_26 → P8_30
10, 11, 9, 17, 8, // P8_31 → P9_35
16, 14, 15, 12, 13, // P8_36 → P8_40
10, 11, 8, 9, 6, // P8_41 → P8_45
7, // P8_46
-1, -1, -1, -1, -1, // P9_1 → P9_5
-1, -1, -1, -1, -1, // P9_6 → P9_10
30, 28, 31, 18, 16, // P9_11 → P9_15
19, 5, 4, 13, 12, // P9_16 → P9_20
3, 2, 17, 15, 21, // P9_21 → P9_25
14, 19, 17, 15, 16, // P9_26 → P9_30
14, -1, -1, -1, -1, // P9_31 → P9_35
-1, -1, -1, -1, -1, // P9_36 → P9_40
20, 7, -1, -1, -1, // P9_41 → P9_45
-1 // P9_46
};

// Pad Control Register
// The addresses of registers, which control the Pin Mux of
// each GPIO Pins
const unsigned long BeagleGPIO::padControl =
{
0x0000, 0x0000, 0x0818, 0x081C, 0x0808, // P8_1 → P8_5
0x080C, 0x0890, 0x0894, 0x089C, 0x0898, // P8_6 → P8_10
0x0834, 0x0830, 0x0824, 0x0828, 0x083C, // P8_11 → P8_15
0x0838, 0x082C, 0x088C, 0x0820, 0x0884, // P8_16 → P8_20
0x0880, 0x0814, 0x0810, 0x0804, 0x0800, // P8_21 → P8_25
0x087C, 0x08E0, 0x08E8, 0x08E4, 0x08EC, // P8_26 → P8_30
0x08D8, 0x08DC, 0x08D4, 0x08CC, 0x08D0, // P8_31 → P8_35
0x08C8, 0x08C0, 0x08C4, 0x08B8, 0x08BC, // P8_36 → P8_40
0x08B0, 0x08B4, 0x08A8, 0x08AC, 0x08A0, // P8_41 → P8_45
0x08A4, // P8_46
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // P9_1 → P9_5
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // P9_6 → P9_10
0x0870, 0x0878, 0x0874, 0x0848, 0x0840, // P9_11 → P9_15
0x084C, 0x095C, 0x0958, 0x097C, 0x0978, // P9_16 → P9_20
0x0954, 0x0950, 0x0844, 0x0984, 0x09AC, // P9_21 → P9_25
0x0980, 0x09A4, 0x099C, 0x0994, 0x0998, // P9_26 → P9_30
0x0990, 0x0000, 0x0000, 0x0000, 0x0000, // P9_31 → P9_35
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // P9_36 → P9_40
0x09B4, 0x0964, 0x0000, 0x0000, 0x0000, // P9_41 → P9_45
0x0000 // P9_46
};

// Control Module Registers: Please refer to Memory Map of
// AM335x MCU
const unsigned long BeagleGPIO::ctrlModuleReg = 0x44E10000;

// GPIO Module registers
const unsigned long BeagleGPIO::GpioBaseReg =
{
0x44E07000, // GPIO0
0x4804C000, // GPIO1
0x481AC000, // GPIO2
0x481AE000 // GPIO3
};

//=======================================================
//=======================================================

BeagleGPIO::BeagleGPIO()
{

// Not initialized by default
mActive = false;

system(“echo 5 > /sys/class/gpio/export > /dev/null”);
system(“echo 65 > /sys/class/gpio/export > /dev/null”);
system(“echo 105 > /sys/class/gpio/export > /dev/null”);

// Opening /dev/mem first
m_gpio_fd = open( “/dev/mem”, O_RDWR | O_SYNC );
if ( m_gpio_fd < 0 )
{
GPIO_ERROR( “Cannot open /dev/mem” );
return;
}

// Map Control Module
mControlModule = (unsigned long *)mmap( NULL, 0x1FFF, PROT_READ | PROT_WRITE, MAP_SHARED, m_gpio_fd, ctrlModuleReg );
if ( mControlModule == MAP_FAILED )
{
GPIO_ERROR( “Control Module Mapping failed” );
return;
}

// Now mapping the GPIO registers
for ( int i=0; i<4; ++i)
{
// Map a GPIO bank
m_gpio[i] = (unsigned long *)mmap( NULL, 0xFFF, PROT_READ | PROT_WRITE, MAP_SHARED, m_gpio_fd, GpioBaseReg[i] );
if ( m_gpio[i] == MAP_FAILED )
{
GPIO_ERROR( "GPIO Mapping failed for GPIO Module " << i );
return;
}
}

// Init complete and successfull
mActive = true;

}

//-------------------------------------------------------
//
//Disstructor
//
//-------------------------------------------------------
BeagleGPIO::~BeagleGPIO()
{
if ( mActive && m_gpio_fd)
close( m_gpio_fd );
}

//-------------------------------------------------------
//
// Configure pin as input/output
//
//-------------------------------------------------------
BeagleGPIO::Status BeagleGPIO::configPin( unsigned short _pin, Direction _direction )
{
if ( !mActive )
return kFail;

//assert(pinBank[_pin]>=0);
//assert(pinId[_pin]>=0);

// Set Pin as GPIO on the pad control
mControlModule[padControl[_pin]/4] |= 0x07;

unsigned long v = 0x1 << pinId[_pin];

if ( _direction == kINPUT)
{
m_gpio[pinBank[_pin]][kOE/4] |= v;
}
else
{
m_gpio[pinBank[_pin]][kOE/4] &= ~v;
}

// Disable Interrupts by default
m_gpio[pinBank[_pin]][kIRQSTATUS_CLR_0/4] |= v;
m_gpio[pinBank[_pin]][kIRQSTATUS_CLR_1/4] |= v;

return kSuccess;
}

//-------------------------------------------------------
//
//! Write a value to a Pin
//
//! return status
//
//-------------------------------------------------------
BeagleGPIO::Status BeagleGPIO::writePin( unsigned short _pin, unsigned char _value )
{
//assert(pinBank[_pin]>=0);
//assert(pinId[_pin]>=0);

unsigned long v = (_value & 0x01) << pinId[_pin];
unsigned long mask = 0x1 << pinId[_pin];

// Remove bit
m_gpio[pinBank[_pin]][kDATAOUT/4] &= ~mask;
// Assign new bit value
m_gpio[pinBank[_pin]][kDATAOUT/4] |= v;

return kSuccess;
}

//-------------------------------------------------------
//
// Read a value from a pin
//
//-------------------------------------------------------
unsigned char BeagleGPIO::readPin( unsigned short _pin )
{
//assert(pinBank[_pin]>=0);
//assert(pinId[_pin]>=0);

unsigned long bit = pinId[_pin];
return (m_gpio[pinBank[_pin]][kDATAIN/4] & (0x1 << bit)) >> bit;
}

------------------------gpio,h -----------------------------------
//=======================================================
//=======================================================

#ifndef GPIO_H
#define GPIO_H

//=======================================================
//=======================================================

#include
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

//=======================================================
//=======================================================

#define GPIO_ERROR(msg) std::cout << "[GPIO] Error : " << msg << std::endl;

#define GPIO_PRINT(msg)

//=======================================================
//=======================================================

class BeagleGPIO
{
public:
// Return status
typedef enum
{
kFail = 0,
kSuccess = 1
} Status;

// Beagle Bone GPIO Register Offsets
enum
{
kREVISION = 0x0,
kSYSCONFIG = 0x10,
kIRQSTATUS_RAW_0 = 0x24,
kIRQSTATUS_RAW_1 = 0x28,
kIRQSTATUS_0 = 0x2C,
kIRQSTATUS_1 = 0x30,
kIRQSTATUS_SET_0 = 0x34,
kIRQSTATUS_SET_1 = 0x38,
kIRQSTATUS_CLR_0 = 0x3C,
kIRQSTATUS_CLR_1 = 0x40,
kIRQWAKEN_0 = 0x44,
kIRQWAKEN_1 = 0x48,
kSYSSTATUS = 0x114,
kCTRL = 0x130,
kOE = 0x134,
kDATAIN = 0x138,
kDATAOUT = 0x13C,
kLEVELDETECT0 = 0x140,
kLEVELDETECT1 = 0x144,
kRISINGDETECT = 0x148,
kFALLINGDETECT = 0x14C,
kDEBOUNCEENABLE = 0x150,
kDEBOUNCINGTIME = 0x154,
kCLEARDATAOUT = 0x190,
kSETDATAOUT = 0x194
} Registers;

// Input/Output pin mode
typedef enum
{
kINPUT = 0,
kOUTPUT = 1
} Direction;

// GPIO Pins
enum
{
P8_1, P8_2, P8_3, P8_4, P8_5,
P8_6, P8_7, P8_8, P8_9, P8_10,
P8_11, P8_12, P8_13, P8_14, P8_15,
P8_16, P8_17, P8_18, P8_19, P8_20,
P8_21, P8_22, P8_23, P8_24, P8_25,
P8_26, P8_27, P8_28, P8_29, P8_30,
P8_31, P8_32, P8_33, P8_34, P8_35,
P8_36, P8_37, P8_38, P8_39, P8_40,
P8_41, P8_42, P8_43, P8_44, P8_45,
P8_46,
P9_1, P9_2, P9_3, P9_4, P9_5,
P9_6, P9_7, P9_8, P9_9, P9_10,
P9_11, P9_12, P9_13, P9_14, P9_15,
P9_16, P9_17, P9_18, P9_19, P9_20,
P9_21, P9_22, P9_23, P9_24, P9_25,
P9_26, P9_27, P9_28, P9_29, P9_30,
P9_31, P9_32, P9_33, P9_34, P9_35,
P9_36, P9_37, P9_38, P9_39, P9_40,
P9_41, P9_42, P9_43, P9_44, P9_45,
P9_46
} GPIO_Pins;

// IO Banks for GPIOs
static const int pinBank;

// Pin Id for GPIOs
static const int pinId;

// Pad Control Register
static const unsigned long padControl;

// Base address of Control Module Registers
static const unsigned long ctrlModuleReg;

// Base addresses of GPIO Modules
static const unsigned long GpioBaseReg;

public:
BeagleGPIO();
~BeagleGPIO();

public:
// Configure pin as input/output
Status configPin( unsigned short _pin, Direction _direction );

// Write a value to a pin
Status writePin( unsigned short _pin, unsigned char _value );

// Read a value from a pin
unsigned char readPin( unsigned short _pin );

// Is this Module active ?
bool IsActive() { return mActive; }

private:
bool mActive;
int m_gpio_fd;
unsigned long * mControlModule;
unsigned long * m_gpio[4];

};

//=======================================================
//=======================================================

#endif

//=======================================================
//=======================================================

Sorry the first file’s name should be gpio.cpp.

The code I have posted is based on the code at the following link: https://github.com/majestik666/Beagle_GPIO/blob/master/Beagle_GPIO.cc.

I have attached my files(gpio.cpp and gpio.h) and hope it could help you. One thing I want to remind you is that in my code I added the following
“system(“echo 5 > /sys/class/gpio/export > /dev/null”);
system(“echo 65 > /sys/class/gpio/export > /dev/null”);
system(“echo 105 > /sys/class/gpio/export > /dev/null”);”.

gpio.cpp (6.57 KB)

gpio.h (3.59 KB)