2189 lines
103 KiB
C
2189 lines
103 KiB
C
/* bcm2835.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.26 2020/01/11 05:07:13 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, as used in the RaspberryPi,
|
|
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).
|
|
|
|
Works on all versions up to and including RPI 4.
|
|
Works with all versions of Debian up to and including Debian Buster 10.
|
|
|
|
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.71.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.
|
|
Before asking a question or reporting a bug, please read
|
|
- http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/How_to_ask_a_software_question
|
|
- http://www.catb.org/esr/faqs/smart-questions.html
|
|
- http://www.chiark.greenend.org.uk/~shgtatham/bugs.html
|
|
|
|
Tested on debian6-19-04-2012, 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian
|
|
and Occidentalisv01, 2016-02-09 Raspbian Jessie.
|
|
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.
|
|
|
|
In order to compile this library, you may need to install:
|
|
- libc6-dev
|
|
- libgcc-s-dev
|
|
- libstdc++-staticdev
|
|
|
|
\par Running as root
|
|
|
|
Prior to the release of Raspbian Jessie in Feb 2016, access to any
|
|
peripheral device via /dev/mem on the RPi required the process to
|
|
run as root. Raspbian Jessie permits non-root users to access the
|
|
GPIO peripheral (only) via /dev/gpiomem, and this library supports
|
|
that limited mode of operation.
|
|
|
|
If the library runs with effective UID of 0 (ie root), then
|
|
bcm2835_init() will attempt to open /dev/mem, and, if successful, it
|
|
will permit use of all peripherals and library functions.
|
|
|
|
If the library runs with any other effective UID (ie not root), then
|
|
bcm2835_init() will attempt to open /dev/gpiomem, and, if
|
|
successful, will only permit GPIO operations. In particular,
|
|
bcm2835_spi_begin() and bcm2835_i2c_begin() will return false and all
|
|
other non-gpio operations may fail silently or crash.
|
|
|
|
If your program needs acccess to /dev/mem but not as root,
|
|
and if you have the libcap-dev package installed on the target,
|
|
you can compile this library to use
|
|
libcap2 so that it tests whether the exceutable has the cap_sys_rawio capability, and therefore
|
|
permission to access /dev/mem.
|
|
To enable this ability, uncomment the #define BCM2835_HAVE_LIBCAP in bcm2835.h or
|
|
-DBCM2835_HAVE_LIBCAP on your compiler command line.
|
|
After your program has been compiled:
|
|
\code
|
|
sudo setcap cap_sys_rawio+ep *myprogname*
|
|
\endcode
|
|
You also need to do these steps on the host once, to support libcap and not-root read/write access
|
|
to /dev/mem:
|
|
1. Install libcap support
|
|
\code
|
|
sudo apt-get install libcap2 libcap-dev
|
|
2. Add current user to kmem group
|
|
\code
|
|
sudo adduser $USER kmem
|
|
\endcode
|
|
3. Allow write access to /dev/mem by members of kmem group
|
|
\code
|
|
echo 'SUBSYSTEM=="mem", KERNEL=="mem", GROUP="kmem", MODE="0660"' | sudo tee /etc/udev/rules.d/98-mem.rules
|
|
\endcode
|
|
\code
|
|
sudo reboot
|
|
\endcode
|
|
|
|
\par Installation
|
|
|
|
This library consists of a single non-shared library and header file, which will 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_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.
|
|
|
|
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 versions 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
|
|
bcm2835_aux
|
|
bcm2835_spi1
|
|
|
|
\par Raspberry Pi 2 (RPI2)
|
|
|
|
For this library to work correctly on RPI2, you MUST have the device tree support 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 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 \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_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:
|
|
|
|
- P1-19 (MOSI)
|
|
- P1-21 (MISO)
|
|
- P1-23 (CLK)
|
|
- P1-24 (CE0)
|
|
- P1-26 (CE1)
|
|
|
|
Although it is possible to select high speeds for the SPI interface, up to 125MHz (see bcm2835_spi_setClockDivider())
|
|
you should not expect to actually achieve those sorts of speeds with the RPi wiring. Our tests on RPi 2 show that the
|
|
SPI CLK line when unloaded has a resonant frequency of about 40MHz, and when loaded, the MOSI and MISO lines
|
|
ring at an even lower frequency. Measurements show that SPI waveforms are very poor and unusable at 62 and 125MHz.
|
|
Dont expect any speed faster than 31MHz to work reliably.
|
|
|
|
The bcm2835_aux_spi_* functions allow you to control the BCM 2835 SPI1 interface,
|
|
allowing you to send and received data by SPI (Serial Peripheral Interface).
|
|
|
|
The Raspberry Pi GPIO pins used for AUX SPI (SPI1) are:
|
|
|
|
- P1-38 (MOSI)
|
|
- P1-35 (MISO)
|
|
- P1-40 (CLK)
|
|
- P1-36 (CE2)
|
|
|
|
\par I2C Pins
|
|
|
|
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:
|
|
|
|
- P1-03 (SDA)
|
|
- P1-05 (SLC)
|
|
|
|
\par PWM
|
|
|
|
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):
|
|
\code
|
|
GPIO PIN RPi pin PWM Channel ALT FUN
|
|
12 0 0
|
|
13 1 0
|
|
18 1-12 0 5
|
|
19 1 5
|
|
40 0 0
|
|
41 1 0
|
|
45 1 0
|
|
52 0 1
|
|
53 1 1
|
|
\endcode
|
|
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 \ref 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.
|
|
|
|
\par Interactions with other systems
|
|
|
|
In order for bcm2835 library SPI to work, you may need to disable the SPI kernel module using:
|
|
|
|
\code
|
|
sudo raspi-config
|
|
under Advanced Options - enable Device Tree
|
|
under Advanced Options - disable SPI
|
|
Reboot.
|
|
\endcode
|
|
|
|
Since bcm2835 accesses the lowest level hardware interfaces (in eh intererests of speed and flexibility)
|
|
there can be intercations with other low level software trying to do similar things.
|
|
|
|
It seems that with "latest" 8.0 Jessie 4.9.24-v7+ kernel PWM just won't
|
|
work unless you disable audio. There's a line
|
|
\code
|
|
dtparam=audio=on
|
|
\endcode
|
|
in the /boot/config.txt.
|
|
Comment it out like this:
|
|
\code
|
|
#dtparam=audio=on
|
|
\endcode
|
|
|
|
\par Real Time performance constraints
|
|
|
|
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:
|
|
|
|
\code
|
|
#define <sched.h>
|
|
#define <sys/mman.h>
|
|
|
|
struct sched_param sp;
|
|
memset(&sp, 0, sizeof(sp));
|
|
sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
|
|
sched_setscheduler(0, SCHED_FIFO, &sp);
|
|
mlockall(MCL_CURRENT | MCL_FUTURE);
|
|
\endcode
|
|
|
|
\par Crashing on some versions of Raspbian
|
|
Some people have reported that various versions of Rasbian will crash or hang
|
|
if certain GPIO pins are toggled: https://github.com/raspberrypi/linux/issues/2550
|
|
when using bcm2835.
|
|
A workaround is to add this line to your /boot/config.txt:
|
|
\code
|
|
dtoverlay=gpio-no-irq
|
|
\endcode
|
|
|
|
\par Bindings to other languages
|
|
|
|
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/
|
|
|
|
Bindings for Ada are available courtesy Tama McGlinn at https://github.com/TamaMcGlinn/ada_raspio
|
|
|
|
\par Open Source Licensing GPL V3
|
|
|
|
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 3 when your application is
|
|
distributed. See https://www.gnu.org/licenses/gpl-3.0.html and COPYING
|
|
|
|
\par Commercial Licensing
|
|
|
|
This is the appropriate option if you are creating proprietary applications
|
|
and you are not prepared to distribute and share the source code of your
|
|
application. To purchase a commercial license, contact info@airspayce.com
|
|
|
|
\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 David Robinson.
|
|
|
|
\version 1.5 Added bcm2835_close() to deinit the library. Suggested by C?sar Ortiz
|
|
|
|
\version 1.6 Document testing on 2012-07-15-wheezy-raspbian and Occidentalisv01
|
|
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 read 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 different 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 Wolfe.
|
|
|
|
\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_delayMicroseconds:
|
|
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 peripherals has been granted.
|
|
|
|
\version 1.21 delayMicroseconds is now not susceptible to 32 bit timer overruns.
|
|
Patch courtesy Jeremy Mortis.
|
|
|
|
\version 1.22 Fixed incorrect definition of BCM2835_GPFEN0 which broke the ability 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 code
|
|
under high load from other processes.
|
|
|
|
\version 1.25 Updated author and distribution location details to airspayce.com
|
|
|
|
\version 1.26 Added missing unmapmem for pads in bcm2835_close to prevent a memory leak.
|
|
Reported by Hartmut Henkel.
|
|
|
|
\version 1.27 bcm2835_gpio_set_pad() no longer needs BCM2835_PAD_PASSWRD: it is
|
|
now automatically included.
|
|
Added support 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 Würtz.
|
|
|
|
\version 1.29 Further fix to SPI from Peter Würtz.
|
|
|
|
\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 connected.
|
|
Contributed by Malcolm Wiles based on work by Arvi Govindaraj.
|
|
|
|
\version 1.33 Added command line utilities i2c and gpio to examples. Contributed by Shahrooz Shahparnia.
|
|
|
|
\version 1.34 Added bcm2835_i2c_write_read_rs() which writes an arbitrary number of bytes,
|
|
sends a repeat start, and reads from the device. Contributed by Eduardo Steinhorst.
|
|
|
|
\version 1.35 Fix build errors when compiled under Qt. Also performance improvements with SPI transfers. Contributed b Udo Klaas.
|
|
|
|
\version 1.36 Make automake's test runner detect that we're skipping tests when not root, the second
|
|
one makes us skip the test when using fakeroot (as used when building
|
|
Debian packages). Contributed by Guido Günther.
|
|
|
|
\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, contributed 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 Frank Hommers <br>
|
|
|
|
\version 1.39 Beta version of RPi2 compatibility. Not tested here on RPi2 hardware.
|
|
Testers please confirm correct operation on RPi2.<br>
|
|
Unnecessary '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 included
|
|
in code compiled with -Wall -Woverflow -Wstrict-overflow -Wshadow -Wextra -pedantic.
|
|
Reported by tlhackque.<br>
|
|
Fixed a problem where calling bcm2835_delayMicroseconds loops forever when debug is set. Reported by tlhackque.<br>
|
|
Reinstated use of volatile in 2 functions where there was a danger of lost reads 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 assistance 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-wheezy.<br>
|
|
|
|
\version 1.44 Added documention about the need for device tree to be enabled on RPI2.<br>
|
|
Improvements to detection of availability 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 bcm2835_gpio_set_pad()
|
|
and bcm2835_gpio_pad() working correctly with non-0 pad groups. Reported by Guido.
|
|
|
|
\version 1.46 2015-09-18
|
|
Added symbolic definitions for remaining pins on 40 pin GPIO header on RPi 2. <br>
|
|
|
|
\version 1.47 2015-11-18
|
|
Fixed possibly incorrect reads in bcm2835_i2c_read_register_rs, patch from Eckhardt 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.
|
|
|
|
\version 1.49 2016-01-05
|
|
Added patch from Jonathan Perkin with new functions bcm2835_gpio_eds_multi() and bcm2835_gpio_set_eds_multi().
|
|
|
|
\version 1.50 2016-02-28
|
|
Added support for running as non-root, permitting access to GPIO only. Functions
|
|
bcm2835_spi_begin() and bcm2835_i2c_begin() will now return 0 if not running as root
|
|
(which prevents access to the SPI and I2C peripherals, amongst others).
|
|
Testing on Raspbian Jessie.
|
|
|
|
\version 1.51 2016-11-03
|
|
Added documentation about SPI clock divider and resulting SPI speeds on RPi3.
|
|
Fixed a problem where seg fault could occur in bcm2835_delayMicroseconds() if not running as root. Patch from Pok.
|
|
|
|
\version 1.52 2017-02-03
|
|
Added link to commercial license purchasing.
|
|
|
|
\version 1.53 2018-01-14
|
|
Added support for AUX SPI (SPI1)
|
|
Contributed by Arjan van Vught (http://www.raspberrypi-dmx.org/)
|
|
|
|
\version 1.54 2018-01-17
|
|
Fixed compile errors in new AUX spi code under some circumstances.
|
|
|
|
\version 1.55 2018-01-20
|
|
Fixed version numbers.
|
|
Fixed some warnings.
|
|
|
|
\version 1.56 2018-06-10
|
|
Supports bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_LSBFIRST), after which SPI bytes are reversed on read or write.
|
|
Based on a suggestion by Damiano Benedetti.
|
|
|
|
\version 1.57 2018-08-28
|
|
Added SPI function bcm2835_spi_set_speed_hz(uint32_t speed_hz);
|
|
Contributed by Arjan van Vught (http://www.raspberrypi-dmx.org/)
|
|
|
|
\version 1.58 2018-11-29
|
|
Added examples/spiram, which shows how to use the included little library (spiram.c and spiram.h)
|
|
to read and write SPI RAM chips such as 23K256-I/P
|
|
|
|
\version 1.59 2019-05-22
|
|
Fixed a bug in bcm2835_i2c_read reported by Charles Hayward where a noisy I2C line cold cause a seg fault by
|
|
reading too many characters.
|
|
|
|
\version 1.60 2019-07-23
|
|
Applied patch from Mark Dootson for RPi 4 compatibility. Thanks Mark. Not tested here on RPi4, but others report it works.
|
|
Tested as still working correctly on earlier RPi models. Tested with Debian Buster on earlier models
|
|
|
|
\version 1.61 2020-01-11
|
|
Fixed errors in the documentation for bcm2835_spi_write.
|
|
Fixes issue seen on Raspberry Pi 4 boards where 64-bit off_t is used by
|
|
default via -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64. The offset was
|
|
being incorrectly converted, this way is clearer and fixes the problem. Contributed by Jonathan Perkin.
|
|
|
|
\version 1.62 2020-01-12
|
|
Fixed a problem that could cause compile failures with size_t and off_t
|
|
|
|
\version 1.63 2020-03-07
|
|
Added bcm2835_aux_spi_transfer, contributed by Michivi
|
|
Adopted GPL V3 licensing
|
|
|
|
\version 1.64 2020-04-11
|
|
Fixed error in definitions of BCM2835_AUX_SPI_STAT_TX_LVL and BCM2835_AUX_SPI_STAT_RX_LVL. Patch from
|
|
Eric Marzec. Thanks.
|
|
|
|
\version 1.65, 1.66 2020-04-16
|
|
Added support for use of capability cap_sys_rawio to determine if access to /dev/mem is available for non-root
|
|
users. Contributed by Doug McFadyen.
|
|
|
|
\version 1.67, 1.66 2020-06-11
|
|
Fixed an error in bcm2835_i2c_read() where the status byte was not correctly updated with BCM2835_BSC_S_DONE
|
|
Reported by Zihan. Thanks.
|
|
|
|
\version 1.69, 2021-03-30
|
|
Added link to Ada bindings by Tama McGlinn.
|
|
Fixed problem with undefined off_t on some compilers.
|
|
|
|
\version 1.70,
|
|
Patch to ensure compilation with gcc -std=c99, as reported by John Blaiklock.
|
|
Fix some inconsistencies in version numbers
|
|
|
|
version 1.71
|
|
Added SMI bus support, courtesy of Benoit Bouchez, including new functions:
|
|
bcm2835_smi_begin(), bcm2835_smi_end(),
|
|
bcm2835_smi_set_timing(), bcm2835_smi_write(), bcm2835_smi_read().
|
|
|
|
\author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
|
|
*/
|
|
|
|
|
|
/* Defines for BCM2835 */
|
|
#ifndef BCM2835_H
|
|
#define BCM2835_H
|
|
|
|
#include <stdint.h>
|
|
|
|
/* Some compilers need this, as reported by Sam James */
|
|
#include <sys/types.h>
|
|
/* Needed to compile with gcc -std=c99, as reported by John Blaiklock.*/
|
|
#include <fcntl.h>
|
|
|
|
#define BCM2835_VERSION 10071 /* Version 1.71 */
|
|
|
|
// Define this if you want to use libcap2 to determine if you have the cap_sys_rawio capability
|
|
// and therefore the capability of opening /dev/mem, even if you are not root.
|
|
// See the comments above in the documentation for 'Running As Root'
|
|
//#define BCM2835_HAVE_LIBCAP
|
|
|
|
/* 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 instead.
|
|
However, not all versions of gcc in all distros support the dmb assembler instruction even on compatible 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
|
|
|
|
/*! Return the minimum of 2 numbers */
|
|
#ifndef MIN
|
|
#define MIN(a, b) (a < b ? a : b)
|
|
#endif
|
|
|
|
/*! Speed of the core clock core_clk */
|
|
#define BCM2835_CORE_CLK_HZ 250000000 /*!< 250 MHz */
|
|
|
|
/*! On all recent OSs, the base of the peripherals is read from a /proc file */
|
|
#define BMC2835_RPI2_DT_FILENAME "/proc/device-tree/soc/ranges"
|
|
|
|
/*! 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
|
|
/*! Alternate base address for RPI 2 / 3 */
|
|
#define BCM2835_RPI2_PERI_BASE 0x3F000000
|
|
/*! Alternate base address for RPI 4 */
|
|
#define BCM2835_RPI4_PERI_BASE 0xFE000000
|
|
/*! Alternate size for RPI 4 */
|
|
#define BCM2835_RPI4_PERI_SIZE 0x01800000
|
|
|
|
/*! 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 AUX registers */
|
|
#define BCM2835_AUX_BASE 0x215000
|
|
/*! Base Address of the AUX_SPI1 registers */
|
|
#define BCM2835_SPI1_BASE 0x215080
|
|
/*! Base Address of the AUX_SPI2 registers */
|
|
#define BCM2835_SPI2_BASE 0x2150C0
|
|
/*! Base Address of the BSC1 registers */
|
|
#define BCM2835_BSC1_BASE 0x804000
|
|
|
|
/* BEB */
|
|
/*! Base address of the SMI registers */
|
|
#define BCM2835_SMI_BASE 0x600000
|
|
|
|
#include <stdlib.h>
|
|
|
|
/*! Physical address and size of the peripherals block
|
|
May be overridden on RPi2
|
|
*/
|
|
extern off_t bcm2835_peripherals_base;
|
|
/*! Size of the peripherals block to be mapped */
|
|
extern size_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 (as root)
|
|
*/
|
|
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 (as root)
|
|
*/
|
|
extern volatile uint32_t *bcm2835_pwm;
|
|
|
|
/*! Base of the CLK registers.
|
|
Available after bcm2835_init has been called (as root)
|
|
*/
|
|
extern volatile uint32_t *bcm2835_clk;
|
|
|
|
/*! Base of the PADS registers.
|
|
Available after bcm2835_init has been called (as root)
|
|
*/
|
|
extern volatile uint32_t *bcm2835_pads;
|
|
|
|
/*! Base of the SPI0 registers.
|
|
Available after bcm2835_init has been called (as root)
|
|
*/
|
|
extern volatile uint32_t *bcm2835_spi0;
|
|
|
|
/*! Base of the BSC0 registers.
|
|
Available after bcm2835_init has been called (as root)
|
|
*/
|
|
extern volatile uint32_t *bcm2835_bsc0;
|
|
|
|
/*! Base of the BSC1 registers.
|
|
Available after bcm2835_init has been called (as root)
|
|
*/
|
|
extern volatile uint32_t *bcm2835_bsc1;
|
|
|
|
/*! Base of the AUX registers.
|
|
Available after bcm2835_init has been called (as root)
|
|
*/
|
|
extern volatile uint32_t *bcm2835_aux;
|
|
|
|
/*! Base of the SPI1 registers.
|
|
Available after bcm2835_init has been called (as root)
|
|
*/
|
|
extern volatile uint32_t *bcm2835_spi1;
|
|
|
|
/* BEB */
|
|
/*! Base of SMI registers.
|
|
Available after bcm2835_init has been called (as root)
|
|
*/
|
|
extern volatile uint32_t *bcm2835_smi;
|
|
|
|
/*! \brief bcm2835RegisterBase
|
|
Register bases for bcm2835_regbase()
|
|
*/
|
|
typedef enum
|
|
{
|
|
BCM2835_REGBASE_ST = 1, /*!< Base of the ST (System Timer) registers. */
|
|
BCM2835_REGBASE_GPIO = 2, /*!< Base of the GPIO registers. */
|
|
BCM2835_REGBASE_PWM = 3, /*!< Base of the PWM registers. */
|
|
BCM2835_REGBASE_CLK = 4, /*!< Base of the CLK registers. */
|
|
BCM2835_REGBASE_PADS = 5, /*!< Base of the PADS registers. */
|
|
BCM2835_REGBASE_SPI0 = 6, /*!< Base of the SPI0 registers. */
|
|
BCM2835_REGBASE_BSC0 = 7, /*!< Base of the BSC0 registers. */
|
|
BCM2835_REGBASE_BSC1 = 8, /*!< Base of the BSC1 registers. */
|
|
BCM2835_REGBASE_AUX = 9, /*!< Base of the AUX registers. */
|
|
BCM2835_REGBASE_SPI1 = 10,/*!< Base of the SPI1 registers. */
|
|
/* BEB */
|
|
BCM2835_REGBASE_SMI = 11 /*!< Base of the SMI registers. */
|
|
|
|
} bcm2835RegisterBase;
|
|
|
|
/*! Size of memory page on RPi */
|
|
#define BCM2835_PAGE_SIZE (4*1024)
|
|
/*! Size of memory block on RPi */
|
|
#define BCM2835_BLOCK_SIZE (4*1024)
|
|
|
|
|
|
/* Defines for GPIO
|
|
The BCM2835 has 54 GPIO pins.
|
|
BCM2835 data sheet, Page 90 onwards.
|
|
*/
|
|
/*! GPIO register offsets from BCM2835_GPIO_BASE.
|
|
Offsets into the GPIO Peripheral block in bytes per 6.1 Register View
|
|
*/
|
|
#define BCM2835_GPFSEL0 0x0000 /*!< GPIO Function Select 0 */
|
|
#define BCM2835_GPFSEL1 0x0004 /*!< GPIO Function Select 1 */
|
|
#define BCM2835_GPFSEL2 0x0008 /*!< GPIO Function Select 2 */
|
|
#define BCM2835_GPFSEL3 0x000c /*!< GPIO Function Select 3 */
|
|
#define BCM2835_GPFSEL4 0x0010 /*!< GPIO Function Select 4 */
|
|
#define BCM2835_GPFSEL5 0x0014 /*!< GPIO Function Select 5 */
|
|
#define BCM2835_GPSET0 0x001c /*!< GPIO Pin Output Set 0 */
|
|
#define BCM2835_GPSET1 0x0020 /*!< GPIO Pin Output Set 1 */
|
|
#define BCM2835_GPCLR0 0x0028 /*!< GPIO Pin Output Clear 0 */
|
|
#define BCM2835_GPCLR1 0x002c /*!< GPIO Pin Output Clear 1 */
|
|
#define BCM2835_GPLEV0 0x0034 /*!< GPIO Pin Level 0 */
|
|
#define BCM2835_GPLEV1 0x0038 /*!< GPIO Pin Level 1 */
|
|
#define BCM2835_GPEDS0 0x0040 /*!< GPIO Pin Event Detect Status 0 */
|
|
#define BCM2835_GPEDS1 0x0044 /*!< GPIO Pin Event Detect Status 1 */
|
|
#define BCM2835_GPREN0 0x004c /*!< GPIO Pin Rising Edge Detect Enable 0 */
|
|
#define BCM2835_GPREN1 0x0050 /*!< GPIO Pin Rising Edge Detect Enable 1 */
|
|
#define BCM2835_GPFEN0 0x0058 /*!< GPIO Pin Falling Edge Detect Enable 0 */
|
|
#define BCM2835_GPFEN1 0x005c /*!< GPIO Pin Falling Edge Detect Enable 1 */
|
|
#define BCM2835_GPHEN0 0x0064 /*!< GPIO Pin High Detect Enable 0 */
|
|
#define BCM2835_GPHEN1 0x0068 /*!< GPIO Pin High Detect Enable 1 */
|
|
#define BCM2835_GPLEN0 0x0070 /*!< GPIO Pin Low Detect Enable 0 */
|
|
#define BCM2835_GPLEN1 0x0074 /*!< GPIO Pin Low Detect Enable 1 */
|
|
#define BCM2835_GPAREN0 0x007c /*!< GPIO Pin Async. Rising Edge Detect 0 */
|
|
#define BCM2835_GPAREN1 0x0080 /*!< GPIO Pin Async. Rising Edge Detect 1 */
|
|
#define BCM2835_GPAFEN0 0x0088 /*!< GPIO Pin Async. Falling Edge Detect 0 */
|
|
#define BCM2835_GPAFEN1 0x008c /*!< GPIO Pin Async. Falling Edge Detect 1 */
|
|
#define BCM2835_GPPUD 0x0094 /*!< GPIO Pin Pull-up/down Enable */
|
|
#define BCM2835_GPPUDCLK0 0x0098 /*!< GPIO Pin Pull-up/down Enable Clock 0 */
|
|
#define BCM2835_GPPUDCLK1 0x009c /*!< GPIO Pin Pull-up/down Enable Clock 1 */
|
|
|
|
/* 2711 has a different method for pin pull-up/down/enable */
|
|
#define BCM2835_GPPUPPDN0 0x00e4 /* Pin pull-up/down for pins 15:0 */
|
|
#define BCM2835_GPPUPPDN1 0x00e8 /* Pin pull-up/down for pins 31:16 */
|
|
#define BCM2835_GPPUPPDN2 0x00ec /* Pin pull-up/down for pins 47:32 */
|
|
#define BCM2835_GPPUPPDN3 0x00f0 /* Pin pull-up/down for pins 57:48 */
|
|
|
|
/*! \brief bcm2835PortFunction
|
|
Port function select modes for bcm2835_gpio_fsel()
|
|
*/
|
|
typedef enum
|
|
{
|
|
BCM2835_GPIO_FSEL_INPT = 0x00, /*!< Input 0b000 */
|
|
BCM2835_GPIO_FSEL_OUTP = 0x01, /*!< Output 0b001 */
|
|
BCM2835_GPIO_FSEL_ALT0 = 0x04, /*!< Alternate function 0 0b100 */
|
|
BCM2835_GPIO_FSEL_ALT1 = 0x05, /*!< Alternate function 1 0b101 */
|
|
BCM2835_GPIO_FSEL_ALT2 = 0x06, /*!< Alternate function 2 0b110, */
|
|
BCM2835_GPIO_FSEL_ALT3 = 0x07, /*!< Alternate function 3 0b111 */
|
|
BCM2835_GPIO_FSEL_ALT4 = 0x03, /*!< Alternate function 4 0b011 */
|
|
BCM2835_GPIO_FSEL_ALT5 = 0x02, /*!< Alternate function 5 0b010 */
|
|
BCM2835_GPIO_FSEL_MASK = 0x07 /*!< Function select bits mask 0b111 */
|
|
} bcm2835FunctionSelect;
|
|
|
|
/*! \brief bcm2835PUDControl
|
|
Pullup/Pulldown defines for bcm2835_gpio_pud()
|
|
*/
|
|
typedef enum
|
|
{
|
|
BCM2835_GPIO_PUD_OFF = 0x00, /*!< Off ? disable pull-up/down 0b00 */
|
|
BCM2835_GPIO_PUD_DOWN = 0x01, /*!< Enable Pull Down control 0b01 */
|
|
BCM2835_GPIO_PUD_UP = 0x02 /*!< Enable Pull Up control 0b10 */
|
|
} bcm2835PUDControl;
|
|
|
|
/* need a value for pud functions that can't work unless RPI 4 */
|
|
#define BCM2835_GPIO_PUD_ERROR 0x08
|
|
|
|
/*! Pad control register offsets from BCM2835_GPIO_PADS */
|
|
#define BCM2835_PADS_GPIO_0_27 0x002c /*!< Pad control register for pads 0 to 27 */
|
|
#define BCM2835_PADS_GPIO_28_45 0x0030 /*!< Pad control register for pads 28 to 45 */
|
|
#define BCM2835_PADS_GPIO_46_53 0x0034 /*!< Pad control register for pads 46 to 53 */
|
|
|
|
/*! Pad Control masks */
|
|
#define BCM2835_PAD_PASSWRD (0x5A << 24) /*!< Password to enable setting pad mask */
|
|
#define BCM2835_PAD_SLEW_RATE_UNLIMITED 0x10 /*!< Slew rate unlimited */
|
|
#define BCM2835_PAD_HYSTERESIS_ENABLED 0x08 /*!< Hysteresis enabled */
|
|
#define BCM2835_PAD_DRIVE_2mA 0x00 /*!< 2mA drive current */
|
|
#define BCM2835_PAD_DRIVE_4mA 0x01 /*!< 4mA drive current */
|
|
#define BCM2835_PAD_DRIVE_6mA 0x02 /*!< 6mA drive current */
|
|
#define BCM2835_PAD_DRIVE_8mA 0x03 /*!< 8mA drive current */
|
|
#define BCM2835_PAD_DRIVE_10mA 0x04 /*!< 10mA drive current */
|
|
#define BCM2835_PAD_DRIVE_12mA 0x05 /*!< 12mA drive current */
|
|
#define BCM2835_PAD_DRIVE_14mA 0x06 /*!< 14mA drive current */
|
|
#define BCM2835_PAD_DRIVE_16mA 0x07 /*!< 16mA drive current */
|
|
|
|
/*! \brief bcm2835PadGroup
|
|
Pad group specification for bcm2835_gpio_pad()
|
|
*/
|
|
typedef enum
|
|
{
|
|
BCM2835_PAD_GROUP_GPIO_0_27 = 0, /*!< Pad group for GPIO pads 0 to 27 */
|
|
BCM2835_PAD_GROUP_GPIO_28_45 = 1, /*!< Pad group for GPIO pads 28 to 45 */
|
|
BCM2835_PAD_GROUP_GPIO_46_53 = 2 /*!< Pad group for GPIO pads 46 to 53 */
|
|
} bcm2835PadGroup;
|
|
|
|
/*! \brief GPIO Pin Numbers
|
|
|
|
Here we define Raspberry Pin GPIO pins on P1 in terms of the underlying BCM GPIO pin numbers.
|
|
These can be passed as a pin number to any function requiring a pin.
|
|
Not all pins on the RPi 26 bin IDE plug are connected to GPIO pins
|
|
and some can adopt an alternate function.
|
|
RPi version 2 has some slightly different pinouts, and these are values RPI_V2_*.
|
|
RPi B+ has yet differnet pinouts and these are defined in RPI_BPLUS_*.
|
|
At bootup, pins 8 and 10 are set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
|
|
When SPI0 is in use (ie after bcm2835_spi_begin()), SPI0 pins are dedicated to SPI
|
|
and cant be controlled independently.
|
|
If you are using the RPi Compute Module, just use the GPIO number: there is no need to use one of these
|
|
symbolic names
|
|
*/
|
|
typedef enum
|
|
{
|
|
RPI_GPIO_P1_03 = 0, /*!< Version 1, Pin P1-03 */
|
|
RPI_GPIO_P1_05 = 1, /*!< Version 1, Pin P1-05 */
|
|
RPI_GPIO_P1_07 = 4, /*!< Version 1, Pin P1-07 */
|
|
RPI_GPIO_P1_08 = 14, /*!< Version 1, Pin P1-08, defaults to alt function 0 UART0_TXD */
|
|
RPI_GPIO_P1_10 = 15, /*!< Version 1, Pin P1-10, defaults to alt function 0 UART0_RXD */
|
|
RPI_GPIO_P1_11 = 17, /*!< Version 1, Pin P1-11 */
|
|
RPI_GPIO_P1_12 = 18, /*!< Version 1, Pin P1-12, can be PWM channel 0 in ALT FUN 5 */
|
|
RPI_GPIO_P1_13 = 21, /*!< Version 1, Pin P1-13 */
|
|
RPI_GPIO_P1_15 = 22, /*!< Version 1, Pin P1-15 */
|
|
RPI_GPIO_P1_16 = 23, /*!< Version 1, Pin P1-16 */
|
|
RPI_GPIO_P1_18 = 24, /*!< Version 1, Pin P1-18 */
|
|
RPI_GPIO_P1_19 = 10, /*!< Version 1, Pin P1-19, MOSI when SPI0 in use */
|
|
RPI_GPIO_P1_21 = 9, /*!< Version 1, Pin P1-21, MISO when SPI0 in use */
|
|
RPI_GPIO_P1_22 = 25, /*!< Version 1, Pin P1-22 */
|
|
RPI_GPIO_P1_23 = 11, /*!< Version 1, Pin P1-23, CLK when SPI0 in use */
|
|
RPI_GPIO_P1_24 = 8, /*!< Version 1, Pin P1-24, CE0 when SPI0 in use */
|
|
RPI_GPIO_P1_26 = 7, /*!< Version 1, Pin P1-26, CE1 when SPI0 in use */
|
|
|
|
/* RPi Version 2 */
|
|
RPI_V2_GPIO_P1_03 = 2, /*!< Version 2, Pin P1-03 */
|
|
RPI_V2_GPIO_P1_05 = 3, /*!< Version 2, Pin P1-05 */
|
|
RPI_V2_GPIO_P1_07 = 4, /*!< Version 2, Pin P1-07 */
|
|
RPI_V2_GPIO_P1_08 = 14, /*!< Version 2, Pin P1-08, defaults to alt function 0 UART0_TXD */
|
|
RPI_V2_GPIO_P1_10 = 15, /*!< Version 2, Pin P1-10, defaults to alt function 0 UART0_RXD */
|
|
RPI_V2_GPIO_P1_11 = 17, /*!< Version 2, Pin P1-11 */
|
|
RPI_V2_GPIO_P1_12 = 18, /*!< Version 2, Pin P1-12, can be PWM channel 0 in ALT FUN 5 */
|
|
RPI_V2_GPIO_P1_13 = 27, /*!< Version 2, Pin P1-13 */
|
|
RPI_V2_GPIO_P1_15 = 22, /*!< Version 2, Pin P1-15 */
|
|
RPI_V2_GPIO_P1_16 = 23, /*!< Version 2, Pin P1-16 */
|
|
RPI_V2_GPIO_P1_18 = 24, /*!< Version 2, Pin P1-18 */
|
|
RPI_V2_GPIO_P1_19 = 10, /*!< Version 2, Pin P1-19, MOSI when SPI0 in use */
|
|
RPI_V2_GPIO_P1_21 = 9, /*!< Version 2, Pin P1-21, MISO when SPI0 in use */
|
|
RPI_V2_GPIO_P1_22 = 25, /*!< Version 2, Pin P1-22 */
|
|
RPI_V2_GPIO_P1_23 = 11, /*!< Version 2, Pin P1-23, CLK when SPI0 in use */
|
|
RPI_V2_GPIO_P1_24 = 8, /*!< Version 2, Pin P1-24, CE0 when SPI0 in use */
|
|
RPI_V2_GPIO_P1_26 = 7, /*!< Version 2, Pin P1-26, CE1 when SPI0 in use */
|
|
RPI_V2_GPIO_P1_29 = 5, /*!< Version 2, Pin P1-29 */
|
|
RPI_V2_GPIO_P1_31 = 6, /*!< Version 2, Pin P1-31 */
|
|
RPI_V2_GPIO_P1_32 = 12, /*!< Version 2, Pin P1-32 */
|
|
RPI_V2_GPIO_P1_33 = 13, /*!< Version 2, Pin P1-33 */
|
|
RPI_V2_GPIO_P1_35 = 19, /*!< Version 2, Pin P1-35, can be PWM channel 1 in ALT FUN 5 */
|
|
RPI_V2_GPIO_P1_36 = 16, /*!< Version 2, Pin P1-36 */
|
|
RPI_V2_GPIO_P1_37 = 26, /*!< Version 2, Pin P1-37 */
|
|
RPI_V2_GPIO_P1_38 = 20, /*!< Version 2, Pin P1-38 */
|
|
RPI_V2_GPIO_P1_40 = 21, /*!< Version 2, Pin P1-40 */
|
|
|
|
/* RPi Version 2, new plug P5 */
|
|
RPI_V2_GPIO_P5_03 = 28, /*!< Version 2, Pin P5-03 */
|
|
RPI_V2_GPIO_P5_04 = 29, /*!< Version 2, Pin P5-04 */
|
|
RPI_V2_GPIO_P5_05 = 30, /*!< Version 2, Pin P5-05 */
|
|
RPI_V2_GPIO_P5_06 = 31, /*!< Version 2, Pin P5-06 */
|
|
|
|
/* RPi B+ J8 header, also RPi 2 40 pin GPIO header */
|
|
RPI_BPLUS_GPIO_J8_03 = 2, /*!< B+, Pin J8-03 */
|
|
RPI_BPLUS_GPIO_J8_05 = 3, /*!< B+, Pin J8-05 */
|
|
RPI_BPLUS_GPIO_J8_07 = 4, /*!< B+, Pin J8-07 */
|
|
RPI_BPLUS_GPIO_J8_08 = 14, /*!< B+, Pin J8-08, defaults to alt function 0 UART0_TXD */
|
|
RPI_BPLUS_GPIO_J8_10 = 15, /*!< B+, Pin J8-10, defaults to alt function 0 UART0_RXD */
|
|
RPI_BPLUS_GPIO_J8_11 = 17, /*!< B+, Pin J8-11 */
|
|
RPI_BPLUS_GPIO_J8_12 = 18, /*!< B+, Pin J8-12, can be PWM channel 0 in ALT FUN 5 */
|
|
RPI_BPLUS_GPIO_J8_13 = 27, /*!< B+, Pin J8-13 */
|
|
RPI_BPLUS_GPIO_J8_15 = 22, /*!< B+, Pin J8-15 */
|
|
RPI_BPLUS_GPIO_J8_16 = 23, /*!< B+, Pin J8-16 */
|
|
RPI_BPLUS_GPIO_J8_18 = 24, /*!< B+, Pin J8-18 */
|
|
RPI_BPLUS_GPIO_J8_19 = 10, /*!< B+, Pin J8-19, MOSI when SPI0 in use */
|
|
RPI_BPLUS_GPIO_J8_21 = 9, /*!< B+, Pin J8-21, MISO when SPI0 in use */
|
|
RPI_BPLUS_GPIO_J8_22 = 25, /*!< B+, Pin J8-22 */
|
|
RPI_BPLUS_GPIO_J8_23 = 11, /*!< B+, Pin J8-23, CLK when SPI0 in use */
|
|
RPI_BPLUS_GPIO_J8_24 = 8, /*!< B+, Pin J8-24, CE0 when SPI0 in use */
|
|
RPI_BPLUS_GPIO_J8_26 = 7, /*!< B+, Pin J8-26, CE1 when SPI0 in use */
|
|
RPI_BPLUS_GPIO_J8_29 = 5, /*!< B+, Pin J8-29, */
|
|
RPI_BPLUS_GPIO_J8_31 = 6, /*!< B+, Pin J8-31, */
|
|
RPI_BPLUS_GPIO_J8_32 = 12, /*!< B+, Pin J8-32, */
|
|
RPI_BPLUS_GPIO_J8_33 = 13, /*!< B+, Pin J8-33, */
|
|
RPI_BPLUS_GPIO_J8_35 = 19, /*!< B+, Pin J8-35, can be PWM channel 1 in ALT FUN 5 */
|
|
RPI_BPLUS_GPIO_J8_36 = 16, /*!< B+, Pin J8-36, */
|
|
RPI_BPLUS_GPIO_J8_37 = 26, /*!< B+, Pin J8-37, */
|
|
RPI_BPLUS_GPIO_J8_38 = 20, /*!< B+, Pin J8-38, */
|
|
RPI_BPLUS_GPIO_J8_40 = 21 /*!< B+, Pin J8-40, */
|
|
} RPiGPIOPin;
|
|
|
|
/* Defines for AUX
|
|
GPIO register offsets from BCM2835_AUX_BASE.
|
|
*/
|
|
#define BCM2835_AUX_IRQ 0x0000 /*!< xxx */
|
|
#define BCM2835_AUX_ENABLE 0x0004 /*!< */
|
|
|
|
#define BCM2835_AUX_ENABLE_UART1 0x01 /*!< */
|
|
#define BCM2835_AUX_ENABLE_SPI0 0x02 /*!< SPI0 (SPI1 in the device) */
|
|
#define BCM2835_AUX_ENABLE_SPI1 0x04 /*!< SPI1 (SPI2 in the device) */
|
|
|
|
|
|
#define BCM2835_AUX_SPI_CNTL0 0x0000 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL1 0x0004 /*!< */
|
|
#define BCM2835_AUX_SPI_STAT 0x0008 /*!< */
|
|
#define BCM2835_AUX_SPI_PEEK 0x000C /*!< Read but do not take from FF */
|
|
#define BCM2835_AUX_SPI_IO 0x0020 /*!< Write = TX, read=RX */
|
|
#define BCM2835_AUX_SPI_TXHOLD 0x0030 /*!< Write = TX keep CS, read=RX */
|
|
|
|
#define BCM2835_AUX_SPI_CLOCK_MIN 30500 /*!< 30,5kHz */
|
|
#define BCM2835_AUX_SPI_CLOCK_MAX 125000000 /*!< 125Mhz */
|
|
|
|
#define BCM2835_AUX_SPI_CNTL0_SPEED 0xFFF00000 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_SPEED_MAX 0xFFF /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT 20 /*!< */
|
|
|
|
#define BCM2835_AUX_SPI_CNTL0_CS0_N 0x000C0000 /*!< CS 0 low */
|
|
#define BCM2835_AUX_SPI_CNTL0_CS1_N 0x000A0000 /*!< CS 1 low */
|
|
#define BCM2835_AUX_SPI_CNTL0_CS2_N 0x00060000 /*!< CS 2 low */
|
|
|
|
#define BCM2835_AUX_SPI_CNTL0_POSTINPUT 0x00010000 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_VAR_CS 0x00008000 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_VAR_WIDTH 0x00004000 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_DOUTHOLD 0x00003000 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_ENABLE 0x00000800 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_CPHA_IN 0x00000400 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_CLEARFIFO 0x00000200 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_CPHA_OUT 0x00000100 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_CPOL 0x00000080 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_MSBF_OUT 0x00000040 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL0_SHIFTLEN 0x0000003F /*!< */
|
|
|
|
#define BCM2835_AUX_SPI_CNTL1_CSHIGH 0x00000700 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL1_IDLE 0x00000080 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL1_TXEMPTY 0x00000040 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL1_MSBF_IN 0x00000002 /*!< */
|
|
#define BCM2835_AUX_SPI_CNTL1_KEEP_IN 0x00000001 /*!< */
|
|
|
|
#define BCM2835_AUX_SPI_STAT_TX_LVL 0xF0000000 /*!< */
|
|
#define BCM2835_AUX_SPI_STAT_RX_LVL 0x00F00000 /*!< */
|
|
#define BCM2835_AUX_SPI_STAT_TX_FULL 0x00000400 /*!< */
|
|
#define BCM2835_AUX_SPI_STAT_TX_EMPTY 0x00000200 /*!< */
|
|
#define BCM2835_AUX_SPI_STAT_RX_FULL 0x00000100 /*!< */
|
|
#define BCM2835_AUX_SPI_STAT_RX_EMPTY 0x00000080 /*!< */
|
|
#define BCM2835_AUX_SPI_STAT_BUSY 0x00000040 /*!< */
|
|
#define BCM2835_AUX_SPI_STAT_BITCOUNT 0x0000003F /*!< */
|
|
|
|
/* Defines for SPI
|
|
GPIO register offsets from BCM2835_SPI0_BASE.
|
|
Offsets into the SPI Peripheral block in bytes per 10.5 SPI Register Map
|
|
*/
|
|
#define BCM2835_SPI0_CS 0x0000 /*!< SPI Master Control and Status */
|
|
#define BCM2835_SPI0_FIFO 0x0004 /*!< SPI Master TX and RX FIFOs */
|
|
#define BCM2835_SPI0_CLK 0x0008 /*!< SPI Master Clock Divider */
|
|
#define BCM2835_SPI0_DLEN 0x000c /*!< SPI Master Data Length */
|
|
#define BCM2835_SPI0_LTOH 0x0010 /*!< SPI LOSSI mode TOH */
|
|
#define BCM2835_SPI0_DC 0x0014 /*!< SPI DMA DREQ Controls */
|
|
|
|
/* Register masks for SPI0_CS */
|
|
#define BCM2835_SPI0_CS_LEN_LONG 0x02000000 /*!< Enable Long data word in Lossi mode if DMA_LEN is set */
|
|
#define BCM2835_SPI0_CS_DMA_LEN 0x01000000 /*!< Enable DMA mode in Lossi mode */
|
|
#define BCM2835_SPI0_CS_CSPOL2 0x00800000 /*!< Chip Select 2 Polarity */
|
|
#define BCM2835_SPI0_CS_CSPOL1 0x00400000 /*!< Chip Select 1 Polarity */
|
|
#define BCM2835_SPI0_CS_CSPOL0 0x00200000 /*!< Chip Select 0 Polarity */
|
|
#define BCM2835_SPI0_CS_RXF 0x00100000 /*!< RXF - RX FIFO Full */
|
|
#define BCM2835_SPI0_CS_RXR 0x00080000 /*!< RXR RX FIFO needs Reading (full) */
|
|
#define BCM2835_SPI0_CS_TXD 0x00040000 /*!< TXD TX FIFO can accept Data */
|
|
#define BCM2835_SPI0_CS_RXD 0x00020000 /*!< RXD RX FIFO contains Data */
|
|
#define BCM2835_SPI0_CS_DONE 0x00010000 /*!< Done transfer Done */
|
|
#define BCM2835_SPI0_CS_TE_EN 0x00008000 /*!< Unused */
|
|
#define BCM2835_SPI0_CS_LMONO 0x00004000 /*!< Unused */
|
|
#define BCM2835_SPI0_CS_LEN 0x00002000 /*!< LEN LoSSI enable */
|
|
#define BCM2835_SPI0_CS_REN 0x00001000 /*!< REN Read Enable */
|
|
#define BCM2835_SPI0_CS_ADCS 0x00000800 /*!< ADCS Automatically Deassert Chip Select */
|
|
#define BCM2835_SPI0_CS_INTR 0x00000400 /*!< INTR Interrupt on RXR */
|
|
#define BCM2835_SPI0_CS_INTD 0x00000200 /*!< INTD Interrupt on Done */
|
|
#define BCM2835_SPI0_CS_DMAEN 0x00000100 /*!< DMAEN DMA Enable */
|
|
#define BCM2835_SPI0_CS_TA 0x00000080 /*!< Transfer Active */
|
|
#define BCM2835_SPI0_CS_CSPOL 0x00000040 /*!< Chip Select Polarity */
|
|
#define BCM2835_SPI0_CS_CLEAR 0x00000030 /*!< Clear FIFO Clear RX and TX */
|
|
#define BCM2835_SPI0_CS_CLEAR_RX 0x00000020 /*!< Clear FIFO Clear RX */
|
|
#define BCM2835_SPI0_CS_CLEAR_TX 0x00000010 /*!< Clear FIFO Clear TX */
|
|
#define BCM2835_SPI0_CS_CPOL 0x00000008 /*!< Clock Polarity */
|
|
#define BCM2835_SPI0_CS_CPHA 0x00000004 /*!< Clock Phase */
|
|
#define BCM2835_SPI0_CS_CS 0x00000003 /*!< Chip Select */
|
|
|
|
/*! \brief bcm2835SPIBitOrder SPI Bit order
|
|
Specifies the SPI data bit ordering for bcm2835_spi_setBitOrder()
|
|
*/
|
|
typedef enum
|
|
{
|
|
BCM2835_SPI_BIT_ORDER_LSBFIRST = 0, /*!< LSB First */
|
|
BCM2835_SPI_BIT_ORDER_MSBFIRST = 1 /*!< MSB First */
|
|
}bcm2835SPIBitOrder;
|
|
|
|
/*! \brief SPI Data mode
|
|
Specify the SPI data mode to be passed to bcm2835_spi_setDataMode()
|
|
*/
|
|
typedef enum
|
|
{
|
|
BCM2835_SPI_MODE0 = 0, /*!< CPOL = 0, CPHA = 0 */
|
|
BCM2835_SPI_MODE1 = 1, /*!< CPOL = 0, CPHA = 1 */
|
|
BCM2835_SPI_MODE2 = 2, /*!< CPOL = 1, CPHA = 0 */
|
|
BCM2835_SPI_MODE3 = 3 /*!< CPOL = 1, CPHA = 1 */
|
|
}bcm2835SPIMode;
|
|
|
|
/*! \brief bcm2835SPIChipSelect
|
|
Specify the SPI chip select pin(s)
|
|
*/
|
|
typedef enum
|
|
{
|
|
BCM2835_SPI_CS0 = 0, /*!< Chip Select 0 */
|
|
BCM2835_SPI_CS1 = 1, /*!< Chip Select 1 */
|
|
BCM2835_SPI_CS2 = 2, /*!< Chip Select 2 (ie pins CS1 and CS2 are asserted) */
|
|
BCM2835_SPI_CS_NONE = 3 /*!< No CS, control it yourself */
|
|
} bcm2835SPIChipSelect;
|
|
|
|
/*! \brief bcm2835SPIClockDivider
|
|
Specifies the divider used to generate the SPI clock from the system clock.
|
|
Figures below give the divider, clock period and clock frequency.
|
|
Clock divided is based on nominal core clock rate of 250MHz on RPi1 and RPi2, and 400MHz on RPi3.
|
|
It is reported that (contrary to the documentation) any even divider may used.
|
|
The frequencies shown for each divider have been confirmed by measurement on RPi1 and RPi2.
|
|
The system clock frequency on RPi3 is different, so the frequency you get from a given divider will be different.
|
|
See comments in 'SPI Pins' for information about reliable SPI speeds.
|
|
Note: it is possible to change the core clock rate of the RPi 3 back to 250MHz, by putting
|
|
\code
|
|
core_freq=250
|
|
\endcode
|
|
in the config.txt
|
|
*/
|
|
typedef enum
|
|
{
|
|
BCM2835_SPI_CLOCK_DIVIDER_65536 = 0, /*!< 65536 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_32768 = 32768, /*!< 32768 = 7.629394531kHz on Rpi2, 12.20703125kHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_16384 = 16384, /*!< 16384 = 15.25878906kHz on Rpi2, 24.4140625kHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_8192 = 8192, /*!< 8192 = 30.51757813kHz on Rpi2, 48.828125kHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_4096 = 4096, /*!< 4096 = 61.03515625kHz on Rpi2, 97.65625kHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_2048 = 2048, /*!< 2048 = 122.0703125kHz on Rpi2, 195.3125kHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_1024 = 1024, /*!< 1024 = 244.140625kHz on Rpi2, 390.625kHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_512 = 512, /*!< 512 = 488.28125kHz on Rpi2, 781.25kHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_256 = 256, /*!< 256 = 976.5625kHz on Rpi2, 1.5625MHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_128 = 128, /*!< 128 = 1.953125MHz on Rpi2, 3.125MHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_64 = 64, /*!< 64 = 3.90625MHz on Rpi2, 6.250MHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_32 = 32, /*!< 32 = 7.8125MHz on Rpi2, 12.5MHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_16 = 16, /*!< 16 = 15.625MHz on Rpi2, 25MHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_8 = 8, /*!< 8 = 31.25MHz on Rpi2, 50MHz on RPI3 */
|
|
BCM2835_SPI_CLOCK_DIVIDER_4 = 4, /*!< 4 = 62.5MHz on Rpi2, 100MHz on RPI3. Dont expect this speed to work reliably. */
|
|
BCM2835_SPI_CLOCK_DIVIDER_2 = 2, /*!< 2 = 125MHz on Rpi2, 200MHz on RPI3, fastest you can get. Dont expect this speed to work reliably.*/
|
|
BCM2835_SPI_CLOCK_DIVIDER_1 = 1 /*!< 1 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3, same as 0/65536 */
|
|
} bcm2835SPIClockDivider;
|
|
|
|
/* Defines for I2C
|
|
GPIO register offsets from BCM2835_BSC*_BASE.
|
|
Offsets into the BSC Peripheral block in bytes per 3.1 BSC Register Map
|
|
*/
|
|
#define BCM2835_BSC_C 0x0000 /*!< BSC Master Control */
|
|
#define BCM2835_BSC_S 0x0004 /*!< BSC Master Status */
|
|
#define BCM2835_BSC_DLEN 0x0008 /*!< BSC Master Data Length */
|
|
#define BCM2835_BSC_A 0x000c /*!< BSC Master Slave Address */
|
|
#define BCM2835_BSC_FIFO 0x0010 /*!< BSC Master Data FIFO */
|
|
#define BCM2835_BSC_DIV 0x0014 /*!< BSC Master Clock Divider */
|
|
#define BCM2835_BSC_DEL 0x0018 /*!< BSC Master Data Delay */
|
|
#define BCM2835_BSC_CLKT 0x001c /*!< BSC Master Clock Stretch Timeout */
|
|
|
|
/* Register masks for BSC_C */
|
|
#define BCM2835_BSC_C_I2CEN 0x00008000 /*!< I2C Enable, 0 = disabled, 1 = enabled */
|
|
#define BCM2835_BSC_C_INTR 0x00000400 /*!< Interrupt on RX */
|
|
#define BCM2835_BSC_C_INTT 0x00000200 /*!< Interrupt on TX */
|
|
#define BCM2835_BSC_C_INTD 0x00000100 /*!< Interrupt on DONE */
|
|
#define BCM2835_BSC_C_ST 0x00000080 /*!< Start transfer, 1 = Start a new transfer */
|
|
#define BCM2835_BSC_C_CLEAR_1 0x00000020 /*!< Clear FIFO Clear */
|
|
#define BCM2835_BSC_C_CLEAR_2 0x00000010 /*!< Clear FIFO Clear */
|
|
#define BCM2835_BSC_C_READ 0x00000001 /*!< Read transfer */
|
|
|
|
/* Register masks for BSC_S */
|
|
#define BCM2835_BSC_S_CLKT 0x00000200 /*!< Clock stretch timeout */
|
|
#define BCM2835_BSC_S_ERR 0x00000100 /*!< ACK error */
|
|
#define BCM2835_BSC_S_RXF 0x00000080 /*!< RXF FIFO full, 0 = FIFO is not full, 1 = FIFO is full */
|
|
#define BCM2835_BSC_S_TXE 0x00000040 /*!< TXE FIFO full, 0 = FIFO is not full, 1 = FIFO is full */
|
|
#define BCM2835_BSC_S_RXD 0x00000020 /*!< RXD FIFO contains data */
|
|
#define BCM2835_BSC_S_TXD 0x00000010 /*!< TXD FIFO can accept data */
|
|
#define BCM2835_BSC_S_RXR 0x00000008 /*!< RXR FIFO needs reading (full) */
|
|
#define BCM2835_BSC_S_TXW 0x00000004 /*!< TXW FIFO needs writing (full) */
|
|
#define BCM2835_BSC_S_DONE 0x00000002 /*!< Transfer DONE */
|
|
#define BCM2835_BSC_S_TA 0x00000001 /*!< Transfer Active */
|
|
|
|
#define BCM2835_BSC_FIFO_SIZE 16 /*!< BSC FIFO size */
|
|
|
|
/*! \brief bcm2835I2CClockDivider
|
|
Specifies the divider used to generate the I2C clock from the system clock.
|
|
Clock divided is based on nominal base clock rate of 250MHz
|
|
*/
|
|
typedef enum
|
|
{
|
|
BCM2835_I2C_CLOCK_DIVIDER_2500 = 2500, /*!< 2500 = 10us = 100 kHz */
|
|
BCM2835_I2C_CLOCK_DIVIDER_626 = 626, /*!< 622 = 2.504us = 399.3610 kHz */
|
|
BCM2835_I2C_CLOCK_DIVIDER_150 = 150, /*!< 150 = 60ns = 1.666 MHz (default at reset) */
|
|
BCM2835_I2C_CLOCK_DIVIDER_148 = 148 /*!< 148 = 59ns = 1.689 MHz */
|
|
} bcm2835I2CClockDivider;
|
|
|
|
/*! \brief bcm2835I2CReasonCodes
|
|
Specifies the reason codes for the bcm2835_i2c_write and bcm2835_i2c_read functions.
|
|
*/
|
|
typedef enum
|
|
{
|
|
BCM2835_I2C_REASON_OK = 0x00, /*!< Success */
|
|
BCM2835_I2C_REASON_ERROR_NACK = 0x01, /*!< Received a NACK */
|
|
BCM2835_I2C_REASON_ERROR_CLKT = 0x02, /*!< Received Clock Stretch Timeout */
|
|
BCM2835_I2C_REASON_ERROR_DATA = 0x04 /*!< Not all data is sent / received */
|
|
} bcm2835I2CReasonCodes;
|
|
|
|
/* Registers offets from BCM2835_SMI_BASE */
|
|
#define BCM2835_SMI_CS 0 /*! < Control and status register > */
|
|
#define BCM2835_SMI_LENGTH 1 /*! < Transfer length register > */
|
|
#define BCM2835_SMI_ADRS 2 /*! < Transfer address register > */
|
|
#define BCM2835_SMI_DATA 3 /*! < Transfer data register > */
|
|
#define BCM2835_SMI_READ0 4 /*! < Read settings 0 register > */
|
|
#define BCM2835_SMI_WRITE0 5 /*! < Write settings 0 register > */
|
|
#define BCM2835_SMI_READ1 6 /*! < Read settings 1 register > */
|
|
#define BCM2835_SMI_WRITE1 7 /*! < Write settings 1 register > */
|
|
#define BCM2835_SMI_READ2 8 /*! < Read settings 2 register > */
|
|
#define BCM2835_SMI_WRITE2 9 /*! < Write settings 2 register > */
|
|
#define BCM2835_SMI_READ3 10 /*! < Read settings 3 register > */
|
|
#define BCM2835_SMI_WRITE3 11 /*! < Write settings 3 register > */
|
|
#define BCM2835_SMI_DMAC 12 /*! < DMA control register > */
|
|
#define BCM2835_SMI_DIRCS 13 /*! < Direct control register > */
|
|
#define BCM2835_SMI_DIRADDR 14 /*! < Direct access address register > */
|
|
#define BCM2835_SMI_DIRDATA 15 /*! < Direct access data register > */
|
|
|
|
/* Register masks for SMI_READ and SMI_WRITE */
|
|
#define BCM2835_SMI_RW_WIDTH_MSK 0xC0000000 /*! < Data width mask > */
|
|
#define BCM2835_SMI_RW_WID8 0x00000000 /*! < Data width 8 bits > */
|
|
#define BCM2835_SMI_RW_WID16 0x40000000 /*! < Data width 16 bits > */
|
|
#define BCM2835_SMI_RW_WID18 0x80000000 /*! < Data width 18 bits > */
|
|
#define BCM2835_SMI_RW_WID9 0xC0000000 /*! < Data width 9 bits > */
|
|
#define BCM2835_SMI_RW_SETUP_MSK 0x3F000000 /*! < Setup cycles (6 bits) > */
|
|
#define BCM2835_SMI_RW_SETUP_LS 24 /*! < Shift for setup cycles > */
|
|
#define BCM2835_SMI_RW_MODE68 0x00800000 /*! < Run cycle motorola mode > */
|
|
#define BCM2835_SMI_RW_MODE80 0x00000000 /*! < Run cycle intel mode > */
|
|
#define BCM2835_SMI_READ_FSETUP 0x00400000 /*! < Read : Setup only for first cycle > */
|
|
#define BCM2835_SMI_WRITE_SWAP 0x00400000 /*! < Write : swap pixel data > */
|
|
#define BCM2835_SMI_RW_HOLD_MSK 0x003F0000 /*! < Hold cycles (6 bits) > */
|
|
#define BCM2835_SMI_RW_HOLD_LS 16 /*! < Shift for hold cycles > */
|
|
#define BCM2835_SMI_RW_PACEALL 0x00008000 /*! < Apply pacing always > */
|
|
#define BCM2835_SMI_RW_PACE_MSK 0x00007F00 /*! < Pace cycles (7 bits) > */
|
|
#define BCM2835_SMI_RW_PACE_LS 8 /*! < Shift for pace cycles > */
|
|
#define BCM2835_SMI_RW_DREQ 0x00000080 /*! < Use DMA req on read/write > */
|
|
#define BCM2835_SMI_RW_STROBE_MSK 0x0000007F /*! < Strobe cycles (7 bits) > */
|
|
#define BCM2835_SMI_RW_STROBE_LS 0 /*! < Shift for strobe cycles > */
|
|
|
|
/* Registers masks for Direct Access control register */
|
|
#define BCM2835_SMI_DIRCS_ENABLE 0x00000001 /*! < Set to enable SMI. 0 = Read from ext. devices > */
|
|
#define BCM2835_SMI_DIRCS_START 0x00000002 /*! < Initiate SMI transfer > */
|
|
#define BCM2835_SMI_DIRCS_DONE 0x00000004 /*! < Set if transfer has finished / Write to clear flag > */
|
|
#define BCM2835_SMI_DIRCS_WRITE 0x00000008 /*! < 1 = Write to ext. devices > */
|
|
|
|
/* Registers masks for Direct Access address register */
|
|
#define BCM2835_SMI_DIRADRS_DEV_MSK 0x00000300 /*! < Timing configuration slot > */
|
|
#define BCM2835_SMI_DIRADRS_DEV_LS 8 /*! < Shift for configuration slot > */
|
|
#define BCM2835_SMI_DIRADRS_DEV0 0x00000000 /*! < Use timing config slot 0 > */
|
|
#define BCM2835_SMI_DIRADRS_DEV1 0x00000100 /*! < Use timing config slot 1 > */
|
|
#define BCM2835_SMI_DIRADRS_DEV2 0x00000200 /*! < Use timing config slot 2 > */
|
|
#define BCM2835_SMI_DIRADRS_DEV3 0x00000300 /*! < Use timing config slot 3 > */
|
|
#define BCM2835_SMI_DIRADRS_MSK 0x0000003F /*! < Adress bits SA5..SA0 > */
|
|
#define BCM2835_SMI_DIRADRS_LS 0 /*! < Shift for address bits > */
|
|
|
|
/* SMI clock control registers : defined as offset from bcm2835_clk */
|
|
#define SMICLK_CNTL (44) /* = 0xB0 */
|
|
#define SMICLK_DIV (45) /* = 0xB4 */
|
|
|
|
|
|
/* 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 32 bits */
|
|
#define BCM2835_ST_CHI 0x0008 /*!< System Timer Counter Upper 32 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 offsets (ie 4 byte multiples) */
|
|
#define BCM2835_PWMCLK_CNTL 40
|
|
#define BCM2835_PWMCLK_DIV 41
|
|
#define BCM2835_PWM_PASSWRD (0x5A << 24) /*!< Password to enable setting PWM clock */
|
|
|
|
#define BCM2835_PWM1_MS_MODE 0x8000 /*!< Run in Mark/Space mode */
|
|
#define BCM2835_PWM1_USEFIFO 0x2000 /*!< Data from FIFO */
|
|
#define BCM2835_PWM1_REVPOLAR 0x1000 /*!< Reverse polarity */
|
|
#define BCM2835_PWM1_OFFSTATE 0x0800 /*!< Ouput Off state */
|
|
#define BCM2835_PWM1_REPEATFF 0x0400 /*!< Repeat last value if FIFO empty */
|
|
#define BCM2835_PWM1_SERIAL 0x0200 /*!< Run in serial mode */
|
|
#define BCM2835_PWM1_ENABLE 0x0100 /*!< Channel Enable */
|
|
|
|
#define BCM2835_PWM0_MS_MODE 0x0080 /*!< Run in Mark/Space mode */
|
|
#define BCM2835_PWM_CLEAR_FIFO 0x0040 /*!< Clear FIFO */
|
|
#define BCM2835_PWM0_USEFIFO 0x0020 /*!< Data from FIFO */
|
|
#define BCM2835_PWM0_REVPOLAR 0x0010 /*!< Reverse polarity */
|
|
#define BCM2835_PWM0_OFFSTATE 0x0008 /*!< Ouput Off state */
|
|
#define BCM2835_PWM0_REPEATFF 0x0004 /*!< Repeat last value if FIFO empty */
|
|
#define BCM2835_PWM0_SERIAL 0x0002 /*!< Run in serial mode */
|
|
#define BCM2835_PWM0_ENABLE 0x0001 /*!< Channel Enable */
|
|
|
|
/*! \brief bcm2835PWMClockDivider
|
|
Specifies the divider used to generate the PWM clock from the system clock.
|
|
Figures below give the divider, clock period and clock frequency.
|
|
Clock divided is based on nominal PWM base clock rate of 19.2MHz
|
|
The frequencies shown for each divider have been confirmed by measurement
|
|
*/
|
|
typedef enum
|
|
{
|
|
BCM2835_PWM_CLOCK_DIVIDER_2048 = 2048, /*!< 2048 = 9.375kHz */
|
|
BCM2835_PWM_CLOCK_DIVIDER_1024 = 1024, /*!< 1024 = 18.75kHz */
|
|
BCM2835_PWM_CLOCK_DIVIDER_512 = 512, /*!< 512 = 37.5kHz */
|
|
BCM2835_PWM_CLOCK_DIVIDER_256 = 256, /*!< 256 = 75kHz */
|
|
BCM2835_PWM_CLOCK_DIVIDER_128 = 128, /*!< 128 = 150kHz */
|
|
BCM2835_PWM_CLOCK_DIVIDER_64 = 64, /*!< 64 = 300kHz */
|
|
BCM2835_PWM_CLOCK_DIVIDER_32 = 32, /*!< 32 = 600.0kHz */
|
|
BCM2835_PWM_CLOCK_DIVIDER_16 = 16, /*!< 16 = 1.2MHz */
|
|
BCM2835_PWM_CLOCK_DIVIDER_8 = 8, /*!< 8 = 2.4MHz */
|
|
BCM2835_PWM_CLOCK_DIVIDER_4 = 4, /*!< 4 = 4.8MHz */
|
|
BCM2835_PWM_CLOCK_DIVIDER_2 = 2, /*!< 2 = 9.6MHz, fastest you can get */
|
|
BCM2835_PWM_CLOCK_DIVIDER_1 = 1 /*!< 1 = 4.6875kHz, same as divider 4096 */
|
|
} bcm2835PWMClockDivider;
|
|
|
|
/* Historical name compatibility */
|
|
#ifndef BCM2835_NO_DELAY_COMPATIBILITY
|
|
#define delay(x) bcm2835_delay(x)
|
|
#define delayMicroseconds(x) bcm2835_delayMicroseconds(x)
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*! \defgroup init Library initialisation and management
|
|
These functions allow you to intialise and control the bcm2835 library
|
|
@{
|
|
*/
|
|
|
|
/*! Initialise the library by opening /dev/mem (if you are root)
|
|
or /dev/gpiomem (if you are not)
|
|
and getting pointers to the
|
|
internal memory for BCM 2835 device registers. You must call this (successfully)
|
|
before calling any other
|
|
functions in this library (except bcm2835_set_debug).
|
|
If bcm2835_init() fails by returning 0,
|
|
calling any other function may result in crashes or other failures.
|
|
If bcm2835_init() succeeds but you are not running as root, then only gpio operations
|
|
are permitted, and calling any other functions may result in crashes or other failures. .
|
|
Prints messages to stderr in case of errors.
|
|
\return 1 if successful else 0
|
|
*/
|
|
extern int bcm2835_init(void);
|
|
|
|
/*! Close the library, deallocating any allocated memory and closing /dev/mem
|
|
\return 1 if successful else 0
|
|
*/
|
|
extern int bcm2835_close(void);
|
|
|
|
/*! Sets the debug level of the library.
|
|
A value of 1 prevents mapping to /dev/mem, and makes the library print out
|
|
what it would do, rather than accessing the GPIO registers.
|
|
A value of 0, the default, causes normal operation.
|
|
Call this before calling bcm2835_init();
|
|
\param[in] debug The new debug level. 1 means debug
|
|
*/
|
|
extern void bcm2835_set_debug(uint8_t debug);
|
|
|
|
/*! Returns the version number of the library, same as BCM2835_VERSION
|
|
\return the current library version number
|
|
*/
|
|
extern unsigned int bcm2835_version(void);
|
|
|
|
/*! @} */
|
|
|
|
/*! \defgroup lowlevel Low level register access
|
|
These functions provide low level register access, and should not generally
|
|
need to be used
|
|
|
|
@{
|
|
*/
|
|
|
|
/*! Gets the base of a register
|
|
\param[in] regbase You can use one of the common values BCM2835_REGBASE_*
|
|
in \ref bcm2835RegisterBase
|
|
\return the register base
|
|
\sa Physical Addresses
|
|
*/
|
|
extern uint32_t* bcm2835_regbase(uint8_t regbase);
|
|
|
|
/*! Reads 32 bit value from a peripheral address WITH a memory barrier before and after each read.
|
|
This is safe, but slow. The MB before protects this read from any in-flight reads that didn't
|
|
use a MB. The MB after protects subsequent reads from another peripheral.
|
|
|
|
\param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
|
|
\return the value read from the 32 bit register
|
|
\sa Physical Addresses
|
|
*/
|
|
extern uint32_t bcm2835_peri_read(volatile uint32_t* paddr);
|
|
|
|
/*! Reads 32 bit value from a peripheral address WITHOUT the read barriers
|
|
You should only use this when:
|
|
o your code has previously called bcm2835_peri_read() for a register
|
|
within the same peripheral, and no read or write to another peripheral has occurred since.
|
|
o your code has called bcm2835_memory_barrier() since the last access to ANOTHER peripheral.
|
|
|
|
\param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
|
|
\return the value read from the 32 bit register
|
|
\sa Physical Addresses
|
|
*/
|
|
extern uint32_t bcm2835_peri_read_nb(volatile uint32_t* paddr);
|
|
|
|
|
|
/*! Writes 32 bit value from a peripheral address WITH a memory barrier before and after each write
|
|
This is safe, but slow. The MB before ensures that any in-flight write to another peripheral
|
|
completes before this write is issued. The MB after ensures that subsequent 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 value from a peripheral address without the write barrier
|
|
You should only use this when:
|
|
o your code has previously called bcm2835_peri_write() for a register
|
|
within the same peripheral, and no other peripheral access has occurred since.
|
|
o your code has called bcm2835_memory_barrier() since the last access to ANOTHER 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 \ref bcm2835FunctionSelect
|
|
*/
|
|
extern void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode);
|
|
|
|
/*! Sets the specified pin output to
|
|
HIGH.
|
|
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
|
\sa bcm2835_gpio_write()
|
|
*/
|
|
extern void bcm2835_gpio_set(uint8_t pin);
|
|
|
|
/*! Sets the specified pin output to
|
|
LOW.
|
|
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
|
\sa bcm2835_gpio_write()
|
|
*/
|
|
extern void bcm2835_gpio_clr(uint8_t pin);
|
|
|
|
/*! Sets any of the first 32 GPIO output pins specified in the mask to
|
|
HIGH.
|
|
\param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
|
|
\sa bcm2835_gpio_write_multi()
|
|
*/
|
|
extern void bcm2835_gpio_set_multi(uint32_t mask);
|
|
|
|
/*! Sets any of the first 32 GPIO output pins specified in the mask to
|
|
LOW.
|
|
\param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
|
|
\sa bcm2835_gpio_write_multi()
|
|
*/
|
|
extern void bcm2835_gpio_clr_multi(uint32_t mask);
|
|
|
|
/*! Reads the current level on the specified
|
|
pin and returns either HIGH or LOW. Works whether or not the pin
|
|
is an input or an output.
|
|
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
|
\return the current level either HIGH or LOW
|
|
*/
|
|
extern uint8_t bcm2835_gpio_lev(uint8_t pin);
|
|
|
|
/*! Event Detect Status.
|
|
Tests whether the specified pin has detected a level or edge
|
|
as requested by bcm2835_gpio_ren(), bcm2835_gpio_fen(), bcm2835_gpio_hen(),
|
|
bcm2835_gpio_len(), bcm2835_gpio_aren(), bcm2835_gpio_afen().
|
|
Clear the flag for a given pin by calling bcm2835_gpio_set_eds(pin);
|
|
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
|
\return HIGH if the event detect status for the given pin is true.
|
|
*/
|
|
extern uint8_t bcm2835_gpio_eds(uint8_t pin);
|
|
|
|
/*! Same as bcm2835_gpio_eds() but checks if any of the pins specified in
|
|
the mask have detected a level or edge.
|
|
\param[in] mask Mask of pins to check. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
|
|
\return Mask of pins HIGH if the event detect status for the given pin is true.
|
|
*/
|
|
extern uint32_t bcm2835_gpio_eds_multi(uint32_t mask);
|
|
|
|
/*! Sets the Event Detect Status register for a given pin to 1,
|
|
which has the effect of clearing the flag. Use this afer seeing
|
|
an Event Detect Status on the pin.
|
|
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
|
*/
|
|
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 Status.
|
|
The GPRENn registers use
|
|
synchronous edge detection. This means the input signal is sampled using the
|
|
system clock and then it is looking for a ?011? pattern on the sampled signal. 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 the
|
|
system clock and then it is looking for a ?100? pattern on the sampled signal. 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 Event 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 Status.
|
|
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_* from bcm2835PUDControl
|
|
On the RPI 4, although this function and bcm2835_gpio_pudclk() are supported for backward
|
|
compatibility, new code should always use bcm2835_gpio_set_pud().
|
|
\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.
|
|
|
|
On the RPI 4, although this function and bcm2835_gpio_pud() are supported for backward
|
|
compatibility, new code should always use bcm2835_gpio_set_pud().
|
|
|
|
\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.
|
|
Caution: requires root access.
|
|
\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.
|
|
Caution: requires root access.
|
|
\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 bcm2835PadGroup. Note
|
|
that it is not necessary to include BCM2835_PAD_PASSWRD in the mask as this
|
|
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 nanosleep():
|
|
If the interval specified in req is not an exact multiple of the granularity
|
|
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 system timers,
|
|
However, you are at the mercy of nanosleep(). From the manual for nanosleep():
|
|
If the interval specified in req is not an exact multiple of the granularity
|
|
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 state 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 given 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 convenient 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_* from bcm2835PUDControl
|
|
*/
|
|
extern void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud);
|
|
|
|
/*! On the BCM2711 based RPI 4, gets the current Pull-up/down mode for the specified pin.
|
|
Returns one of BCM2835_GPIO_PUD_* from bcm2835PUDControl.
|
|
On earlier RPI versions not based on the BCM2711, returns BCM2835_GPIO_PUD_ERROR
|
|
\param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
|
*/
|
|
|
|
extern uint8_t bcm2835_gpio_get_pud(uint8_t pin);
|
|
|
|
/*! @} */
|
|
|
|
/*! \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 return the pins to
|
|
their default functions.
|
|
\sa bcm2835_spi_end()
|
|
\return 1 if successful, 0 otherwise (perhaps because you are not running as root)
|
|
*/
|
|
extern int 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
|
|
Set the bit order to be used for transmit and receive. The bcm2835 SPI0 only supports BCM2835_SPI_BIT_ORDER_MSB,
|
|
so if you select BCM2835_SPI_BIT_ORDER_LSB, the bytes will be reversed in software.
|
|
The library defaults to BCM2835_SPI_BIT_ORDER_MSB.
|
|
\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 clock divider by converting the speed parameter to
|
|
the equivalent SPI clock divider. ( see \sa bcm2835_spi_setClockDivider)
|
|
\param[in] speed_hz The desired SPI clock speed in Hz
|
|
*/
|
|
extern void bcm2835_spi_set_speed_hz(uint32_t speed_hz);
|
|
|
|
/*! 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 asserted during the
|
|
transfer.
|
|
\param[in] cs Specifies the CS pins(s) that are used to activate the desired 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 pin(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_chipSelect)
|
|
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 slave.
|
|
Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect)
|
|
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 least len bytes long
|
|
Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual
|
|
\param[in] tbuf Buffer of bytes to send.
|
|
\param[out] rbuf Received bytes will by put in this buffer
|
|
\param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send/received
|
|
\sa bcm2835_spi_transfer()
|
|
*/
|
|
extern void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len);
|
|
|
|
/*! Transfers any number of bytes to and from the currently selected SPI slave
|
|
using bcm2835_spi_transfernb.
|
|
The returned data from the slave replaces the transmitted data in the buffer.
|
|
\param[in,out] buf Buffer of bytes to send. Received bytes will replace the contents
|
|
\param[in] len Number of bytes int eh buffer, and the number of bytes to send/received
|
|
\sa bcm2835_spi_transfer()
|
|
*/
|
|
extern void bcm2835_spi_transfern(char* buf, uint32_t len);
|
|
|
|
/*! Transfers any number of bytes to the currently selected SPI slave.
|
|
Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect)
|
|
during the transfer.
|
|
\param[in] buf Buffer of bytes to send.
|
|
\param[in] len Number of bytes in the buf buffer, and the number of bytes to send
|
|
*/
|
|
extern void bcm2835_spi_writenb(const char* buf, uint32_t len);
|
|
|
|
/*! Transfers half-word to the currently selected SPI slave.
|
|
Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect)
|
|
during the transfer.
|
|
Clocks the 8 bit value out on MOSI, and simultaneously clocks in data from MISO.
|
|
Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual
|
|
\param[in] data The 8 bit data byte to write to MOSI
|
|
\sa bcm2835_spi_writenb()
|
|
*/
|
|
extern void bcm2835_spi_write(uint16_t data);
|
|
|
|
/*! Start AUX SPI operations.
|
|
Forces RPi AUX SPI pins P1-38 (MOSI), P1-38 (MISO), P1-40 (CLK) and P1-36 (CE2)
|
|
to alternate function ALT4, which enables those pins for SPI interface.
|
|
\return 1 if successful, 0 otherwise (perhaps because you are not running as root)
|
|
*/
|
|
extern int bcm2835_aux_spi_begin(void);
|
|
|
|
/*! End AUX SPI operations.
|
|
SPI1 pins P1-38 (MOSI), P1-38 (MISO), P1-40 (CLK) and P1-36 (CE2)
|
|
are returned to their default INPUT behaviour.
|
|
*/
|
|
extern void bcm2835_aux_spi_end(void);
|
|
|
|
/*! Sets the AUX SPI clock divider and therefore the AUX SPI clock speed.
|
|
\param[in] divider The desired AUX SPI clock divider.
|
|
*/
|
|
extern void bcm2835_aux_spi_setClockDivider(uint16_t divider);
|
|
|
|
/*!
|
|
* Calculates the input for \sa bcm2835_aux_spi_setClockDivider
|
|
* @param speed_hz A value between \sa BCM2835_AUX_SPI_CLOCK_MIN and \sa BCM2835_AUX_SPI_CLOCK_MAX
|
|
* @return Input for \sa bcm2835_aux_spi_setClockDivider
|
|
*/
|
|
extern uint16_t bcm2835_aux_spi_CalcClockDivider(uint32_t speed_hz);
|
|
|
|
/*! Transfers half-word to the AUX SPI slave.
|
|
Asserts the currently selected CS pins during the transfer.
|
|
\param[in] data The 8 bit data byte to write to MOSI
|
|
\return The 16 bit byte simultaneously read from MISO
|
|
\sa bcm2835_spi_transfern()
|
|
*/
|
|
extern void bcm2835_aux_spi_write(uint16_t data);
|
|
|
|
/*! Transfers any number of bytes to the AUX SPI slave.
|
|
Asserts the CE2 pin during the transfer.
|
|
\param[in] buf Buffer of bytes to send.
|
|
\param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send
|
|
*/
|
|
extern void bcm2835_aux_spi_writenb(const char *buf, uint32_t len);
|
|
|
|
/*! Transfers any number of bytes to and from the AUX SPI slave
|
|
using bcm2835_aux_spi_transfernb.
|
|
The returned data from the slave replaces the transmitted data in the buffer.
|
|
\param[in,out] buf Buffer of bytes to send. Received bytes will replace the contents
|
|
\param[in] len Number of bytes in the buffer, and the number of bytes to send/received
|
|
\sa bcm2835_aux_spi_transfer()
|
|
*/
|
|
extern void bcm2835_aux_spi_transfern(char *buf, uint32_t len);
|
|
|
|
/*! Transfers any number of bytes to and from the AUX SPI slave.
|
|
Asserts the CE2 pin 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 least len bytes long
|
|
\param[in] tbuf Buffer of bytes to send.
|
|
\param[out] rbuf Received bytes will by put in this buffer
|
|
\param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send/received
|
|
*/
|
|
extern void bcm2835_aux_spi_transfernb(const char *tbuf, char *rbuf, uint32_t len);
|
|
|
|
/*! Transfers one byte to and from the AUX SPI slave.
|
|
Clocks the 8 bit value out on MOSI, and simultaneously clocks in data from MISO.
|
|
Returns the read data byte from the slave.
|
|
\param[in] value The 8 bit data byte to write to MOSI
|
|
\return The 8 bit byte simultaneously read from MISO
|
|
\sa bcm2835_aux_spi_transfern()
|
|
*/
|
|
extern uint8_t bcm2835_aux_spi_transfer(uint8_t value);
|
|
|
|
/*! @} */
|
|
|
|
/*! \defgroup i2c I2C access
|
|
These functions let you use I2C (The Broadcom Serial Control bus with the Philips
|
|
I2C bus/interface version 2.1 January 2000.) to interface with an external I2C device.
|
|
@{
|
|
*/
|
|
|
|
/*! Start I2C operations.
|
|
Forces RPi I2C pins P1-03 (SDA) and P1-05 (SCL)
|
|
to alternate function ALT0, which enables those pins for I2C interface.
|
|
You should call bcm2835_i2c_end() when all I2C functions are complete to return the pins to
|
|
their default functions
|
|
\return 1 if successful, 0 otherwise (perhaps because you are not running as root)
|
|
\sa bcm2835_i2c_end()
|
|
*/
|
|
extern int bcm2835_i2c_begin(void);
|
|
|
|
/*! End I2C operations.
|
|
I2C pins P1-03 (SDA) and P1-05 (SCL)
|
|
are returned to their default INPUT behaviour.
|
|
*/
|
|
extern void bcm2835_i2c_end(void);
|
|
|
|
/*! Sets the I2C slave address.
|
|
\param[in] addr The I2C slave address.
|
|
*/
|
|
extern void bcm2835_i2c_setSlaveAddress(uint8_t addr);
|
|
|
|
/*! Sets the I2C clock divider and therefore the I2C clock speed.
|
|
\param[in] divider The desired I2C clock divider, one of BCM2835_I2C_CLOCK_DIVIDER_*,
|
|
see \ref bcm2835I2CClockDivider
|
|
*/
|
|
extern void bcm2835_i2c_setClockDivider(uint16_t divider);
|
|
|
|
/*! Sets the I2C clock divider by converting the baudrate parameter to
|
|
the equivalent I2C clock divider. ( see \sa bcm2835_i2c_setClockDivider)
|
|
For the I2C standard 100khz you would set baudrate to 100000
|
|
The use of baudrate corresponds to its use in the I2C kernel device
|
|
driver. (Of course, bcm2835 has nothing to do with the kernel driver)
|
|
*/
|
|
extern void bcm2835_i2c_set_baudrate(uint32_t baudrate);
|
|
|
|
/*! Transfers any number of bytes to the currently selected I2C slave.
|
|
(as previously set by \sa bcm2835_i2c_setSlaveAddress)
|
|
\param[in] buf Buffer of bytes to send.
|
|
\param[in] len Number of bytes in the buf buffer, and the number of bytes to send.
|
|
\return reason see \ref bcm2835I2CReasonCodes
|
|
*/
|
|
extern uint8_t bcm2835_i2c_write(const char * buf, uint32_t len);
|
|
|
|
/*! Transfers any number of bytes from the currently selected I2C slave.
|
|
(as previously set by \sa bcm2835_i2c_setSlaveAddress)
|
|
\param[in] buf Buffer of bytes to receive.
|
|
\param[in] len Number of bytes in the buf buffer, and the number of bytes to received.
|
|
\return reason see \ref bcm2835I2CReasonCodes
|
|
*/
|
|
extern uint8_t bcm2835_i2c_read(char* buf, uint32_t len);
|
|
|
|
/*! Allows reading from I2C slaves that require a repeated start (without any prior stop)
|
|
to read after the required slave register has been set. For example, the popular
|
|
MPL3115A2 pressure and temperature sensor. Note that your device must support or
|
|
require this mode. If your device does not require this mode then the standard
|
|
combined:
|
|
\sa bcm2835_i2c_write
|
|
\sa bcm2835_i2c_read
|
|
are a better choice.
|
|
Will read from the slave previously set by \sa bcm2835_i2c_setSlaveAddress
|
|
\param[in] regaddr Buffer containing the slave register you wish to read from.
|
|
\param[in] buf Buffer of bytes to receive.
|
|
\param[in] len Number of bytes in the buf buffer, and the number of bytes to received.
|
|
\return reason see \ref bcm2835I2CReasonCodes
|
|
*/
|
|
extern uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len);
|
|
|
|
/*! Allows sending an arbitrary number of bytes to I2C slaves before issuing a repeated
|
|
start (with no prior stop) and reading a response.
|
|
Necessary for devices that require such behavior, such as the MLX90620.
|
|
Will write to and read from the slave previously set by \sa bcm2835_i2c_setSlaveAddress
|
|
\param[in] cmds Buffer containing the bytes to send before the repeated start condition.
|
|
\param[in] cmds_len Number of bytes to send from cmds buffer
|
|
\param[in] buf Buffer of bytes to receive.
|
|
\param[in] buf_len Number of bytes to receive in the buf buffer.
|
|
\return reason see \ref bcm2835I2CReasonCodes
|
|
*/
|
|
extern uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint32_t buf_len);
|
|
|
|
/*! @} */
|
|
|
|
/*! \defgroup smi SMI bus support
|
|
Allows access to SMI bus
|
|
@{
|
|
*/
|
|
/*! Start SMI operations.
|
|
Forces RPi SMI pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
|
|
to alternate function ALT1, which enables those pins for SMI interface.
|
|
You should call bcm2835_smi_end() when all SMI functions are complete to return the pins to
|
|
their default functions.
|
|
Only address bits SA0 to SA3 are available as RPi uses GPIO0 (SA5) and GPIO1 (SA4) for I2C
|
|
HAT identification EEPROM access
|
|
\sa bcm2835_smi_end()
|
|
\return 1 if successful, 0 otherwise (perhaps because you are not running as root)
|
|
*/
|
|
extern int bcm2835_smi_begin (void);
|
|
|
|
/*! End SMI operations.
|
|
SMI 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_smi_end (void);
|
|
|
|
/*! Setup SMI bus cycle timing parameters
|
|
There are four SMI channels for read operation and four channels for write operation
|
|
Cycles are expressed as multiple of 8ns
|
|
Note that Pace cycles are not used (no effect on hardware) but they are required for
|
|
configuration. It is recommended to set this value to 1 (and not 0) to have the
|
|
smallest cycle in case the hardware would recognize it
|
|
\param[in] smichannel SMI configuration slot to setup (0 to 3)
|
|
\param[in] readchannel Set to 1 to configure the read channel (0 = configure write channel)
|
|
\param[in] setupcycles Time between address assertion on bus and OE/WR signal assertion
|
|
\param[in] strobecycles Duration of OE/WR signal assertion
|
|
\param[in] holdcycles Time after OE/WR deassertion before address is deasserted
|
|
\param[in] pacecycles Time before next SMI bus cycle
|
|
*/
|
|
extern void bcm2835_smi_set_timing(uint32_t smichannel, uint32_t readchannel,
|
|
uint32_t setupcycles, uint32_t strobecycles,
|
|
uint32_t holdcycles, uint32_t pacecycles);
|
|
|
|
/*! Transfers one byte to SMI bus.
|
|
Uses polled transfer as described in BCM 2835 ARM Peripherals manual
|
|
\param[in] timingslot SMI configuration slot to use (0 to 3)
|
|
\param[in] data The data byte to write
|
|
\param[in] address The address to write to
|
|
\sa bcm2835_smi_writenb()
|
|
*/
|
|
extern void bcm2835_smi_write (uint32_t smichannel, uint8_t data, uint32_t address);
|
|
|
|
/*! Reads one byte from SMI bus.
|
|
Uses polled transfer as described in BCM 2835 ARM Peripherals manual
|
|
\param[in] smichannel SMI configuration slot to use (0 to 3)
|
|
\param[in] address The address to read from
|
|
\return value read from SMI bus
|
|
\sa bcm2835_smi_readnb()
|
|
*/
|
|
extern uint32_t bcm2835_smi_read (uint32_t smichannel, uint32_t address);
|
|
|
|
/*! @} */
|
|
|
|
|
|
/*! \defgroup st System Timer access
|
|
Allows access to and delays using the System Timer Counter.
|
|
@{
|
|
*/
|
|
|
|
/*! Read the System Timer Counter register.
|
|
\return the value read from the System Timer Counter Lower 32 bits register
|
|
*/
|
|
extern uint64_t bcm2835_st_read(void);
|
|
|
|
/*! Delays for the specified number of microseconds with offset.
|
|
\param[in] offset_micros Offset in microseconds
|
|
\param[in] micros Delay in microseconds
|
|
*/
|
|
extern void bcm2835_st_delay(uint64_t offset_micros, uint64_t micros);
|
|
|
|
/*! @} */
|
|
|
|
/*! \defgroup pwm Pulse Width Modulation
|
|
Allows control of 2 independent PWM channels. A limited subset of GPIO pins
|
|
can be connected to one of these 2 channels, allowing PWM control of GPIO pins.
|
|
You have to set the desired pin into a particular Alt Fun to PWM output. See the PWM
|
|
documentation on the Main Page.
|
|
@{
|
|
*/
|
|
|
|
/*! Sets the PWM clock divisor,
|
|
to control the basic PWM pulse widths.
|
|
\param[in] divisor Divides the basic 19.2MHz PWM clock. You can use one of the common
|
|
values BCM2835_PWM_CLOCK_DIVIDER_* in \ref bcm2835PWMClockDivider
|
|
*/
|
|
extern void bcm2835_pwm_set_clock(uint32_t divisor);
|
|
|
|
/*! Sets the mode of the given PWM channel,
|
|
allowing you to control the PWM mode and enable/disable that channel
|
|
\param[in] channel The PWM channel. 0 or 1.
|
|
\param[in] markspace Set true if you want Mark-Space mode. 0 for Balanced mode.
|
|
\param[in] enabled Set true to enable this channel and produce PWM pulses.
|
|
*/
|
|
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 SPI 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.
|
|
*/
|
|
|
|
/*! example spimem_test.c
|
|
Shows how to use the included little library (spiram.c and spiram.h)
|
|
to read and write SPI RAM chips such as 23K256-I/P
|
|
*/
|