New GPIO libraries


22 posts
by Mike McCauly » Sun Jun 24, 2012 9:53 am
Hi all,

I have uploaded 2 new GPIO support libraries for RPi:

- bcm2835 is a C library for Raspberry Pi (RPi). It provides access to
GPIO and other IO functions on the Broadcom BCM 2835 chip,
allowing access to the GPIO pins on the
26 pin IDE plug on the RPi board so you can control and interface with various external devices.

Full doc and downloads from http://www.open.com.au/mikem/bcm2835

- Device::BCM2835 is a perl wrapper for the above library. Its available from CPAN in the usual perlish way.

Feedback and suggestions to me please.
Posts: 8
Joined: Sun Jun 24, 2012 9:47 am
by panik » Sun Jun 24, 2012 9:40 pm
Nice. I tried the bcm2835 C library, and had a pretty smooth experience.

blink.c: Worked the first time. I used another pin, but that's it.
input.c: You might want to comment out line 29: bcm2845_set_debug(1) by default. That bit me (softly).
event.c: Again the debug. Also, line 39: bcm2845_gpio_len(RPI_GPIO_PIN_15), instead of bcm2845_gpio_len(PIN). That one bit me a little bit harder. But just a little.

I have a debounce capacitor on my input pin, and a pullup resistor. Commenting bcm2845_gpio_set_pud(PIN, BCM2835_GPIO_PUD_UP) made no difference (obviously). I'm not desoldering my setup to test this further, if you don't mind ;)

I'll have a better look at it later. Just received my Pi, and there's so much to try. Thanks!
User avatar
Posts: 273
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands
by Mike McCauly » Sun Jun 24, 2012 9:49 pm
Hi,

thanks for the feedback.
Fixes for the issues you mentioned have been uploaded in new version 1.1

BTW, look for SPI support soon.

Cheers.

panik wrote:Nice. I tried the bcm2835 C library, and had a pretty smooth experience.

blink.c: Worked the first time. I used another pin, but that's it.
input.c: You might want to comment out line 29: bcm2845_set_debug(1) by default. That bit me (softly).
event.c: Again the debug. Also, line 39: bcm2845_gpio_len(RPI_GPIO_PIN_15), instead of bcm2845_gpio_len(PIN). That one bit me a little bit harder. But just a little.

I have a debounce capacitor on my input pin, and a pullup resistor. Commenting bcm2845_gpio_set_pud(PIN, BCM2835_GPIO_PUD_UP) made no difference (obviously). I'm not desoldering my setup to test this further, if you don't mind ;)

I'll have a better look at it later. Just received my Pi, and there's so much to try. Thanks!
Posts: 8
Joined: Sun Jun 24, 2012 9:47 am
by pygmy_giant » Sun Jun 24, 2012 10:39 pm
God bless you sir.
Ostendo ignarus addo scientia.
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by panik » Mon Jun 25, 2012 9:56 pm
Thanks for the fast reply and update. Looking forward to SPI!

In event.c, on line 39, changing the 'len' to 'hen', to detect a high instead of a low, showed the expected behaviour (but only after a reboot, it seems).

I haven't managed to detect a rising or falling edge. Could it be the debounce capacitor making the transition too smooth? Do I need a Schmitt trigger? I often wish I had formal training for this stuff. And more time. And a scope. And not be an idiot.

I was also planning to ask about the discrepancy in the bcm2835 versus bcm2845 prefix, but you seem to have changed that already :) Thanks again!
User avatar
Posts: 273
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands
by Mike McCauly » Tue Jun 26, 2012 4:11 am
Thanks again,

SPI support functions now added to both the bcm2835 C library and the Device::BCM2835 perl library. All the other issues you reported should be OK now.

Please let me know if there are any further issues

panik wrote:Thanks for the fast reply and update. Looking forward to SPI!

In event.c, on line 39, changing the 'len' to 'hen', to detect a high instead of a low, showed the expected behaviour (but only after a reboot, it seems).

I haven't managed to detect a rising or falling edge. Could it be the debounce capacitor making the transition too smooth? Do I need a Schmitt trigger? I often wish I had formal training for this stuff. And more time. And a scope. And not be an idiot.

I was also planning to ask about the discrepancy in the bcm2835 versus bcm2845 prefix, but you seem to have changed that already :) Thanks again!
Posts: 8
Joined: Sun Jun 24, 2012 9:47 am
by Mike McCauly » Tue Jun 26, 2012 7:58 am
New version 1.3 now with spi_transfern() which can transfer any number of bytes by SPI. Similar in Device::BCM2835 1.3

panik: I tested OK here with both + and - going edges.

Mike McCauly wrote:Thanks again,

SPI support functions now added to both the bcm2835 C library and the Device::BCM2835 perl library. All the other issues you reported should be OK now.

Please let me know if there are any further issues

panik wrote:Thanks for the fast reply and update. Looking forward to SPI!

In event.c, on line 39, changing the 'len' to 'hen', to detect a high instead of a low, showed the expected behaviour (but only after a reboot, it seems).

