bcm2835 H
bcm2835 H
h
C and C++ support for Broadcom BCM 2835 as used in Raspberry Pi
Author: Mike McCauley
Copyright (C) 2011-2013 Mike McCauley
$Id: bcm2835.h,v 1.20 2015/03/31 04:55:41 mikem Exp mikem $
*/
/*! \mainpage C library for Broadcom BCM 2835 as used in Raspberry Pi
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 anothe
r 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.48.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 licensi
ng.
Before asking a question or reporting a bug, please read http://www.catb.org/e
sr/faqs/smart-questions.html
Tested on debian6-19-04-2012, 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-ra
spbian
and Occidentalisv01
CAUTION: it has been observed that when detect enables such as bcm2835_gpio_le
n()
are used and the pin is pulled LOW
it can cause temporary hangs on 2012-07-15-wheezy-raspbian, 2013-07-26-wheezyraspbian
and Occidentalisv01.
Reason for this is not yet determined, but we suspect that an interrupt handle
r 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.
\par Installation
This library consists of a single non-shared library and header file, which wi
ll be
installed in the usual places by make install
\code
# download the latest version of the library, say bcm2835-1.xx.tar.gz, then:
tar zxvf bcm2835-1.xx.tar.gz
cd bcm2835-1.xx
./configure
make
sudo make check
sudo make install
\endcode
\par Physical Addresses
The functions bcm2835_peri_read(), bcm2835_peri_write() and bcm2835_peri_set_b
its()
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 bu
s
addresses for peripherals are set up to map onto the peripheral bus address ra
nge starting at
0x7E000000. Thus a peripheral advertised in the manual at bus address 0x7Ennnn
nn is available at
physical address 0x20nnnnnn.
On RPI 2, the peripheral addresses are different and the bcm2835 library gets
them
from reading /proc/device-tree/soc/ranges. This is only availble with recent v
ersions of the kernel on RPI 2.
After initialisation, 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
\par Raspberry Pi 2 (RPI2)
For this library to work correctly on RPI2, you MUST have the device tree supp
ort enabled in the kernel.
You should also ensure you are using the latest version of Linux. The library
has been tested on RPI2
with 2015-02-16-raspbian-wheezy and ArchLinuxARM-rpi-2 as of 2015-03-29.
When device tree suport is enabled, the file /proc/device-tree/soc/ranges will
appear in the file system,
and the bcm2835 module relies on its presence to correctly run on RPI2 (it is
optional for RPI1).
Without device tree support enabled and the presence of this file, it will not
work on RPI2.
To enable device tree support:
\code
sudo raspi-config
under Advanced Options - enable Device Tree
Reboot.
\endcode
\par Pin Numbering
The GPIO pin numbering as used by RPi is different to and inconsistent with th
e 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 t
he BCM 2835,
as well as power and ground pins. Not all GPIO pins on the BCM 2835 are availa
ble 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 p
ins
that you should use for convenience. See \ref RPiGPIOPin.
\par SPI Pins
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_Periph
eral_Interface_Bus
When bcm2835_spi_begin() is called it changes the bahaviour of the SPI interfa
ce 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:
-
P1-19
P1-21
P1-23
P1-24
P1-26
(MOSI)
(MISO)
(CLK)
(CE0)
(CE1)
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
\par Acknowledgements
Some of this code has been inspired by Dom and Gert.
The I2C code has been inspired by Alan Barr.
\par Revision History
\version 1.0 Initial release
\version 1.1 Minor bug fixes
\version 1.2 Added support for SPI
\version 1.3 Added bcm2835_spi_transfern()
\version 1.4 Fixed a problem that prevented SPI CE1 being used. Reported by Da
vid Robinson.
\version 1.5 Added bcm2835_close() to deinit the library. Suggested by C?sar O
rtiz
\version 1.6 Document testing on 2012-07-15-wheezy-raspbian and Occidentalisv0
1
Functions bcm2835_gpio_ren(), bcm2835_gpio_fen(), bcm2835_gpio_hen()
bcm2835_gpio_len(), bcm2835_gpio_aren() and bcm2835_gpio_afen() now
changes only the pin specified. Other pins that were already previously
enabled stay enabled.
Added bcm2835_gpio_clr_ren(), bcm2835_gpio_clr_fen(), bcm2835_gpio_clr_hen()
bcm2835_gpio_clr_len(), bcm2835_gpio_clr_aren(), bcm2835_gpio_clr_afen()
to clear the enable for individual pins, suggested by Andreas Sundstrom.
\version 1.7 Added bcm2835_spi_transfernb to support different buffers for rea
d and write.
\version 1.8 Improvements to read barrier, as suggested by maddin.
\version 1.9 Improvements contributed by mikew:
I noticed that it was mallocing memory for the mmaps on /dev/mem.
It's not necessary to do that, you can just mmap the file directly,
so I've removed the mallocs (and frees).
I've also modified delayMicroseconds() to use nanosleep() for long waits,
and a busy wait on a high resolution timer for the rest. This is because
I've found that calling nanosleep() takes at least 100-200 us.
You need to link using '-lrt' using this version.
I've added some unsigned casts to the debug prints to silence compiler
warnings I was getting, fixed some typos, and changed the value of
BCM2835_PAD_HYSTERESIS_ENABLED to 0x08 as per Gert van Loo's doc at
http://www.scribd.com/doc/101830961/GPIO-Pads-Control2
Also added a define for the passwrd value that Gert says is needed to
change pad control settings.
\version 1.10 Changed the names of the delay functions to bcm2835_delay()
and bcm2835_delayMicroseconds() to prevent collisions with wiringPi.
Macros to map delay()-> bcm2835_delay() and
Macros to map delayMicroseconds()-> bcm2835_delayMicroseconds(), which
can be disabled by defining BCM2835_NO_DELAY_COMPATIBILITY
\version 1.11 Fixed incorrect link to download file
\version 1.12 New GPIO pin definitions for RPi version 2 (which has a differen
t GPIO mapping)
\version 1.13 New GPIO pin definitions for RPi version 2 plug P5
Hardware base pointers are now available (after initialisation) externally as
bcm2835_gpio
bcm2835_pwm bcm2835_clk bcm2835_pads bcm2835_spi0.
\version 1.14 Now compiles even if CLOCK_MONOTONIC_RAW is not available, uses
CLOCK_MONOTONIC instead.
Fixed errors in documentation of SPI divider frequencies based on 250MHz clock
.
Reported by Ben Simpson.
\version 1.15 Added bcm2835_close() to end of examples as suggested by Mark Wo
lfe.
\version 1.16 Added bcm2835_gpio_set_multi, bcm2835_gpio_clr_multi and bcm2835
_gpio_write_multi
to allow a mask of pins to be set all at once. Requested by Sebastian Loncar.
\version 1.17 Added bcm2835_gpio_write_mask. Requested by Sebastian Loncar.
\version 1.18 Added bcm2835_i2c_* functions. Changes to bcm2835_delayMicroseco
nds:
now uses the RPi system timer counter, instead of clock_gettime, for improved
accuracy.
No need to link with -lrt now. Contributed by Arjan van Vught.
\version 1.19 Removed inlines added by previous patch since they don't seem to
work everywhere.
Reported by olly.
\version 1.20 Patch from Mark Dootson to close /dev/mem after access to the pe
ripherals has been granted.
\version 1.21 delayMicroseconds is now not susceptible to 32 bit timer overrun
s.
Patch courtesy Jeremy Mortis.
\version 1.22 Fixed incorrect definition of BCM2835_GPFEN0 which broke the abi
lity to set
falling edge events. Reported by Mark Dootson.
\version 1.23 Added bcm2835_i2c_set_baudrate and bcm2835_i2c_read_register_rs.
Improvements to bcm2835_i2c_read and bcm2835_i2c_write functions
to fix ocasional reads not completing. Patched by Mark Dootson.
\version 1.24 Mark Dootson p[atched a problem with his previously submitted co
de
under high load from other processes.
\version 1.25 Updated author and distribution location details to airspayce.co
m
\version 1.26 Added missing unmapmem for pads in bcm2835_close to prevent a me
mory leak.
Reported by Hartmut Henkel.
\version 1.27 bcm2835_gpio_set_pad() no longer needs BCM2835_PAD_PASSWRD: it i
s
now automatically included.
Added suport for PWM mode with bcm2835_pwm_* functions.
\version 1.28 Fixed a problem where bcm2835_spi_writenb() would have problems
with transfers of more than
64 bytes dues to read buffer filling. Patched by Peter Wrtz.
\version 1.29 Further fix to SPI from Peter Wrtz.
\version 1.30 10 microsecond delays from bcm2835_spi_transfer and bcm2835_spi_
transfern for
significant performance improvements, Patch by Alan Watson.
\version 1.31 Fix a GCC warning about dummy variable, patched by Alan Watson.
Thanks.
\version 1.32 Added option I2C_V1 definition to compile for version 1 RPi.
By default I2C code is generated for the V2 RPi which has SDA1 and SCL1 connec
ted.
Contributed by Malcolm Wiles based on work by Arvi Govindaraj.
\version 1.33 Added command line utilities i2c and gpio to examples. Contribut
ed by Shahrooz Shahparnia.
\version 1.34 Added bcm2835_i2c_write_read_rs() which writes an arbitrary numb
er of bytes,
sends a repeat start, and reads from the device. Contributed by Eduardo Steinh
orst.
\version 1.35 Fix build errors when compiled under Qt. Also performance improv
ements with SPI transfers. Contributed b Udo Klaas.
\version 1.36 Make automake's test runner detect that we're skipping tests whe
n not root, the second
one makes us skip the test when using fakeroot (as used when building
Debian packages). Contributed by Guido Gnther.
\version 1.37 Moved confiure.in to configure.ac as receommnded by autoreconf.<
br>
Improvements to bcm2835_st_read to account for possible timer overflow, contri
buted by 'Ed'.<br>
Added definitions for Raspberry Pi B+ J8 header GPIO pins.<br>
\version 1.38 Added bcm2835_regbase for the benefit of C# wrappers, patch by F
rank Hommers <br>
\version 1.39 Beta version of RPi2 compatibility. Not tested here on RPi2 hard
ware.
Testers please confirm correct operation on RPi2.<br>
Unneccessary 'volatile' qualifiers removed from all variables and signatures.<
br>
Removed unsupportable PWM dividers, based on a report from Christophe Cecillon
.<br>
Minor improvements to spi.c example.<br>
\version 1.40 Correct operation on RPi2 has been confirmed.<br>
Fixed a number of compiler errors and warnings that occur when bcm2835.h is in
cluded
in code compiled with -Wall -Woverflow -Wstrict-overflow -Wshadow -Wextra -ped
antic.
Reported by tlhackque.<br>
Fixed a problem where calling bcm2835_delayMicroseconds loops forever when deb
ug is set. Reported by tlhackque.<br>
Reinstated use of volatile in 2 functions where there was a danger of lost rea
ds or writes. Reported by tlhackque.<br>
\version 1.41 Added BCM2835_VERSION macro and new function bcm2835_version();
Requested by tlhackque.<br>
Improvements to peripheral memory barriers as suggested by tlhackque.<br>
Reinstated some necessary volatile declarations as requested by tlhackque.<br>
\version 1.42 Further improvements to memory barriers with the patient assista
nce and patches of tlhackque.<br>
\version 1.43 Fixed problems with compiling barriers on RPI 2 with Arch Linux
and gcc 4.9.2.
Reported and patched by Lars Christensen.<br>
Testing on RPI 2, with ArchLinuxARM-rpi-2-latest and 2015-02-16-raspbian-wheez
y.<br>
\version 1.44 Added documention about the need for device tree to be enabled o
n RPI2.<br>
Improvements to detection of availablity of DMB instruction based on value of
__ARM_ARCH macro.<br>
\version 1.45 Fixed an error in the pad group offsets that would prevent bcm28
35_gpio_set_pad()
and bcm2835_gpio_pad() working correctly with non-0 pad groups. Reported by Gu
ido.
\version 1.46 2015-09-18
Added symbolic definitions for remaining pins on 40 pin GPIO header o
n RPi 2. <br>
\version 1.47 2015-11-18
Fixed possibly incorrect reads in bcm2835_i2c_read_register_rs, patch from Eck
hardt Ulrich.<br>
\version 1.48 2015-12-08
Added patch from Eckhardt Ulrich that fixed problems that could cause hanging
with bcm2835_i2c_read_register_rs
and others.
\author Mike McCauley ([email protected]) DO NOT CONTACT THE AUTHOR DIRECTL
Y: USE THE LISTS
*/
/* Defines for BCM2835 */
#ifndef BCM2835_H
#define BCM2835_H
#include <stdint.h>
#define BCM2835_VERSION 10048 /* Version 1.48 */
/* RPi 2 is ARM v7, and has DMB instruction for memory barriers.
Older RPis are ARM v6 and don't, so a coprocessor instruction must be used in
stead.
However, not all versions of gcc in all distros support the dmb assembler ins
truction even on conmpatible processors.
This test is so any ARMv7 or higher processors with suitable GCC will use DMB
.
*/
#if __ARM_ARCH >= 7
#define BCM2835_HAVE_DMB
#endif
/*! \defgroup constants Constants for passing to and from library functions
The values here are designed to be passed to various functions in the bcm2835
library.
@{
*/
/*! This means pin HIGH, true, 3.3volts on a pin. */
#define HIGH 0x1
/*! This means pin LOW, false, 0volts on a pin. */
#define LOW 0x0
/*! Speed of the core clock core_clk */
#define BCM2835_CORE_CLK_HZ
250000000
/*! On RPi2 with BCM2836, and all recent OSs, the base of the peripherals is rea
d from a /proc file */
#define BMC2835_RPI2_DT_FILENAME "/proc/device-tree/soc/ranges"
/*! Offset into BMC2835_RPI2_DT_FILENAME for the peripherals base address */
#define BMC2835_RPI2_DT_PERI_BASE_ADDRESS_OFFSET 4
/*! Offset into BMC2835_RPI2_DT_FILENAME for the peripherals size address */
#define BMC2835_RPI2_DT_PERI_SIZE_OFFSET 8
/*! Physical addresses for various peripheral register sets
Base Physical Address of the BCM 2835 peripheral registers
Note this is different for the RPi2 BCM2836, where this is derived from /proc/
device-tree/soc/ranges
If /proc/device-tree/soc/ranges exists on a RPi 1 OS, it would be expected to
contain the
following numbers:
*/
/*! Peripherals block base address on RPi 1 */
#define BCM2835_PERI_BASE
0x20000000
/*! Size of the peripherals block on RPi 1 */
#define BCM2835_PERI_SIZE
0x01000000
/*! Offsets for the bases of various peripherals within the peripherals block
/ Base Address of the System Timer registers
*/
#define BCM2835_ST_BASE
0x3000
/*! Base Address of the Pads registers */
#define BCM2835_GPIO_PADS
0x100000
/*! Base Address of the Clock/timer registers */
#define BCM2835_CLOCK_BASE
0x101000
/*! Base Address of the GPIO registers */
#define BCM2835_GPIO_BASE
0x200000
/*! Base Address of the SPI0 registers */
#define BCM2835_SPI0_BASE
0x204000
/*! Base Address of the BSC0 registers */
#define BCM2835_BSC0_BASE
0x205000
/*! Base Address of the PWM registers */
#define BCM2835_GPIO_PWM
0x20C000
/*! Base Address of the BSC1 registers */
#define BCM2835_BSC1_BASE
0x804000
/*! Physical address and size of the peripherals block
May be overridden on RPi2
*/
extern uint32_t *bcm2835_peripherals_base;
/*! Size of the peripherals block to be mapped */
extern uint32_t bcm2835_peripherals_size;
/*! Virtual memory address of the mapped peripherals block */
extern uint32_t *bcm2835_peripherals;
/*! Base of the ST (System Timer) registers.
Available after bcm2835_init has been called
*/
extern volatile uint32_t *bcm2835_st;
/*! Base of the GPIO registers.
Available after bcm2835_init has been called
*/
extern volatile uint32_t *bcm2835_gpio;
/*! Base of the PWM registers.
Available after bcm2835_init has been called
*/
extern volatile uint32_t *bcm2835_pwm;
/*! Base of the CLK registers.
Available after bcm2835_init has been called
*/
extern volatile uint32_t *bcm2835_clk;
/*! Base of the PADS registers.
Available after bcm2835_init has been called
*/
extern volatile uint32_t *bcm2835_pads;
/*! Base of the SPI0 registers.
Available after bcm2835_init has been called
*/
extern volatile uint32_t *bcm2835_spi0;
(4*1024)
(4*1024)
#define BCM2835_GPLEV1
#define BCM2835_GPEDS0
tatus 0 */
#define BCM2835_GPEDS1
tatus 1 */
#define BCM2835_GPREN0
tect Enable 0 */
#define BCM2835_GPREN1
tect Enable 1 */
#define BCM2835_GPFEN0
etect Enable 0 */
#define BCM2835_GPFEN1
etect Enable 1 */
#define BCM2835_GPHEN0
able 0 */
#define BCM2835_GPHEN1
able 1 */
#define BCM2835_GPLEN0
ble 0 */
#define BCM2835_GPLEN1
ble 1 */
#define BCM2835_GPAREN0
Edge Detect 0 */
#define BCM2835_GPAREN1
Edge Detect 1 */
#define BCM2835_GPAFEN0
Edge Detect 0 */
#define BCM2835_GPAFEN1
Edge Detect 1 */
#define BCM2835_GPPUD
nable */
#define BCM2835_GPPUDCLK0
nable Clock 0 */
#define BCM2835_GPPUDCLK1
nable Clock 1 */
0b100 */
0b101 */
0b110, */
0b111 */
0b011 */
0b010 */
mask 0b111 */
} bcm2835PUDControl;
/*! Pad control register offsets from BCM2835_GPIO_PADS */
#define BCM2835_PADS_GPIO_0_27
0x002c /*!< Pad control register fo
r pads 0 to 27 */
#define BCM2835_PADS_GPIO_28_45
0x0030 /*!< Pad control register fo
r pads 28 to 45 */
#define BCM2835_PADS_GPIO_46_53
0x0034 /*!< Pad control register fo
r pads 46 to 53 */
/*! Pad Control masks */
#define BCM2835_PAD_PASSWRD
le setting pad mask */
#define BCM2835_PAD_SLEW_RATE_UNLIMITED
#define BCM2835_PAD_HYSTERESIS_ENABLED
#define BCM2835_PAD_DRIVE_2mA
#define BCM2835_PAD_DRIVE_4mA
#define BCM2835_PAD_DRIVE_6mA
#define BCM2835_PAD_DRIVE_8mA
#define BCM2835_PAD_DRIVE_10mA
#define BCM2835_PAD_DRIVE_12mA
#define BCM2835_PAD_DRIVE_14mA
#define BCM2835_PAD_DRIVE_16mA
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
RPI_GPIO_P1_07
RPI_GPIO_P1_08
tion 0 UART0_TXD */
RPI_GPIO_P1_10
tion 0 UART0_RXD */
RPI_GPIO_P1_11
RPI_GPIO_P1_12
in ALT FUN 5 */
RPI_GPIO_P1_13
RPI_GPIO_P1_15
RPI_GPIO_P1_16
RPI_GPIO_P1_18
RPI_GPIO_P1_19
e */
RPI_GPIO_P1_21
e */
RPI_GPIO_P1_22
RPI_GPIO_P1_23
*/
RPI_GPIO_P1_24
*/
RPI_GPIO_P1_26
*/
/* RPi Version 2 */
RPI_V2_GPIO_P1_03
RPI_V2_GPIO_P1_05
RPI_V2_GPIO_P1_07
RPI_V2_GPIO_P1_08
tion 0 UART0_TXD */
RPI_V2_GPIO_P1_10
tion 0 UART0_RXD */
RPI_V2_GPIO_P1_11
RPI_V2_GPIO_P1_12
in ALT FUN 5 */
RPI_V2_GPIO_P1_13
RPI_V2_GPIO_P1_15
RPI_V2_GPIO_P1_16
RPI_V2_GPIO_P1_18
RPI_V2_GPIO_P1_19
e */
RPI_V2_GPIO_P1_21
e */
RPI_V2_GPIO_P1_22
RPI_V2_GPIO_P1_23
*/
RPI_V2_GPIO_P1_24
*/
RPI_V2_GPIO_P1_26
*/
RPI_V2_GPIO_P1_29
RPI_V2_GPIO_P1_31
RPI_V2_GPIO_P1_32
RPI_V2_GPIO_P1_33
RPI_V2_GPIO_P1_35
RPI_V2_GPIO_P1_36
RPI_V2_GPIO_P1_37
RPI_V2_GPIO_P1_38
RPI_V2_GPIO_P1_40
21,
22,
23,
24,
10,
/*!<
/*!<
/*!<
/*!<
/*!<
Version
Version
Version
Version
Version
1,
1,
1,
1,
1,
Pin
Pin
Pin
Pin
Pin
P1-13 */
P1-15 */
P1-16 */
P1-18 */
P1-19, MOSI when SPI0 in us
=
=
=
=
2,
3,
4,
14,
/*!<
/*!<
/*!<
/*!<
Version
Version
Version
Version
2,
2,
2,
2,
Pin
Pin
Pin
Pin
P1-03 */
P1-05 */
P1-07 */
P1-08, defaults to alt func
27,
22,
23,
24,
10,
/*!<
/*!<
/*!<
/*!<
/*!<
Version
Version
Version
Version
Version
2,
2,
2,
2,
2,
Pin
Pin
Pin
Pin
Pin
P1-13 */
P1-15 */
P1-16 */
P1-18 */
P1-19, MOSI when SPI0 in us
5,
6,
12,
13,
19,
16,
26,
20,
21,
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
Version
Version
Version
Version
Version
Version
Version
Version
Version
2,
2,
2,
2,
2,
2,
2,
2,
2,
Pin
Pin
Pin
Pin
Pin
Pin
Pin
Pin
Pin
P1-29
P1-31
P1-32
P1-33
P1-35
P1-36
P1-37
P1-38
P1-40
*/
*/
*/
*/
*/
*/
*/
*/
*/
2,
2,
2,
2,
Pin
Pin
Pin
Pin
P5-03
P5-04
P5-05
P5-06
*/
*/
*/
*/
ity */
#define BCM2835_SPI0_CS_CSPOL1
ity */
#define BCM2835_SPI0_CS_CSPOL0
ity */
#define BCM2835_SPI0_CS_RXF
*/
#define BCM2835_SPI0_CS_RXR
eading (full) */
#define BCM2835_SPI0_CS_TXD
ept Data */
#define BCM2835_SPI0_CS_RXD
s Data */
#define BCM2835_SPI0_CS_DONE
*/
#define BCM2835_SPI0_CS_TE_EN
#define BCM2835_SPI0_CS_LMONO
#define BCM2835_SPI0_CS_LEN
#define BCM2835_SPI0_CS_REN
#define BCM2835_SPI0_CS_ADCS
Deassert Chip Select */
#define BCM2835_SPI0_CS_INTR
XR */
#define BCM2835_SPI0_CS_INTD
one */
#define BCM2835_SPI0_CS_DMAEN
#define BCM2835_SPI0_CS_TA
#define BCM2835_SPI0_CS_CSPOL
y */
#define BCM2835_SPI0_CS_CLEAR
and TX */
#define BCM2835_SPI0_CS_CLEAR_RX
*/
#define BCM2835_SPI0_CS_CLEAR_TX
*/
#define BCM2835_SPI0_CS_CPOL
#define BCM2835_SPI0_CS_CPHA
#define BCM2835_SPI0_CS_CS
/*!<
/*!<
/*!<
/*!<
/*!<
Unused */
Unused */
LEN LoSSI enable */
REN Read Enable */
ADCS Automatically
to be passed to bcm2835_spi_setDataMode()
/*!<
/*!<
/*!<
/*!<
CPOL
CPOL
CPOL
CPOL
=
=
=
=
0,
0,
1,
1,
CPHA
CPHA
CPHA
CPHA
=
=
=
=
0
1
0
1
*/
*/
*/
*/
#define
#define
#define
#define
eout */
BCM2835_BSC_FIFO
BCM2835_BSC_DIV
BCM2835_BSC_DEL
BCM2835_BSC_CLKT
0x0010
0x0014
0x0018
0x001c
/*!<
/*!<
/*!<
/*!<
BSC
BSC
BSC
BSC
Master
Master
Master
Master
Data FIFO */
Clock Divider */
Data Delay */
Clock Stretch Tim
/*!<
/*!<
/*!<
/*!<
Interrupt on RX */
Interrupt on TX */
Interrupt on DONE */
Start transfer, 1 = Star
BCM2835_I2C_REASON_ERROR_CLKT
meout */
BCM2835_I2C_REASON_ERROR_DATA
ceived */
} bcm2835I2CReasonCodes;
= 0x02,
= 0x04
/* Defines for ST
GPIO register offsets from BCM2835_ST_BASE.
Offsets into the ST Peripheral block in bytes per 12.1 System Timer Registers
The System Timer peripheral provides four 32-bit timer channels and a single
64-bit free running counter.
BCM2835_ST_CLO is the System Timer Counter Lower bits register.
The system timer free-running counter lower register is a read-only register
that returns the current value
of the lower 32-bits of the free running counter.
BCM2835_ST_CHI is the System Timer Counter Upper bits register.
The system timer free-running counter upper register is a read-only register
that returns the current value
of the upper 32-bits of the free running counter.
*/
#define BCM2835_ST_CS
0x0000 /*!< System Timer Control/Status
*/
#define BCM2835_ST_CLO
0x0004 /*!< System Timer Counter Lower 3
2 bits */
#define BCM2835_ST_CHI
0x0008 /*!< System Timer Counter Upper 3
2 bits */
/*! @} */
/* Defines for PWM, word offsets (ie 4 byte multiples) */
#define BCM2835_PWM_CONTROL 0
#define BCM2835_PWM_STATUS 1
#define BCM2835_PWM_DMAC
2
#define BCM2835_PWM0_RANGE 4
#define BCM2835_PWM0_DATA 5
#define BCM2835_PWM_FIF1
6
#define BCM2835_PWM1_RANGE 8
#define BCM2835_PWM1_DATA 9
/* Defines for PWM Clock, word
#define BCM2835_PWMCLK_CNTL
#define BCM2835_PWMCLK_DIV
#define BCM2835_PWM_PASSWRD
M clock */
#define
#define
#define
#define
#define
#define
#define
BCM2835_PWM1_MS_MODE
BCM2835_PWM1_USEFIFO
BCM2835_PWM1_REVPOLAR
BCM2835_PWM1_OFFSTATE
BCM2835_PWM1_REPEATFF
BCM2835_PWM1_SERIAL
BCM2835_PWM1_ENABLE
0x8000
0x2000
0x1000
0x0800
0x0400
0x0200
0x0100
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
#define
#define
#define
#define
#define
#define
BCM2835_PWM0_MS_MODE
BCM2835_PWM_CLEAR_FIFO
BCM2835_PWM0_USEFIFO
BCM2835_PWM0_REVPOLAR
BCM2835_PWM0_OFFSTATE
BCM2835_PWM0_REPEATFF
0x0080
0x0040
0x0020
0x0010
0x0008
0x0004
/*!<
/*!<
/*!<
/*!<
/*!<
/*!<
#define BCM2835_PWM0_SERIAL
#define BCM2835_PWM0_ENABLE
another peripheral
completes before this write is issued. The MB after ensures that subseque
nt reads and writes
to another peripheral will see the effect of this write.
This is a tricky optimization; if you aren't sure, use the barrier version
.
\param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
\param[in] value The 32 bit value to write
\sa Physical Addresses
*/
extern void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value);
/*! Writes 32 bit
You should only
o your code has
within the same
nce.
o your code has called bcm2835_memory_barrier() since the last access to A
NOTHER peripheral.
This is a tricky optimization; if you aren't sure, use the barrier version
.
\param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
\param[in] value The 32 bit value to write
\sa Physical Addresses
*/
extern void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value);
/*! Alters a number of bits in a 32 peripheral regsiter.
It reads the current valu and then alters the bits defines as 1 in mask,
according to the bit value in value.
All other bits that are 0 in the mask are unaffected.
Use this to alter a subset of the bits in a register.
Memory barriers are used. Note that this is not atomic; an interrupt
routine can cause unexpected results.
\param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
\param[in] value The 32 bit value to write, masked in by mask.
\param[in] mask Bitmask that defines the bits that will be altered in the
register.
\sa Physical Addresses
*/
extern void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value,
uint32_t mask);
/*! @}
end of lowlevel */
/*! \defgroup gpio GPIO register access
These functions allow you to control the GPIO interface. You can set the
function of each GPIO pin, read the input state and set the output state.
@{
*/
/*! Sets the Function Select register for the given pin, which configures
the pin as Input, Output or one of the 6 alternate functions.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
\param[in] mode Mode to set the pin to, one of BCM2835_GPIO_FSEL_* from \r
ef bcm2835FunctionSelect
*/
extern void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode);
/*! Sets the specified pin output to
HIGH.
*/
extern void bcm2835_gpio_set_eds(uint8_t pin);
/*! Same as bcm2835_gpio_set_eds() but clears the flag for any pin which
is set in the mask.
\param[in] mask Mask of pins to clear. Use eg: (1 << RPI_GPIO_P1_03) | (1
<< RPI_GPIO_P1_05)
*/
extern void bcm2835_gpio_set_eds_multi(uint32_t mask);
/*! Enable Rising Edge Detect Enable for the specified pin.
When a rising edge is detected, sets the appropriate pin in Event Detect S
tatus.
The GPRENn registers use
synchronous edge detection. This means the input signal is sampled using t
he
system clock and then it is looking for a ?011? pattern on the sampled sig
nal. This
has the effect of suppressing glitches.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_ren(uint8_t pin);
/*! Disable Rising Edge Detect Enable for the specified pin.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_clr_ren(uint8_t pin);
/*! Enable Falling Edge Detect Enable for the specified pin.
When a falling edge is detected, sets the appropriate pin in Event Detect
Status.
The GPRENn registers use
synchronous edge detection. This means the input signal is sampled using t
he
system clock and then it is looking for a ?100? pattern on the sampled sig
nal. This
has the effect of suppressing glitches.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_fen(uint8_t pin);
/*! Disable Falling Edge Detect Enable for the specified pin.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_clr_fen(uint8_t pin);
/*! Enable High Detect Enable for the specified pin.
When a HIGH level is detected on the pin, sets the appropriate pin in Even
t Detect Status.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_hen(uint8_t pin);
/*! Disable High Detect Enable for the specified pin.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_clr_hen(uint8_t pin);
/*! Enable Low Detect Enable for the specified pin.
When a LOW level is detected on the pin, sets the appropriate pin in Event
Detect Status.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_len(uint8_t pin);
/*! Disable Low Detect Enable for the specified pin.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_clr_len(uint8_t pin);
/*! Enable Asynchronous Rising Edge Detect Enable for the specified pin.
When a rising edge is detected, sets the appropriate pin in Event Detect S
tatus.
Asynchronous means the incoming signal is not sampled by the system clock.
As such
rising edges of very short duration can be detected.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_aren(uint8_t pin);
/*! Disable Asynchronous Rising Edge Detect Enable for the specified pin.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_clr_aren(uint8_t pin);
/*! Enable Asynchronous Falling Edge Detect Enable for the specified pin.
When a falling edge is detected, sets the appropriate pin in Event Detect
Status.
Asynchronous means the incoming signal is not sampled by the system clock.
As such
falling edges of very short duration can be detected.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_afen(uint8_t pin);
/*! Disable Asynchronous Falling Edge Detect Enable for the specified pin.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
*/
extern void bcm2835_gpio_clr_afen(uint8_t pin);
/*! Sets the Pull-up/down register for the given pin. This is
used with bcm2835_gpio_pudclk() to set the Pull-up/down resistor for the
given pin.
However, it is usually more convenient to use bcm2835_gpio_set_pud().
\param[in] pud The desired Pull-up/down mode. One of BCM2835_GPIO_PUD_* fr
om bcm2835PUDControl
\sa bcm2835_gpio_set_pud()
*/
extern void bcm2835_gpio_pud(uint8_t pud);
/*! Clocks the Pull-up/down value set earlier by bcm2835_gpio_pud() into the
pin.
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
\param[in] on HIGH to clock the value from bcm2835_gpio_pud() into the pin
.
LOW to remove the clock.
\sa bcm2835_gpio_set_pud()
*/
extern void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on);
/*! Reads and returns the Pad Control for the given GPIO group.
\param[in] group The GPIO pad group number, one of BCM2835_PAD_GROUP_GPIO_
*
\return Mask of bits from BCM2835_PAD_* from \ref bcm2835PadGroup
*/
extern uint32_t bcm2835_gpio_pad(uint8_t group);
/*! Sets the Pad Control for the given GPIO group.
\param[in] group The GPIO pad group number, one of BCM2835_PAD_GROUP_GPIO_
*
\param[in] control Mask of bits from BCM2835_PAD_* from \ref bcm2835PadGro
up. Note
that it is not necessary to include BCM2835_PAD_PASSWRD in the mask as thi
s
is automatically included.
*/
extern void bcm2835_gpio_set_pad(uint8_t group, uint32_t control);
/*! Delays for the specified number of milliseconds.
Uses nanosleep(), and therefore does not use CPU until the time is up.
However, you are at the mercy of nanosleep(). From the manual for nanoslee
p():
If the interval specified in req is not an exact multiple of the granulari
ty
underlying clock (see time(7)), then the interval will be
rounded up to the next multiple. Furthermore, after the sleep completes,
there may still be a delay before the CPU becomes free to once
again execute the calling thread.
\param[in] millis Delay in milliseconds
*/
extern void bcm2835_delay (unsigned int millis);
/*! Delays for the specified number of microseconds.
Uses a combination of nanosleep() and a busy wait loop on the BCM2835 syst
em timers,
However, you are at the mercy of nanosleep(). From the manual for nanoslee
p():
If the interval specified in req is not an exact multiple of the granulari
ty
underlying clock (see time(7)), then the interval will be
rounded up to the next multiple. Furthermore, after the sleep completes,
there may still be a delay before the CPU becomes free to once
again execute the calling thread.
For times less than about 450 microseconds, uses a busy wait on the System
Timer.
It is reported that a delay of 0 microseconds on RaspberryPi will in fact
result in a delay of about 80 microseconds. Your mileage may vary.
\param[in] micros Delay in microseconds
*/
extern void bcm2835_delayMicroseconds (uint64_t micros);
/*! Sets the output state of the specified pin
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
\param[in] on HIGH sets the output to HIGH and LOW to LOW.
*/
extern void bcm2835_gpio_write(uint8_t pin, uint8_t on);
/*! Sets any of the first 32 GPIO output pins specified in the mask to the s
tate given by on
\param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1
<< RPI_GPIO_P1_05)
\param[in] on HIGH sets the output to HIGH and LOW to LOW.
*/
extern void bcm2835_gpio_write_multi(uint32_t mask, uint8_t on);
/*! Sets the first 32 GPIO output pins specified in the mask to the value gi
ven by value
\param[in] value values required for each bit masked in by mask, eg: (1 <<
RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
\param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1
<< RPI_GPIO_P1_05)
*/
extern void bcm2835_gpio_write_mask(uint32_t value, uint32_t mask);
/*! Sets the Pull-up/down mode for the specified pin. This is more convenien
t than
clocking the mode in with bcm2835_gpio_pud() and bcm2835_gpio_pudclk().
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
\param[in] pud The desired Pull-up/down mode. One of BCM2835_GPIO_PUD_* fr
om bcm2835PUDControl
*/
extern void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud);
/*! @} */
/*! \defgroup spi SPI access
These functions let you use SPI0 (Serial Peripheral Interface) to
interface with an external SPI device.
@{
*/
/*! Start SPI operations.
Forces RPi SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0)
and P1-26 (CE1)
to alternate function ALT0, which enables those pins for SPI interface.
You should call bcm2835_spi_end() when all SPI funcitons are complete to r
eturn the pins to
their default functions
\sa bcm2835_spi_end()
*/
extern void bcm2835_spi_begin(void);
/*! End SPI operations.
SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (
CE1)
are returned to their default INPUT behaviour.
*/
extern void bcm2835_spi_end(void);
/*! Sets the SPI bit order
NOTE: has no effect. Not supported by SPI0.
Defaults to
\param[in] order The desired bit order, one of BCM2835_SPI_BIT_ORDER_*,
see \ref bcm2835SPIBitOrder
*/
extern void bcm2835_spi_setBitOrder(uint8_t order);
/*! Sets the SPI clock divider and therefore the
SPI clock speed.
\param[in] divider The desired SPI clock divider, one of BCM2835_SPI_CLOCK
_DIVIDER_*,
see \ref bcm2835SPIClockDivider
*/
extern void bcm2835_spi_setClockDivider(uint16_t divider);
/*! Sets the SPI data mode
Sets the clock polariy and phase
\param[in] mode The desired data mode, one of BCM2835_SPI_MODE*,
see \ref bcm2835SPIMode
*/
extern void bcm2835_spi_setDataMode(uint8_t mode);
/*! Sets the chip select pin(s)
When an bcm2835_spi_transfer() is made, the selected pin(s) will be assert
ed during the
transfer.
\param[in] cs Specifies the CS pins(s) that are used to activate the desir
ed slave.
One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
*/
extern void bcm2835_spi_chipSelect(uint8_t cs);
/*! Sets the chip select pin polarity for a given pin
When an bcm2835_spi_transfer() occurs, the currently selected chip select
pin(s)
will be asserted to the
value given by active. When transfers are not happening, the chip select p
in(s)
return to the complement (inactive) value.
\param[in] cs The chip select pin to affect
\param[in] active Whether the chip select pin is to be active HIGH
*/
extern void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active);
/*! Transfers one byte to and from the currently selected SPI slave.
Asserts the currently selected CS pins (as previously set by bcm2835_spi_c
hipSelect)
during the transfer.
Clocks the 8 bit value out on MOSI, and simultaneously clocks in data from
MISO.
Returns the read data byte from the slave.
Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls
manual
\param[in] value The 8 bit data byte to write to MOSI
\return The 8 bit byte simultaneously read from MISO
\sa bcm2835_spi_transfern()
*/
extern uint8_t bcm2835_spi_transfer(uint8_t value);
/*! Transfers any number of bytes to and from the currently selected SPI sla
ve.
Asserts the currently selected CS pins (as previously set by bcm2835_spi_c
hipSelect)
during the transfer.
Clocks the len 8 bit bytes out on MOSI, and simultaneously clocks in data
from MISO.
The data read read from the slave is placed into rbuf. rbuf must be at lea
st len bytes long
Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls
manual
*/
extern void bcm2835_pwm_set_mode(uint8_t channel, uint8_t markspace, uint8_t
enabled);
/*! Sets the maximum range of the PWM output.
The data value can vary between 0 and this range to control PWM output
\param[in] channel The PWM channel. 0 or 1.
\param[in] range The maximum value permitted for DATA.
*/
extern void bcm2835_pwm_set_range(uint8_t channel, uint32_t range);
/*! Sets the PWM pulse ratio to emit to DATA/RANGE,
where RANGE is set by bcm2835_pwm_set_range().
\param[in] channel The PWM channel. 0 or 1.
\param[in] data Controls the PWM output ratio as a fraction of the range.
Can vary from 0 to RANGE.
*/
extern void bcm2835_pwm_set_data(uint8_t channel, uint32_t data);
/*! @} */
#ifdef __cplusplus
}
#endif
#endif /* BCM2835_H */
/*! @example blink.c
Blinks RPi GPIO pin 11 on and off
*/
/*! @example input.c
Reads the state of an RPi input pin
*/
/*! @example event.c
Shows how to use event detection on an input pin
*/
/*! @example spi.c
Shows how to use SPI interface to transfer a byte to and from an SPI device
*/
/*! @example spin.c
Shows how to use SPI interface to transfer a number of bytes to and from an SP
I device
*/
/*! @example pwm.c
Shows how to use PWM to control GPIO pins
*/
/*! @example i2c.c
Command line utility for executing i2c commands with the
Broadcom bcm2835. Contributed by Shahrooz Shahparnia.
*/
/*! example gpio.c
Command line utility for executing gpio commands with the
Broadcom bcm2835. Contributed by Shahrooz Shahparnia.
*/