How to turn on/off GPIOs in BBB

1,120 views
Skip to first unread message

matt

unread,
Feb 12, 2014, 7:14:38 AM2/12/14
to beagl...@googlegroups.com
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;
}

Micka

unread,
Feb 12, 2014, 8:25:45 AM2/12/14
to beagl...@googlegroups.com
you should watch this video => https://www.youtube.com/watch?v=wui_wU1AeQc
Enjoy,


--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

matt

unread,
Feb 12, 2014, 3:04:34 PM2/12/14
to beagl...@googlegroups.com
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.

Brandon I

unread,
Feb 17, 2014, 5:12:51 AM2/17/14
to beagl...@googlegroups.com
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.

bogao3037

unread,
Feb 25, 2014, 1:23:43 PM2/25/14
to beagl...@googlegroups.com
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 <iostream>
#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

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

 

bogao3037

unread,
Feb 25, 2014, 1:47:49 PM2/25/14
to beagl...@googlegroups.com

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
gpio.h
Reply all
Reply to author
Forward
0 new messages