I haven't managed to detect a rising or falling edge. Could it be the debounce capacitor making the transition too smooth? Do I need a Schmitt trigger? I often wish I had formal training for this stuff. And more time. And a scope. And not be an idiot.

I was also planning to ask about the discrepancy in the bcm2835 versus bcm2845 prefix, but you seem to have changed that already :) Thanks again!
Posts: 8
Joined: Sun Jun 24, 2012 9:47 am
by selsinork » Tue Jun 26, 2012 6:17 pm
Hi Mike,

I really like the idea of a library, and a perl interface to it rather than a python one is even better :)

but.... (there's always a but...)

it would be much nicer if it would use the underlying linux drivers instead of going directly to /dev/mem

lots of reasons, but consider this simple one, the kernel driver 'owns' the addresses you're writing to and can modify them at any time without telling you, so your lib is part way through setting something up, the kernel reschedules your process and some other code gets to run, that code uses the kernel driver to access a gpio, the kernel driver then modifies the gpio registers which it's perfectly entitled to do as it owns them. Your code now fails, as it doesn't know what's been modified, and it likely fails randomly or there's unforseen side effects.

So the RPi already has a generic kernel gpio driver, it's user for things like blinking the OK led on sdcard access. Details of how to use the kernel driver from kernelspace or userspace here http://git.kernel.org/?p=linux/kernel/g ... n/gpio.txt (the userspace stuff through sysfs is towards the bottom) there are even some patches posted to add interrupt capability here viewtopic.php?f=44&t=7509

One of the useful parts about using the kernel drivers is that someone can add an spi or i2c gpio expander, load it's kernel driver and your code would just work with the additional gpios..

Also, It seems that the official kernel might become bootc's 3.2.20 sometime soon at which point there will be i2c and spi drivers in the kernel that your lib could conflict with too.

So again, love the idea, especially the perl bit... just think it could be so much better if it played nice with the kernel drivers as well.
Posts: 151
Joined: Mon Apr 16, 2012 8:31 am
by panik » Wed Jun 27, 2012 4:25 pm
Mike McCauly wrote:panik: I tested OK here with both + and - going edges.

I have the rising and falling edge detection working now too. With and without a Schmitt trigger. That was probably just me making things more complicated than they actually are. I do need to reboot after making "detection-type" changes in the code, which complicated the testing a little bit. But when it works, it works. Thanks!
User avatar
Posts: 273
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands
by DaveTheWalker » Wed Jul 04, 2012 9:07 pm
That's fantastic - thanks! Got it all working nicely. Any plans to get I2C working next?...

Dave
Posts: 34
Joined: Wed Jul 04, 2012 9:06 pm
by pjc123 » Fri Jul 06, 2012 8:33 pm
Could someone take the installation instructions for the library and parse out each command, because I think my install failed. I am guessing it is because I am not separating the commands out properly during the installation. The error I get when trying to run one of the example programs is that it can not find the header file.

tar zxvf bcm2835-1.0.tar.gz cd bcm2835-1.0 ./configure make # as root: make check make install

I am reading this as:

tar zxvf bcm2835-1.0.tar.gz (Worked)
cd bcm2835-1.0 (Worked)
./configure make # (Ran, but not sure the syntax is correct)
make check make install (Ran, but not sure the syntax is right)

I saved the output of the screen for all these commands, so if it is more involved than an error in one of these lines, I can include that as well. Also, do I need to uninstall everything and reinstall to clean up anything?

The last I did any programming in "C" was 15 years ago, and I threw away all my old books. I would just like to try this out before I order a more updated book to brush up.
Posts: 910
Joined: Thu Mar 29, 2012 3:37 pm
by pjc123 » Fri Jul 06, 2012 11:48 pm
Never mind. After searching the internet, I see that the correct commands are.......

./configure
make
make check
make install

Works great. Thanks for supplying the library......that must of took quite a bit of work.
Posts: 910
Joined: Thu Mar 29, 2012 3:37 pm
by Chewy » Sat Jul 07, 2012 2:18 pm
Excellent job Mike.

I've been playing with the perl module Device::BCM2835. I found the CPAN module was impossible to install using CPAN command line, it kept complaining about yaml but after an hour of fiddling I gave up and installed them manually.

I'm playing with basic I/O at the moment and can report that both work fine for me. I can detect switches being pushed and light up LEDs from perl, nothing very adventurous yet but if the fundamentals work the rest will follow.

If anyone would care for snippets of my code as a hint or whatever then please shout.
Posts: 12
Joined: Fri Mar 09, 2012 11:34 pm
by pjc123 » Tue Jul 10, 2012 12:08 am
Mike,

I have a question. I am using pullup resistors on my external GPIO input port circuitry, so for your example program "event.c" I figured I should comment out the pullup resistor code (BCM2835_GPIO_PUD_UP). That worked, but is the reason because the default setting is BCM2835_GPIO_PUD_OFF? If so, maybe I will specifically set it to off in my code for my own sake of clarity.

Thanks.
Posts: 910
Joined: Thu Mar 29, 2012 3:37 pm
by tonyzhang78 » Fri Jul 20, 2012 9:29 pm
Mike,
When I used function 'delayMicroseconds(50)' in my program, I found the real delay time on osciloscope is around 125 microsecond.
Posts: 2
Joined: Fri Jul 20, 2012 9:14 pm
by pygmy_giant » Sun Oct 07, 2012 4:08 pm
Hi

This is also just what I'm looking for and was wondering if anyone can help me with 4 questions:

1) I can't get this to install under Raspbian despite being in Super User mode ('Access Denied') so I'm just bunging the .h and .c files in the same folder as my calling code - is that OK?

