BBB GPIO and parallel output of more pins

Hi everyone,

i need to use a group of pins (up to 8 pins) to output a value in a certain range but i wonder if there is a way to be sure that all output pins are set at the same time.
Otherwise i would have an unspecified output value during the transition between a value to another. I read somewhere that is possible set an entire bank instead
of a single pin, maybe using PRU ?
I would be very grateful if someone could address me to solve this problem.

Thank you.

Did you ever find out how to do this? I have the same requirement and can’t seem to find an answer as to how to do this

Yes, but for me the simplest way was using a port expander (i used MCP23008) through I2C Interface, very simple to handle with BBB.

Hi,

Ok Robert, i will try to explain how i solved my problem, apologise me if something is not clear but i am not an expert and i beg anyone to correct me if i say something wrong.
I2C is a serial protocol and is fully supported by BBB so you can set output pins (8 pins) of MCP23008 setting a chip’s register once the chip is connected and initialized. When you set your output serial data all chip’s output pins are set at the same time (because there is an internal synchronized register).

So, if you need to set 4 pins with 1101 you can set chip’s register with 00001101 value e then you find the value 1101 at the chip’s output pins.

You don’t need to set your GPIO to use the MCP23008 because P9_19 (CLK) and P9_20 (SDA) are already set to work with I2C protocol (at least in debian Wheezy) and all you need is assign an unique address (connecting address pins to GND or VCC) to every MCP23008 chip you connect to these pins (is a bus).

Take a look at these links, i think i started from there :

http://embedded-lab.com/blog/?p=2834

http://www.gigamegablog.com/2012/11/04/beaglebone-coding-101-i2c/

Pretty funny that there are 2 Robert Berger’s with the same question!

But thanks a lot Mirko for the explanation. That may help my situation as we do have the opportunity to add some hardware.

I did find a way to do parallel writes to the GPIO by doing direct access of the GPIO registers instead of going the the /sysfs filesystem access. Unfortunately I could not find a way to do this with Ruby without creating a C extension. (I spent all day yesterday trying! Looks like the existing mmap gems for ruby are all obsolete and don’t work with Ruby 2.x and/or won’t map in /dev/mem)

A good description of the solution is at http://elinux.org/EBC_Exercise_11b_gpio_via_mmap

It has some C examples of how to do it natively and shows how you can use devmem2 to do it in the shell command line.

For Ruby

if you’re update rate was low, you could shell out to devmem2 to do parallel writes:

For instance to get the 32bit value (that’s how big the registers are) at 0x4804c13c

value = devmem2 0x4804c13c
That would show you what the bits are for gpio1

To clear the bits in the pattern 0x01000000 in the GPIO_CLEARDATAOUT register

result = devmem2 0x4804c190 w 0x01000000

That would turn the USR3 LED off if it was on

To set the bit pattern in GPIO_SETDATAOUT (0x194) register

result = devmem2 0x4804c194 w 0x01000000

That would turn the USR3 LED on

To turn on USR1 and USR 3 at the same time:

result = devmem2 0x4804c194 w 0x01400000

You could do the same to a group of other gpio pins as long as they are all on the gpio 32 bit register

Getting devmem2

Turns out that devmem2 is not a Debian package (though it is an Ubuntu package) but you can get the source at http://www.lartmaker.nl/lartware/port/devmem2.c
and compile and install it with:

gcc devmem2.c -o devmem2
chmod a+x devmem2
mv devmem2 /usr/local/bin

I’m memory mapping GPIO so I can run some GPIO pins MUCH faster than doing it through the file system. (340 nsec versus 80 usec) You can use those GPIO_CLEARDATA and GPIO_SETDATA registers to either turn on or turn off multiple bits at once, but there are two important limitations:

  1. You can turn on any number of bits, or turn off any number of bits, but you can’t do both at once. Use GPIO_DATAOUT to write all 32 bits at once (and GPIO_DATAIN to read before writing so you don’t change the bits you are not using.)
  2. Each GPIO_CLEARDATA and GPIO_SETDATA register is only for a single GPIO. There are four GPIOs and the expansion header pin numbers have no relationship with which GPIO and bit number within that GPIO you need to toggle. So it is unlikely all your pins are connected to a single GPIO. For instance, I’m using P9.11 and P9.12 and they are on GPIO0 and GPIO1.