Library for Raspberry Pi
Version: | 2014-03-06 |
---|---|
Status: | beta |
SeeAlso: | Raspberry Pi documentation, BCM2835 datasheet |
Author: | Advamation, Roland Koebler (support@advamation.de) |
Copyright: | (c) Advamation (info@advamation.de) |
License: | open-source / MIT |
RCS: | am_rpi.c,v 1.75 2014/05/02 11:49:25 rk Exp |
Table of contents
- 1 init / exit / logging
- 2 system information
- 3 miscellaneous functions
- 4 system timer
- 5 I/O
- 5.1 I/O pins
- 5.2 I/O configuration
- 5.3 GPIO
- 5.4 SPI
- 5.4.1 configure SPI-pins
- 5.4.2 manually lock SPI
- 5.4.3 manually unlock SPI
- 5.4.4 set SPI-auto-locking timeout
- 5.4.5 configure SPI
- 5.4.6 read SPI-configuration
- 5.4.7 set SPI clock
- 5.4.8 read SPI clock
- 5.4.9 start/init SPI
- 5.4.10 stop/end SPI
- 5.4.11 write byte to SPI FIFO
- 5.4.12 read byte from SPI FIFO
- 5.4.13 write byte to SPI FIFO (blocking) + return received byte (if any)
- 5.4.14 wait until SPI is done
- 5.4.15 communicate over SPI
- 5.4.16 communicate over SPI: write some data N times
- 5.4.17 communicate over SPI: write a data-window
- 5.4.18 SPI interface
- 5.5 I2C
- 5.5.1 configure I2C-pins
- 5.5.2 en-/disable I2C
- 5.5.3 check if I2C is enabled
- 5.5.4 manually lock I2C
- 5.5.5 manually unlock I2C
- 5.5.6 set I2C-auto-locking timeout
- 5.5.7 set I2C clock
- 5.5.8 read I2C clock
- 5.5.9 read byte from I2C-FIFO
- 5.5.10 write byte to I2C-FIFO
- 5.5.11 wait until I2C is done
- 5.5.12 read data from I2C
- 5.5.13 write data to I2C
- 5.5.14 write data to I2C, then read data
- 5.5.15 read data from I2C with 10-bit slave-address
- 5.5.16 write data to I2C with 10-bit slave-address
- 5.5.17 write data to I2C, then read data, 10-bit slave-address
- 5.5.18 I2C interface
- 5.5.19 I2C-communication with Advamation RS-485-/I2C-protocol
- 6 UI-functions
1 init / exit / logging
1.1 init library + map registers
Check if it's a Raspberry Pi, initialize the library, increase the init-counter and map I/O memory. Does nothing (except increasing the init-counter), if already initialized.
am_rpi_init() and am_rpi_exit() should always be called pairwise.
Usage: | AM_ERROR am_rpi_init(void) |
---|---|
Returns: | 0 on success, <0 on error |
1.2 exit library + unmap registers
Decrease the init-counter. If 0, de-initialize the library, unmap I/O memory, close logfiles and reset log-level.
Usage: | void am_rpi_exit(void) |
---|
1.3 configure logging
All messages up to "level" are printed and/or stored in the logfile. DEBUG/INFO are printed to stdout, MESSAGE/WARNING/CRITICAL/ERROR to stderr.
The available levels are:
- AM_LOG_LEVEL_DEBUG
- AM_LOG_LEVEL_INFO
- AM_LOG_LEVEL_MESSAGE
- AM_LOG_LEVEL_WARNING (default)
- AM_LOG_LEVEL_CRITICAL
- AM_LOG_LEVEL_ERROR
Usage: | AM_ERROR am_rpi_logging(enum am_log_level level, char const *logfile, enum am_log_level logfile_level) |
---|---|
Parameters: |
|
Returns: | 0 on success, <0 on error (AM_ERROR_INVALID_ARGUMENT, AM_ERROR_IO if the logfile cannot be opened (see errno for details)) |
SeeAlso: | am_logging |
2 system information
Note: | These functions work even without initializing the library! |
---|
2.1 hardware information
Check if this is a Raspberry Pi and get its hardware information from /proc/cpuinfo.
Usage: | AM_ERROR am_rpi_info(char const **model, char const **rev, char const **manufacturer, uint16_t *rev_raw, uint64_t *serial) |
||||||
---|---|---|---|---|---|---|---|
Parameters: |
|
||||||
Returns: | 0 on success, AM_ERROR_DEVICE_NOT_SUPPORTED if this is no Raspberry Pi, AM_ERROR_MEMORY, AM_ERROR_IO, AM_ERROR_PERMISSIONS on error |
||||||
Uses: | /proc/cpuinfo |
||||||
Note: |
|
2.2 get Raspberry Pi revision-number
Get Raspberry Pi revision-number. This reads an internal variable (and is fast after am_rpi_init()), and uses am_rpi_info() otherwise.
Usage: | AM_ERROR am_rpi_info_rev(uint16_t *rev_raw) |
---|---|
Returns: | 0 on success, <0 on error; after am_rpi_info, always 0 is returned |
2.3 CPU-clock speed information
Usage: | AM_ERROR am_rpi_info_clk(uint16_t *clk, uint16_t *clk_min, uint16_t *clk_max) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_DEVICE_UNEXPECTED, AM_ERROR_MEMORY, AM_ERROR_PERMISSIONS, AM_ERROR_IO on error |
Note: | All output-parameters may be NULL if the value is not needed. |
Uses: | /sys/devices/system/cpu/cpu0/cpufreq/ |
2.4 memory size and usage information
Usage: | AM_ERROR am_rpi_info_memory(uint32_t *mem, uint32_t *used, uint32_t *free, uint32_t *free_buffers_cache) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_DEVICE_UNEXPECTED, AM_ERROR_MEMORY, AM_ERROR_PERMISSIONS, AM_ERROR_IO on error |
Note: |
|
Uses: | /proc/meminfo |
2.5 temperature information
Usage: | AM_ERROR am_rpi_info_temperature(double *t) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_DEVICE_UNEXPECTED, AM_ERROR_MEMORY, AM_ERROR_PERMISSIONS, AM_ERROR_IO on error |
Note: | All output-parameters may be NULL if the value is not needed. |
Uses: | /sys/class/thermal/thermal_zone0/temp |
3 miscellaneous functions
Note: | These functions work even without initializing the library! |
---|
3.1 delay / wait / sleep
Depending on the length of a delay, there are several ways:
- <= 1us:
- Delay via busy-loop, more or less counting machine cycles. Depends on CPU clock and compiler optimization, and causes system load. See am_rpi_delay_nop*().
- >= 1us:
- Delay-loop, waiting for a timer to reach the desired delay. Compiler- and clock-independent, guarantees a minimum delay. Causes system load. See am_rpi_delay_us().
- >= 60us:
- Sleep-functions (e.g. nanosleep(), g_usleep()) are probably best. Although they may delay the program much longer than requested, they don't cause system load.
3.1.1 wait CPU-cycles
Wait a specified amount of CPU cycles. Note that the delay is not completely predictable and depends on the system load and the CPU frequency.
The measured values for 700 MHz, gcc -O3/-O4, idle, are roughly:
n | ns |
---|---|
1 | 1.4 |
2 | 2.8 |
3 | 4.4 |
4 | 5.8 |
5 | 7.5 |
7 | 10.0 |
10 | 14.4 |
15 | 20.1 |
21 | 29.0 |
28 | 40.3 |
32 | 46.1 |
35 | 50.4 |
42 | 60.5 |
49 | 70.6 |
56 | 80.8 |
63 | 91.0 |
70 | 101.0 |
83 | 120.0 |
Usage: | am_rpi_delay_nop1() am_rpi_delay_nop2() ... am_rpi_delay_nop256() |
---|
3.1.2 wait some µs
Wait (at least) a specified amount of microseconds in a busy-loop.
Usage: | void am_rpi_delay_us(uint16_t us) |
---|---|
Parameters: |
|
4 system timer
Continuously running 64-bit, 1 MHz system timer.
4.1 read system timer
Usage: | uint64_t am_rpi_timer(void) |
---|---|
Returns: | 64-bit timer value |
4.2 read lower-half of system timer
Usage: | uint32_t am_rpi_timer_lo(void) |
---|---|
Returns: | 32-bit timer value |
5 I/O
Note: |
|
---|
5.1 I/O pins
GPIO connector:
Pin | Description | ALT0 | ALT1 | ALT2 | ALT3 | ALT4 | ALT5 | notes |
---|---|---|---|---|---|---|---|---|
P1-1 | (+3.3V) | (max. 50mA draw) | ||||||
P1-2 | (+5V) | |||||||
P1-3 | GPIO_0(Rev1) GPIO_2(Rev2) | SDA0 SDA1 | SA5 SA3 | (res) (res) | – – | – – | – – | incl. 1k8 pull-up incl. 1k8 pull-up |
P1-4 | (+5V) | |||||||
P1-5 | GPIO_1(Rev1) GPIO_3(Rev2) | SCL0 SCL1 | SA4 SA2 | (res) (res) | – – | – – | – – | incl. 1k8 pull-up incl. 1k8 pull-up |
P1-6 | (GND) | |||||||
P1-7 | GPIO_4 | GPCLK0 | SA1 | (res) | – | – | ARM_TDI | |
P1-8 | GPIO_14 | UART0_TXD | SD6 | (res) | – | – | UART1_TXD | default: UART0_TXD |
P1-9 | (GND) | |||||||
P1-10 | GPIO_15 | UART0_RXD | SD7 | (res) | – | – | UART1_RXD | default: UART0_RXD |
P1-11 | GPIO_17 | (res) | SD9 | (res) | UART0_RTS | SPI1_EN1_N | UART1_RTS | |
P1-12 | GPIO_18 | PCM_CLK | SD10 | (res) | sl.SDA/MOSI | SPI1_CE0_N | PWM0 | |
P1-13 | GPIO_21(Rev1) GPIO_27(Rev2) | PCM_DOUT (res) | SD13 (res) | (res) (res) | sl.CE_N SD1_DAT3 | SPI1_SCLK ARM_TMS | GPCLK1 (res) | |
P1-14 | (GND) | |||||||
P1-15 | GPIO_22 | (res) | SD14 | (res) | SD1_CLK | ARM_TRST | – | |
P1-16 | GPIO_23 | (res) | SD15 | (res) | SD1_CMD | ARM_RTCK | – | |
P1-17 | (+3.3V) | |||||||
P1-18 | GPIO_24 | (res) | SD16 | (res) | SD1_DAT0 | ARM_TDO | – | |
P1-19 | GPIO_10 | SPI0_MOSI | SD2 | (res) | – | – | – | |
P1-20 | (GND) | |||||||
P1-21 | GPIO_9 | SPI0_MISO | SD1 | (res) | – | – | – | |
P1-22 | GPIO_25 | (res) | SD17 | (res) | SD1_DAT1 | ARM_TCK | – | |
P1-23 | GPIO_11 | SPI0_SCLK | SD3 | (res) | – | – | – | |
P1-24 | GPIO_8 | SPI0_CE0_N | SD0 | (res) | – | – | – | |
P1-25 | (GND) | |||||||
P1-26 | GPIO_7 | SPI0_CE1_N | SW E_N/.. | (res) | – | – | – | |
P5-3 | GPIO_28 | SDA0 | SA5 | PCM_CLK | (res) | – | – | |
P5-4 | GPIO_29 | SCL0 | SA4 | PCM_FS | (res) | – | – | |
P5-5 | GPIO_30 | (res) | SA3 | PCM_DIN | CTS0 | – | – | |
P5-6 | GPIO_31 | (res) | SA2 | PCM_DOUT | RTS0 | – | – | |
CSI-14 | GPIO_2(Rev1) GPIO_0(Rev2) | SDA1 SDA0 | SA3 SA5 | (res) (res) | – – | – – | – – | incl. 1k?? pull-up, default: SDA incl. 1k?? pull-up, default: SDA |
CSI-13 | GPIO_3(Rev1) GPIO_1(Rev2) | SCL1 SCL0 | SA2 SA4 | (res) (res) | – – | – – | – – | incl. 1k?? pull-up, default: SCL incl. 1k?? pull-up, default: SCL |
CSI-12 | GPIO_5 | GPCLK1 | SA0 | (res) | – | – | ARM_TDO | default: CAM_CLK |
CSI-11 | GPIO_27(Rev1) GPIO_21(Rev2) | (res) PCM_DOUT | (res) SD13 | (res) (res) | SD1_DAT3 slave CE_N | ARM_TMS SPI1_SCLK | (res) GPCLK1 | default: CAM_GPIO default: CAM_GPIO |
GPIOs are not 5V-tolerant!
Note: |
|
---|
5.2 I/O configuration
5.2.1 configure I/O pins
Usage: | AM_ERROR am_rpi_gpio_config(uint32_t gpios, enum am_rpi_gpiomode mode) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on error |
5.2.2 read I/O pin configuration
Usage: | int am_rpi_gpio_config_read(enum am_rpi_gpio gpio) |
---|---|
Parameters: |
|
Returns: | enum am_rpi_gpiomode on success, AM_ERROR_INVALID_ARGUMENT on error |
5.2.3 configure GPIO-pin pull-up/pull-down
Usage: | AM_ERROR am_rpi_gpio_pullupdown(uint32_t gpios, enum am_rpi_pullupdown pullupdown) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on error |
Note: | On power-down, the following pull-ups/-downs are active:
|
5.3 GPIO
5.3.1 read GPIO(s)
Usage: | uint32_t am_rpi_gpio_read(uint32_t gpios) |
---|---|
Parameters: |
|
Returns: | read input levels, masked by gpios |
5.3.2 write GPIO output level
Usage: | AM_ERROR am_rpi_gpio_write(uint32_t gpios, bool level) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on error |
5.3.3 set GPIO(s)
Usage: | AM_ERROR am_rpi_gpio_set(uint32_t gpios) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on error |
5.3.4 clear GPIO(s)
Usage: | AM_ERROR am_rpi_gpio_clr(uint32_t gpios) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on error |
5.4 SPI
Broadcom BCM2835 contains 3 SPI interfaces: 1 full-featured SPI (SPI0) and two mini-SPIs (SPI1, SPI2). But only SPI0 is accessible on the Raspberry Pi.
This library supports concurrent access to the SPI from different programs, which use this library, by using automatic locks:
- Before every communication, the SPI is locked. If another program has currently locked the SPI, the functions wait until the SPI becomes unlocked or a timeout occurs.
- After successfully locking the SPI, the SPI is reconfigured.
- After communication, the SPI is unlocked again.
- It's also possible to manually lock the SPI, but this should be used with care, since it could prevent other programs from accessing SPI at all.
If you want to use SPI from different threads in a program, use e.g. a mutex to make sure only 1 thread accesses the SPI at the same time. If the threads use different SPI-configurations, make sure to reconfigure the SPI after acquiring the mutex.
Note: |
|
---|
5.4.1 configure SPI-pins
Use GPIO_P1_21 as MISO, GPIO_P1_19 as MOSI, GPIO_P1_23 as SCK, and optionally GPIO_P1_24 as CS0 / GPIO_P1_26 as CS1
Usage: | void am_rpi_spi_pins(bool cs0, bool cs1) |
---|---|
Parameters: |
|
5.4.2 manually lock SPI
Wait until the SPI is unlocked and manually lock (and configure) the SPI.
Usually, it's not necessary to use this function, since am_rpi_spi_start()/_stop()/_comm()/_comm_writeN()/_write_window() automatically lock and unlock the SPI. But the SPI may be locked manually, e.g. if several SPI-communications must directly follow each other, or to prevent other programs to access the SPI.
Note that you additionally have to use a mutex, if you're accessing the SPI from several threads in the same program.
Always use am_rpi_spi_unlock() for every successful call to this function.
Usage: | AM_ERROR am_rpi_spi_lock(int32_t timeout_ms) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_BUSY after timeout |
5.4.3 manually unlock SPI
Manually unlock the SPI.
This is usually only necessary after am_rpi_spi_lock(); otherwise, locking and unlocking is automatically done by am_rpi_spi_start()/_stop().
Usage: | void am_rpi_spi_unlock(void) |
---|
5.4.4 set SPI-auto-locking timeout
Set timeout, after which SPI-communication-functions return AM_ERROR_BUSY if they cannot lock the SPI.
Usage: | void am_rpi_spi_locking_timeout(uint16_t timeout_ms) |
---|---|
Parameters: | timeout_ms: timeout in ms (default: 1000ms) |
5.4.5 configure SPI
Usage: | AM_ERROR am_rpi_spi_config(enum am_rpi_spi_mode mode, enum am_rpi_spi_clkcfg clkcfg, enum am_rpi_spi_cspol cspol0, enum am_rpi_spi_cspol cspol1) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT/AM_ERROR_NOT_IMPLEMENTED on error |
Note: |
|
5.4.6 read SPI-configuration
Usage: | void am_rpi_spi_config_read(enum am_rpi_spi_mode *mode, enum am_rpi_spi_clkcfg *clkcfg, enum am_rpi_spi_cspol *cspol0, enum am_rpi_spi_cspol *cspol1) |
---|---|
Parameters: |
|
Note: |
|
5.4.7 set SPI clock
Usage: | AM_ERROR am_rpi_spi_clk(enum am_rpi_spi_clk clkdiv) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on error |
Note: |
|
5.4.8 read SPI clock
Usage: | void am_rpi_spi_clk_read(enum am_rpi_spi_clk *clkdiv) |
---|---|
Parameters: |
|
Note: |
|
5.4.9 start/init SPI
Auto-lock SPI, clear FIFOs and enable SPI. Also reconfigure SPI if it was configured by another program.
Must be called before writing any data to SPI FIFOs.
Usage: | AM_ERROR am_rpi_spi_start(int cs) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT/AM_ERROR_BUSY on error |
5.4.10 stop/end SPI
Stop and auto-unlock SPI, and clear the SPI-buffers. Must be called after every SPI communication.
Usage: | void am_rpi_spi_stop(void) |
---|
5.4.11 write byte to SPI FIFO
Usage: | AM_ERROR am_rpi_spi_write_byte(char byte) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_BUFFER_FULL if the TX FIFO is full |
5.4.12 read byte from SPI FIFO
Usage: | AM_ERROR am_rpi_spi_read_byte(char *byte) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_BUFFER_EMPTY if the RX FIFO is empty |
Note: | SPI is symmetric, so for each written byte, one byte must be read. Otherwise the receive-buffer will run full and stop the SPI. Alternatively, the SPI-RX-buffer may be cleared. |
5.4.13 write byte to SPI FIFO (blocking) + return received byte (if any)
This is useful to send bytes very quickly.
Usage: | int am_rpi_spi_rw(char byte) |
---|---|
Parameters: |
|
Returns: | received byte, or AM_ERROR_BUFFER_EMPTY if the RX FIFO was empty |
5.4.14 wait until SPI is done
Also clear the SPI-RX-buffer.
Usage: | void am_rpi_spi_wait_done(void) |
---|
5.4.15 communicate over SPI
- auto-lock + start/init SPI
- write + read data
- wait until done
- stop + auto-unlock SPI
Usage: | AM_ERROR am_rpi_spi_comm(int cs, unsigned int len, char const *txdata, char *rxdata) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT/AM_ERROR_BUSY on error |
5.4.16 communicate over SPI: write some data N times
- auto-lock + start/init SPI
- write some data (prefix)
- write data several times
- write some more data (suffix)
- wait until done
- stop + auto-unlock SPI
Usage: | AM_ERROR am_rpi_spi_comm_writeN(int cs, unsigned int pre_len, char const* pre_data, unsigned int repeat, unsigned int len, char const *txdata, unsigned int suf_len, char const *suf_data) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT/AM_ERROR_BUSY on error |
5.4.17 communicate over SPI: write a data-window
- auto-lock and start/init SPI
- write data from a window
- wait until done
- stop and auto-unlock SPI
Usage: | AM_ERROR am_rpi_spi_write_window(int cs, uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t rowstride, char const *txdata, bool swap) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT/AM_ERROR_BUSY on error |
Note: | If swap=1, w must be even! |
5.4.18 SPI interface
SPI interface abstraction.
If a driver for an SPI-device should not be Raspberry Pi-dependent, better use this abstraction-layer instead of the functions above.
Usage: | AM_ERROR ret; AM_SPI_INTERFACE *my_spi; my_spi = am_rpi_spi; char txdata[...], rxdata[...]; ... ret = my_spi->comm(cs, len, txdata, rxdata); |
---|---|
SeeAlso: | documentation of am_rpi_spi_comm(), advamation.h |
5.5 I2C
Broadcom BCM2835 contains 3 "BSC"s (Broadcom Serial Controller), which are compatible to fast-mode (400 Kb/s) I2C v2.1:
- BSC0: on P1 on Rev. 1.0, on P5/CSI on Rev. 2.0
- BSC1: on P1 on Rev. 2.0, on SCI on Rev. 1.0
- BSC2: dedicated to HDMI and should not be used otherwise.
Currently, only the BSC on P1 is supported.
The BSC supports single-master-mode, and 7-/10-bit addressing, and has 16-byte-FIFOs.
This library supports concurrent access to the I2C from different programs, which use this library:
- Before every communication, the I2C is locked. If another program has currently locked the I2C, the functions wait until the I2C becomes unlocked or a timeout occurs.
- After successfully locking the I2C, the I2C is reconfigured.
- After communication, the I2C is unlocked again.
- It's also possible to manually lock the I2C, but this should be used with care, since it could prevent other programs from accessing I2C at all.
If you want to use I2C from different threads in a program, use e.g. a mutex to make sure only 1 thread accesses the I2C at the same time. If the threads use different I2C-speeds, make sure to reconfigure the I2C-clock after acquiring the mutex.
5.5.1 configure I2C-pins
Use GPIO_P1_3 as SDA, GPIO_P1_5 as SCL.
Usage: | void am_rpi_i2c_pins(void) |
---|
5.5.2 en-/disable I2C
I2C has to be enabled before any data can be written/read. But the I2C-registers can also be accessed when I2C is disabled.
Note that you should only disable the I2C if you are sure that no other application uses the I2C; otherwise, you will break other programs!
Usage: | void am_rpi_i2c_enable(bool enable) |
---|---|
Parameters: |
|
5.5.3 check if I2C is enabled
Usage: | bool am_rpi_i2c_enabled(void) |
---|---|
Returns: | 0 if disabled, 1 if enabled |
5.5.4 manually lock I2C
Wait until the I2C is unlocked and manually lock (and configure) the I2C.
Usually, it's not necessary to use this function, since am_rpi_i2c_read()/_write()/_write_read() (and its 10-bit-address variants) automatically lock and unlock the I2C. But the I2C may be locked manually, e.g. if several I2C-communications must directly follow each other, or to prevent other programs to access the I2C.
Note that you additionally have to use a mutex, if you're accessing the I2C from several threads in the same program.
Always use am_rpi_i2c_unlock() for every successful call to this function.
Usage: | AM_ERROR am_rpi_i2c_lock(int32_t timeout_ms) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_BUSY after timeout |
5.5.5 manually unlock I2C
Manually unlock the I2C.
This is usually only necessary after am_rpi_i2c_lock(); otherwise, locking and unlocking is automatically done by am_rpi_i2c_read()/_write()/write_read().
Usage: | void am_rpi_i2c_unlock(void) |
---|
5.5.6 set I2C-auto-locking timeout
Set timeout, after which I2C-communication-functions return AM_ERROR_BUSY if they cannot lock the I2C.
Usage: | void am_rpi_i2c_locking_timeout(uint16_t timeout_ms) |
---|---|
Parameters: | timeout_ms: timeout in ms (default: 1000ms) |
5.5.7 set I2C clock
Usage: | AM_ERROR am_rpi_i2c_clk(enum am_rpi_i2c_clk clkdiv) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on error |
Note: |
|
5.5.8 read I2C clock
Usage: | void am_rpi_i2c_clk_read(enum am_rpi_i2c_clk *clkdiv) |
---|---|
Parameters: |
|
Note: |
|
5.5.9 read byte from I2C-FIFO
(low-level function without locking)
Usage: | AM_ERROR am_rpi_i2c_read_byte(char *byte) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_BUFFER_EMPTY if RX FIFO is empty, AM_ERROR_COMM_FAILED on timeout/ACK error |
5.5.10 write byte to I2C-FIFO
(low-level function without locking)
Usage: | AM_ERROR am_rpi_i2c_write_byte(char byte) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_BUFFER_FULL if TX FIFO is full, AM_ERROR_COMM_FAILED on timeout/ACK error |
5.5.11 wait until I2C is done
(low-level function without locking)
Usage: | AM_ERROR am_rpi_i2c_wait_done(void) |
---|---|
Returns: | 0 on success, AM_ERROR_COMM_FAILED on timeout/ACK error |
5.5.12 read data from I2C
- auto-lock I2C and set I2C-speed
- reset errors/done, set address + length, clear FIFO
- start transfer
- read data
- wait until done
- auto-unlock I2C
Usage: | AM_ERROR am_rpi_i2c_read(uint8_t address, uint16_t rxlen, char *rxdata) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on invalid address, AM_ERROR_COMM_FAILED on timeout/ACK error, AM_ERROR_BUSY on locking-timeout |
5.5.13 write data to I2C
- auto-lock I2C and set I2C-speed
- reset errors/done, set address + length + FIFO
- start transfer
- write more data to FIFO
- wait until done
- auto-unlock I2C
Usage: | AM_ERROR am_rpi_i2c_write(uint8_t address, uint16_t txlen, char const *txdata) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on invalid address, AM_ERROR_COMM_FAILED on timeout/ACK error, AM_ERROR_BUSY on locking-timeout |
5.5.14 write data to I2C, then read data
- auto-lock I2C and set I2C-speed
- reset errors/done, set address + tx-length + FIFO
- start transfer
- write more data to FIFO
- wait until TX-FIFO is empty
- set rx-length
- repeated start + reset done
- read data
- wait until done
- auto-unlock I2C
Usage: | AM_ERROR am_rpi_i2c_write_read(uint8_t address, uint16_t txlen, char const *txdata, uint16_t rxlen, char *rxdata) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on invalid address, AM_ERROR_COMM_FAILED on timeout/ACK error, AM_ERROR_BUSY on locking-timeout |
5.5.15 read data from I2C with 10-bit slave-address
Like am_rpi_i2c_read(), but with 10-bit slave-address.
Usage: | AM_ERROR am_rpi_i2c_read10(uint16_t address, uint16_t rxlen, char *rxdata) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on invalid address, AM_ERROR_COMM_FAILED on timeout/ACK error, AM_ERROR_BUSY on locking-timeout |
5.5.16 write data to I2C with 10-bit slave-address
Like am_rpi_i2c_write(), but with 10-bit slave-address.
Usage: | AM_ERROR am_rpi_i2c_write10(uint16_t address, uint16_t txlen, char const *txdata) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on invalid address/len, AM_ERROR_COMM_FAILED on timeout/ACK error, AM_ERROR_BUSY on locking-timeout |
5.5.17 write data to I2C, then read data, 10-bit slave-address
Like am_rpi_i2c_write_read(), but with 10-bit slave-address.
Usage: | AM_ERROR am_rpi_i2c_write_read10(uint16_t address, uint16_t txlen, char const *txdata, uint16_t rxlen, char *rxdata) |
---|---|
Parameters: |
|
Returns: | 0 on success, AM_ERROR_INVALID_ARGUMENT on invalid address, AM_ERROR_COMM_FAILED on timeout/ACK error, AM_ERROR_BUSY on locking-timeout |
5.5.18 I2C interface
I2C interface abstraction.
If a driver for an I2C-device should not be Raspberry Pi-dependent, better use this abstraction-layer instead of the functions above.
Usage: | AM_ERROR ret; AM_I2C_INTERFACE *my_i2c; my_i2c = am_rpi_i2c; ret = my_i2c->read(...); ret = my_i2c->write(...); ret = my_i2c->write_read(...); ret = my_i2c->read10(...); ret = my_i2c->write10(...); ret = my_i2c->write_read10(...); |
---|---|
SeeAlso: | documentation of the above functions, advamation.h |
5.5.19 I2C-communication with Advamation RS-485-/I2C-protocol
Communicate with a I2C-device with the Advamation RS-485-/I2C-protocol, incl. CRC/PEC.
Usage: | AM_ERROR am_rpi_i2c_prot(uint8_t address, enum am_cmd cmd, unsigned int txlen, char const *txdata, unsigned int rxlen, unsigned int *received_len, char *rxdata) |
---|---|
Parameters: |
|
Returns: | 0 on success, <0 on error (AM_ERROR_INVALID_ARGUMENT on invalid address/txlen/rxlen, AM_ERROR_COMM_FAILED on timeout/ACK error, AM_ERROR_COMM_CRC on incorrect CRC, AM_ERROR_COMM_TOOSHORT if less then rxlen bytes received), AM_ERROR_BUSY on locking-timeout |
SeeAlso: | advamation.h, am_rpi_i2c_write_read() |
6 UI-functions
6.1 map enum GPIO_* to a string
Usage: | const char* am_rpi_gpio2str(enum am_rpi_gpio gpio) |
---|---|
Returns: | string or "unknown" |
6.2 map string to enum GPIO_*
Usage: | enum am_rpi_gpio am_rpi_str2gpio(char const *s) |
---|---|
Returns: | found enum or -1 |