This 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.
It provides functions for reading digital inputs and setting digital outputs, using SPI and I2C, and for accessing the system timers. Pin event detection is supported by polling (interrupts are not supported).
It is C++ compatible, and installs as a header file and non-shared library on any Linux-based distro (but clearly is no use except on Raspberry Pi or another board with BCM 2835).
The version of the package that this documentation refers to can be downloaded from http://www.airspayce.com/mikem/bcm2835/bcm2835-1.36.tar.gz You can find the latest version at http://www.airspayce.com/mikem/bcm2835
Several example programs are provided.
Based on data in http://elinux.org/RPi_Low-level_peripherals and http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf and http://www.scribd.com/doc/101830961/GPIO-Pads-Control2
You can also find online help and discussion at http://groups.google.com/group/bcm2835 Please use that group for all questions and discussions on this topic. Do not contact the author directly, unless it is to discuss commercial licensing.
Tested on debian6-19-04-2012, 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian and Occidentalisv01 CAUTION: it has been observed that when detect enables such as bcm2835_gpio_len() are used and the pin is pulled LOW it can cause temporary hangs on 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian and Occidentalisv01. Reason for this is not yet determined, but we suspect that an interrupt handler is hitting a hard loop on those OSs. If you must use bcm2835_gpio_len() and friends, make sure you disable the pins with bcm2835_gpio_clr_len() and friends after use.
This library consists of a single non-shared library and header file, which will be installed in the usual places by make install
The functions bcm2835_peri_read(), bcm2835_peri_write() and bcm2835_peri_set_bits() are low level peripheral register access functions. They are designed to use physical addresses as described in section 1.2.3 ARM physical addresses of the BCM2835 ARM Peripherals manual. Physical addresses range from 0x20000000 to 0x20FFFFFF for peripherals. The bus addresses for peripherals are set up to map onto the peripheral bus address range starting at 0x7E000000. Thus a peripheral advertised in the manual at bus address 0x7Ennnnnn is available at physical address 0x20nnnnnn.
The base address of the various peripheral registers are available with the following externals: bcm2835_gpio bcm2835_pwm bcm2835_clk bcm2835_pads bcm2835_spio0 bcm2835_st bcm2835_bsc0 bcm2835_bsc1
The GPIO pin numbering as used by RPi is different to and inconsistent with the underlying BCM 2835 chip pin numbering. http://elinux.org/RPi_BCM2835_GPIOs
RPi has a 26 pin IDE header that provides access to some of the GPIO pins on the BCM 2835, as well as power and ground pins. Not all GPIO pins on the BCM 2835 are available on the IDE header.
RPi Version 2 also has a P5 connector with 4 GPIO pins, 5V, 3.3V and Gnd.
The functions in this library are designed to be passed the BCM 2835 GPIO pin number and not the RPi pin number. There are symbolic definitions for each of the available pins that you should use for convenience. See RPiGPIOPin.
The bcm2835_spi_* functions allow you to control the BCM 2835 SPI0 interface, allowing you to send and received data by SPI (Serial Peripheral Interface). For more information about SPI, see http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
When bcm2835_spi_begin() is called it changes the bahaviour of the SPI interface pins from their default GPIO behaviour in order to support SPI. While SPI is in use, you will not be able to control the state of the SPI pins through the usual bcm2835_spi_gpio_write(). When bcm2835_spi_end() is called, the SPI pins will all revert to inputs, and can then be configured and controled with the usual bcm2835_gpio_* calls.
The Raspberry Pi GPIO pins used for SPI are:
The bcm2835_i2c_* functions allow you to control the BCM 2835 BSC interface, allowing you to send and received data by I2C ("eye-squared cee"; generically referred to as "two-wire interface") . For more information about I?C, see http://en.wikipedia.org/wiki/I%C2%B2C
The Raspberry Pi V2 GPIO pins used for I2C are:
The BCM2835 supports hardware PWM on a limited subset of GPIO pins. This bcm2835 library provides functions for configuring and controlling PWM output on these pins.
The BCM2835 contains 2 independent PWM channels (0 and 1), each of which be connnected to a limited subset of GPIO pins. The following GPIO pins may be connected to the following PWM channels (from section 9.5):
In order for a GPIO pin to emit output from its PWM channel, it must be set to the Alt Function given above. Note carefully that current versions of the Raspberry Pi only expose one of these pins (GPIO 18 = RPi Pin 1-12) on the IO headers, and therefore this is the only IO pin on the RPi that can be used for PWM. Further it must be set to ALT FUN 5 to get PWM output.
Both PWM channels are driven by the same PWM clock, whose clock dvider can be varied using bcm2835_pwm_set_clock(). Each channel can be separately enabled with bcm2835_pwm_set_mode(). The average output of the PWM channel is determined by the ratio of DATA/RANGE for that channel. Use bcm2835_pwm_set_range() to set the range and bcm2835_pwm_set_data() to set the data in that ratio
Each PWM channel can run in either Balanced or Mark-Space mode. In Balanced mode, the hardware sends a combination of clock pulses that results in an overall DATA pulses per RANGE pulses. In Mark-Space mode, the hardware sets the output HIGH for DATA clock pulses wide, followed by LOW for RANGE-DATA clock pulses.
The PWM clock can be set to control the PWM pulse widths. The PWM clock is derived from a 19.2MHz clock. You can set any divider, but some common ones are provided by the BCM2835_PWM_CLOCK_DIVIDER_* values of bcm2835PWMClockDivider.
For example, say you wanted to drive a DC motor with PWM at about 1kHz, and control the speed in 1/1024 increments from 0/1024 (stopped) through to 1024/1024 (full on). In that case you might set the clock divider to be 16, and the RANGE to 1024. The pulse repetition frequency will be 1.2MHz/1024 = 1171.875Hz.
The bcm2835 is a library for user programs (i.e. they run in 'userland'). Such programs are not part of the kernel and are usually subject to paging and swapping by the kernel while it does other things besides running your program. This means that you should not expect to get real-time performance or real-time timing constraints from such programs. In particular, there is no guarantee that the bcm2835_delay() and bcm2835_delayMicroseconds() will return after exactly the time requested. In fact, depending on other activity on the host, IO etc, you might get significantly longer delay times than the one you asked for. So please dont expect to get exactly the time delay you request.
Arjan reports that you can prevent swapping on Linux with the following code fragment:
mikem has made Perl bindings available at CPAN: http://search.cpan.org/~mikem/Device-BCM2835-1.9/lib/Device/BCM2835.pm Matthew Baker has kindly made Python bindings available at: https://github.com/mubeta06/py-libbcm2835 Gary Marks has created a Serial Peripheral Interface (SPI) command-line utility for Raspberry Pi, based on the bcm2835 library. The utility, spincl, is licensed under Open Source GNU GPLv3 by iP Solutions (http://ipsolutionscorp.com), as a free download with source included: http://ipsolutionscorp.com/raspberry-pi-spi-utility/
This is the appropriate option if you want to share the source code of your application with everyone you distribute it to, and you also want to give them the right to share who uses it. If you wish to use this software under Open Source Licensing, you must contribute all your source code to the open source community in accordance with the GPL Version 2 when your application is distributed. See http://www.gnu.org/copyleft/gpl.html and COPYING
Some of this code has been inspired by Dom and Gert. The I2C code has been inspired by Alan Barr.