2) does this method circumvent linux and so make it suitable for use on the bare metal?

3) how do I use the code to enable pull-ups?

4) I read on the google group that the latest addition is 1.10 while only 1.8 is available from the website - where can I get the latest stable release?

Any help appreciated - thanks in advance .... :)
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by richtoy » Mon Oct 15, 2012 8:41 pm
Posts: 11
Joined: Tue Jun 05, 2012 8:35 pm
by gordon@drogon.net » Mon Oct 15, 2012 9:16 pm
tonyzhang78 wrote:Mike,
When I used function 'delayMicroseconds(50)' in my program, I found the real delay time on osciloscope is around 125 microsecond.


Mike originally copied my original delay() and delayMicroseconds() from wiringPi (without attribution, nor care for the fact that wiringPi was GPLv3 at the time), so yes, it's somewhat sub-optimal as my versions were sub-optimal too. f you want better timing, use the new ones in wiringPi, however I do notice he's now changed the ones in the .10 release, so they should be more accurate.

Mike also originally copied all the /dev/mem setup code from wiringPi - which I'd adapted (but not strictly copied) from Gert/Dom's code. Again, attribution would have been nice, but he's subsequently changed it somewhat. Still some of my original comments in the current code though.

I am mildly irritated by all this, but at the end of the day, it's all the more to promote the Pi's GPIO, so what the heck. Mike is from Austrailia, afterall... ;-)

-Gordon
--
Gordons projects: https://projects.drogon.net/
User avatar
Posts: 1543
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
by pjc123 » Tue Oct 16, 2012 3:52 pm
gordon@drogon.net wrote:I am mildly irritated by all this, but at the end of the day, it's all the more to promote the Pi's GPIO, so what the heck. Mike is from Austrailia, afterall... ;-)
-Gordon


Since you are both from Australia, may I suggest that you head over to Bartertown and solve this issue in the Thunderdome. "Two programmers enter, one programmer leave".
Posts: 910
Joined: Thu Mar 29, 2012 3:37 pm
by gordon@drogon.net » Tue Oct 16, 2012 4:00 pm
pjc123 wrote:
gordon@drogon.net wrote:I am mildly irritated by all this, but at the end of the day, it's all the more to promote the Pi's GPIO, so what the heck. Mike is from Austrailia, afterall... ;-)
-Gordon


Since you are both from Australia, may I suggest that you head over to Bartertown and solve this issue in the Thunderdome. "Two programmers enter, one programmer leave".


I'm from Scotland. (and currently live in England)

-Gordon
--
Gordons projects: https://projects.drogon.net/
User avatar
Posts: 1543
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
by AnalogArsonist » Sun Nov 25, 2012 10:48 pm
This library looks like a lot of fun and exactly what I wanted but I'm having trouble installing it. When I run the 'make' command I get the following error:

Code: Select all
root@raspberrypi:/home/pi/bcm2835-1.12# make
make  all-recursive
make[1]: Entering directory `/home/pi/bcm2835-1.12'
Making all in src
make[2]: Entering directory `/home/pi/bcm2835-1.12/src'
gcc -DHAVE_CONFIG_H -I. -I..     -g -O2 -MT bcm2835.o -MD -MP -MF .deps/bcm2835.Tpo -c -o bcm2835.o bcm2835.c
bcm2835.c: In function âbcm2835_delayMicrosecondsâ:
bcm2835.c:342: error: âCLOCK_MONOTONIC_RAWâ undeclared (first use in this function)
bcm2835.c:342: error: (Each undeclared identifier is reported only once
bcm2835.c:342: error: for each function it appears in.)
make[2]: *** [bcm2835.o] Error 1
make[2]: Leaving directory `/home/pi/bcm2835-1.12/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/pi/bcm2835-1.12'
make: *** [all] Error 2


I just upgraded the GPU firmware and raspbian using this link: http://raspberrypi.stackexchange.com/questions/164/how-do-i-update-software-and-firmware

Code: Select all
root@raspberrypi:/home/pi/bcm2835-1.12/src# uname -a
Linux raspberrypi 3.2.27+ #285 PREEMPT Tue Nov 20 17:49:40 GMT 2012 armv6l GNU/Linux


I googled the missing function and appears that it's defined in time.h which should be part of the kernel, right? Can anyone help me, please? Do I need to compile the kernel again?

Thanks, Ben
Posts: 5
Joined: Sat Mar 10, 2012 3:45 am
by AnalogArsonist » Tue Dec 04, 2012 5:35 pm
The conversation has been moved to http://groups.google.com/group/bcm2835 as it says on his website.
Posts: 5
Joined: Sat Mar 10, 2012 3:45 am