Library for Raspberry Pi - Python binding

Version: 2014-06-26
Status: experimental
Requires:Python >=2.6 / 3.x, ctypes Advamation Raspberry Pi-Library
SeeAlso:rpi_h, am_rpi.c/am_rpi.h
Author: Advamation, Roland Koebler (support@advamation.de)
Copyright: (c) Advamation (info@advamation.de)
License:open-source / MIT
RCS:rpi.py,v 1.25 2014/06/26 13:00:37 rk Exp

Lightweight wrapper around the Advamation Raspberry Pi C-Library.


Table of contents


1   generic usage

Before using the library, the Python module has to be imported, e.g.:

from am_rpi import rpi
from am_rpi.advamation import AM_ERROR, AM_ERROR_CODE

# optionally:
from am_rpi.rpi import GPIO, GPIO_MODE, GPIO_PULLUPDOWN, SPI_MODE, SPI_CLKCFG, SPI_CSPOL, SPI_CLK, I2C_CLK
from am_rpi.advamation import AM_CMD, AM_LOG_LEVEL
from am_rpi import advamation

The functions usually throw AM_ERROR on error, so always catch it, e.g.:

try:
    rpi.init()
except AM_ERROR as err:
    print("Error: Raspberry Pi-init failed. (%s / %d)" % (err.message, err.code))
    sys.exit(1)

try:
    info = rpi.info()
    ...
except AM_ERROR as err:
    print("Exception: %s (%d)" % (err.message, err.code))
    sys.exit(1)

rpi.exit()

In addition, they throw LibraryNotInitialized if some functions are called before initializing the library, and e.g. TypeError for invalid parameters.

Many functions return several bytes as a bytestring.

  • In Python 3, these bytestrings can be accesses somehow like a list of integers (i.e. if you access a bytestring-element (e.g. s[0]), you'll get the integer-value of the byte).
  • In Python 2, accessing a bytestring-element gives you a 1-character-string. To get the integer-value, you have to use ord() for every element, or use the function advamation.bytes2list().

2   init / exit / logging

2.1   Initialize 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.

init() and exit() should always be called pairwise.

Usage:init()
Raises:AM_ERROR

2.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:exit()

2.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:

logging(level=AM_LOG_LEVEL.WARNING, logfile=None, logfile_level=AM_LOG_LEVEL.WARNING)

Parameters:
  • level: log-level for "print"
  • logfile_level: log-level for the logfile
  • logfile: filename of the logfile (None: no logfile)
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT, IO if the logfile cannot be opened (see errno for details))

SeeAlso:

advamation.AM_LOG_LEVEL

3   system information

Note:These functions work even without initializing the library!

3.1   Hardware information.

Check if this is a Raspberry Pi and get its hardware information from /proc/cpuinfo.

Usage:

info()

Returns:

{"model": "...", "rev": "...", "manufacturer": "...", "rev_raw": ..., "serial": ...}

  • model: Raspberry Pi model
  • rev: Raspberry Pi revision
  • manufacturer: Raspberry Pi manufacturer
  • rev_raw: Raspberry Pi raw revision number
  • serial: Raspberry Pi serial-number
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: DEVICE_NOT_SUPPORTED if this is no Raspberry Pi, MEMORY, IO, PERMISSIONS)

Uses:

/proc/cpuinfo

Note:

The following values currently exist:

model

"A" "B" "UNKNOWN"

rev

"1.0" "1.0+ECN0001/Fuses mod, D14 removed" "2.0 256MB" "2.0 512MB" "UNKNOWN"

manufacturer

"Sony" "Egoman" "Quisda" "UNKNOWN"

3.2   Get Raspberry Pi revision-number.

This reads an internal variable (and is fast after init()), and uses info() of the C-library otherwise.

Usage:info_rev()
Returns:raw revision number
Raises:AM_ERROR on error

3.3   CPU-clock speed information.

Usage:

info_clk()

Returns:

{"clk": ..., "clk_min": ..., "clk_max": ...}

  • clk: current clock in MHz
  • clk_min: min. clock in MHz
  • clk_max: max. clock in MHz
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: DEVICE_UNEXPECTED, MEMORY, PERMISSIONS, IO)

Uses:

/sys/devices/system/cpu/cpu0/cpufreq/

3.4   Memory size and usage information.

Usage:

info_memory()

Returns:

{"mem": ..., "used": ..., "free": ..., "free_buffers_cache": ...}

  • mem: total memory in kB
  • used: used memory in kB without buffers/cache
  • free: free memory in kB
  • free_buffers_cache: free+buffer+cache memory in kB
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: DEVICE_UNEXPECTED, MEMORY, PERMISSIONS, IO)

Note:

The returned total memory is usually less then the physical memory on the board, since the memory is shared between CPU and GPU.

Uses:

/proc/meminfo

3.5   Temperature information.

Usage:info_temperature()
Returns:CPU-temperature in °C
Raises:LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: DEVICE_UNEXPECTED, MEMORY, PERMISSIONS, IO)

3.6   SD-card-information.

Usage:

info_sd()

Returns:
{"CID": ..., "CSD": ..., "SCR": ..., "SIZE": ...,
 "manfid": number,
 "oemid":  'XX',
 "name":   'XXXXX',
 "rev":    'x.x',
 "serial": number,
 "date":   'MM/YYYY'
}
Raises:

AM_ERROR

3.7   Filesystem-statistics.

Convenience-function e.g. for RPC.

Usage:info_statvfs()
Returns:(bsize, frsize, blocks, bfree, bavail, files, ffree, favail, fsid, flag, namemax) of the root-fs.
SeeAlso:statvfs, os.statvfs

3.8   Operating-system information.

Convenience-function e.g. for RPC.

Usage:

info_os()

Returns:
{"name": os_name, "id": os_id, "version": os_version, "version_id": os_version_id,
 "kernel_release": ...,
 "hostname": ...}
Raises:

AM_ERROR if /etc/os-release is not available or uname does not work

SeeAlso:

/etc/os-release, os.uname

4   miscellaneous functions

Note:These functions work even without initializing the library!

4.1   Wait some µs.

Wait (at least) a specified amount of microseconds in a busy-loop.

Usage:

delay_us(us)

Parameters:
  • us: microseconds to wait (0..65535)

5   system timer

Continuously running 64-bit, 1 MHz system timer.

5.1   Read the system timer.

Usage:timer()
Returns:64-bit timer value
Raises:LibraryNotInitialized

5.2   Read the lower-half of the system timer.

Usage:timer_lo()
Returns:32-bit timer value
Raises:LibraryNotInitialized

6   I/O

Note:
  • Parameter gpios is a 32-bit-mask, containing 1 bit for every GPIO. Multiple GPIO-values can be combined, e.g.: GPIO.P1_7, GPIO.P1_7|GPIO.P1_10, GPIO.P1_26+GPIO.P1_7+GPIO.P1_22, GPIO.ALL.

6.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:
  • Better use GPIO.P1_# instead of GPIO.GPIO_#.
  • 6 GPIOs were switched between Rev. 1.0 and Rev. 2.0 (GPIO_0/GPIO_2, GPIO_1/GPIO_3, GPIO_21/GPIO_27). This library transparently switches the GPIOs, so that all look like Rev. 2.0. But better always use GPIO.P1_# instead of GPIO.GPIO_#.
  • 4 GPIOs were added on Rev. 2.0 (P5); they are ignored in Rev. 1.0.
  • GPIO.P1_8 + GPIO.P1_10 are used by the Linux serial console by default. To use them as GPIO, you have to disable the serial console and reboot.
  • For pull-up/pull-down-state on power-down, see gpio_pullupdown().

6.2   I/O configuration

6.2.1   Configure I/O pins.

Usage:

gpio_config(gpios, mode)

Parameters:
  • gpios: GPIOs to configure
  • mode: GPIO_MODE.INPUT / GPIO_MODE.OUTPUT / GPIO_MODE.ALT0..5
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT)

SeeAlso:

GPIO.*, GPIO_MODE.*

6.2.2   Read I/O pin configuration.

Usage:

gpio_config_read(gpio)

Parameters:
  • gpio: single GPIO
Returns:

GPIO_MODE.INPUT / GPIO_MODE.OUTPUT / GPIO_MODE.ALT0..5

Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT)

SeeAlso:

GPIO.*, GPIO_MODE.*

6.2.3   Configure GPIO-pin pull-up/pull-down.

Usage:

gpio_pullupdown(gpios, pullupdown)

Parameters:
  • gpios: GPIOs to configure
  • pullupdown: GPIO_PULLUPDOWN.DISABLE / GPIO_PULLUPDOWN.PULL_DOWN / GPIO_PULLUPDOWN.PULL_UP
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT)

Note:

On power-down, the following pull-ups/-downs are active:

  • pull-up: GPIO 0-8 / P1_3/5/7/24/26, CSI_12/13/14
  • pull-down: GPIO 9-27, 30-31 / P1_8/10/11/12/13/15/16/18/19/21/22/23, P5_5/6, CSI_11
  • none: GPIO 28, 29 / P5_3/4
SeeAlso:

GPIO.*, GPIO_PULLUPDOWN.*

6.3   GPIO

6.3.1   Read GPIO(s).

Usage:

gpio_read(gpios=0xffffffff)

Parameters:
  • gpios: GPIOs to read, 0xffffffff for all
Returns:

read input levels, masked by gpios

Raises:

LibraryNotInitialized

SeeAlso:

GPIO.*

6.3.2   Write GPIO output level.

Usage:

gpio_write(gpios, level)

Parameters:
  • gpios: GPIOs to write
  • level: 0/False to clear, 1/True to set
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT)

SeeAlso:

GPIO.*

6.3.3   Set GPIO(s).

Usage:

gpio_set(gpios)

Parameters:
  • gpios: GPIOs to set
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT)

SeeAlso:

GPIO.*

6.3.4   Clear GPIO(s).

Usage:

gpio_clr(gpios)

Parameters:
  • gpios: GPIOs to clear
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT)

SeeAlso:

GPIO.*

6.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:
  • SPI is msb-first
  • TX- and RX-FIFO are 64 bytes.

6.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:

spi_pins(cs0=False, cs1=False)

Parameters:
  • CS0: use GPIO.P1_24 as CS0 / SPI0_CE0_N?
  • CS1: use GPIO.P1_26 as CS1 / SPI0_CE1_N?
Raises:

LibraryNotInitialized

6.4.2   Manually lock the SPI.

Wait until the SPI is unlocked and manually lock (and configure) the SPI.

Usually, it's not necessary to use this function, since 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 spi_unlock() for every successful call to this function.

Usage:

spi_lock(timeout_ms=-1)

Parameters:
  • timeout_ms: timeout in ms (0..65535), 0=non-blocking, -1/omitted=use auto-locking timeout
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: BUSY after timeout)

6.4.3   Manually unlock the SPI.

This is usually only necessary after spi_lock(); otherwise, locking and unlocking is automatically done by spi_start()/_stop().

Usage:spi_unlock()
Raises:LibraryNotInitialized

6.4.4   Set SPI-auto-locking timeout.

Set timeout, after which SPI-communication-functions raise AM_ERROR(AM_ERROR_CODE.BUSY) if they cannot lock the SPI.

Usage:spi_locking_timeout(timeout_ms)
Parameters:timeout_ms: timeout in ms (0..65535, default: 1000ms)
Raises:LibraryNotInitialized

6.4.5   Configure SPI.

Usage:

spi_config(mode=-1, clkcfg=-1, cspol0=-1, cspol1=-1)

Parameters:
  • mode: SPI mode (SPI_MODE.*)
  • clkcfg: SPI clock polarity and clock phase (SPI_CLKCFG.*)
  • cspol0/1: SPI chip-select polarity (SPI_CSPOL.*)
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT, NOT_IMPLEMENTED)

Note:
  • If a parameter is -1/omitted, the appr. configuration is not changed.
  • If the SPI is currently not locked by this program, configuring the SPI is delayed until the next lock.
SeeAlso:

SPI_MODE.*, SPI_CLKCFG.*, SPI_CSPOL.*

6.4.6   Read SPI-configuration.

Usage:

spi_config_read()

Returns:

{"mode": ..., "clkcfg": ..., "cspol0": ..., "cspol1": ...}

  • mode: SPI mode
  • clkcfg: SPI clock polarity and clock phase
  • cspol0/1: SPI chip-select polarity
Raises:

LibraryNotInitialized

Note:

This returns the current configuration, which may differ from the values set by spi_config() if the SPI is not locked.

SeeAlso:

SPI_MODE.*, SPI_CLKCFG.*, SPI_CSPOL.*

6.4.7   Set SPI clock.

Usage:

spi_clk(clkdiv)

Parameters:
  • clkdiv: clock divisor (SPI_CLK.* or 4/6/8/10/.../65536)
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT)

Note:
  • SPI-speed is 250 MHz / clkdiv
  • If the SPI is currently not locked by this program, setting the SPI-clock is delayed until the next lock.
SeeAlso:

SPI_CLK.*

6.4.8   Read SPI clock.

Usage:spi_clk_read()
Returns:clock divisor
Raises:LibraryNotInitialized
Note:This returns the current clock, which may differ from the value set by spi_clk() if the SPI is not locked.
SeeAlso:SPI_CLK.*

6.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:

spi_start(cs=-1)

Parameters:
  • cs: chip-select to use (0 for CS0, 1 for CS1 or -1 for none)
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT)

6.4.10   Stop/end SPI.

Stop and auto-unlock SPI, and clear the SPI-buffers. Must be called after every SPI communication.

Usage:spi_stop()
Raises:LibraryNotInitialized

6.4.11   Write byte to SPI FIFO.

Usage:

spi_write_byte(byte)

Parameters:
  • byte: byte to send (int 0..0xFF / bytestring)
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: BUFFER_FULL if the TX FIFO is full)

6.4.12   Read byte from SPI FIFO.

Usage:spi_read_byte()
Returns:received byte (0..0xFF)
Raises:LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: 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.

6.4.13   Write byte to SPI FIFO (blocking) + return received byte (if any).

This is useful to send bytes very quickly.

Usage:

spi_rw(byte)

Parameters:
  • byte: byte to send (int 0..0xFF / bytestring)
Returns:

received byte (0..0xFF)

Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: BUFFER_EMPTY if the RX FIFO was empty)

6.4.14   Wait until SPI is done.

Also clear the SPI-RX-buffer.

Usage:spi_wait_done()
Raises:LibraryNotInitialized

6.4.15   Communicate over SPI.

  • auto-lock + start/init SPI
  • write + read data
  • wait until done
  • stop + auto-unlock SPI
Usage:

spi_comm(cs=-1, txdata=b"")

Parameters:
  • cs: chip-select to use (0/1 or -1 for none)
  • txdata: transmit-data (bytestring or list of 0..0xFF)
Returns:

received data (bytestring)

Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT)

6.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:

spi_comm_writeN(cs=-1, prefix=b"", repeat=1, txdata=b"", suffix=b"")

Parameters:
  • cs: chip-select to use (0/1 or -1 for none)
  • prefix: prefix-data (bytestring or list of 0..0xFF)
  • repeat: number of repeats
  • txdata: data to send repeatedly (bytestring or list of 0..0xFF)
  • suffix: suffix-data (bytestring or list of 0..0xFF)
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT, BUSY)

6.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:

spi_write_window(cs=-1, x0=0, y0=0, w=-1, h=-1, rowstride=-1, txdata=b"", swap=False)

Parameters:
  • cs: chip-select to use (0/1 or -1 for none)
  • x0/y0: start of the data-window (0..65535)
  • w: width of the data-window (0..65535)
  • h: height of the data-window (0..65535)
  • rowstride: length of a data-row (0..65535)
  • txdata: transmit-data (bytestring or list of 0..0xFF)
  • swap: False/0=no swap, True/1=swap bytes 2-byte-wise
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT, BUSY)

Note:

If swap is True, w must be even!

6.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.

6.5.1   Configure I2C-pins.

Use GPIO.P1_3 as SDA, GPIO.P1_5 as SCL.

Usage:i2c_pins()
Raises:LibraryNotInitialized

6.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:

i2c_enable(enable=True)

Parameters:
  • enable: False=disable I2C, True=enable I2C
Raises:

LibraryNotInitialized

6.5.3   Check if I2C is enabled.

Usage:i2c_enabled()
Returns:False if disabled, True if enabled
Raises:LibraryNotInitialized

6.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 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 i2c_unlock() for every successful call to this function.

Usage:

i2c_lock(timeout_ms=-1)

Parameters:
  • timeout_ms: timeout in ms (0..65535), 0=non-blocking, -1/omitted=use auto-locking timeout
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: BUSY after timeout)

6.5.5   Manually unlock I2C.

This is usually only necessary after i2c_lock(); otherwise, locking and unlocking is automatically done by i2c_read()/_write()/write_read().

Usage:i2c_unlock()
Raises:LibraryNotInitialized

6.5.6   Set I2C-auto-locking timeout.

Set timeout, after which I2C-communication-functions raise AM_ERROR(AM_ERROR_CODE.BUSY) if they cannot lock the I2C.

Usage:i2c_locking_timeout(timeout_ms)
Parameters:timeout_ms: timeout in ms (0..65535, default: 1000ms)
Raises:LibraryNotInitialized

6.5.7   Set I2C clock.

Usage:

i2c_clk(clkdiv)

Parameters:
  • clkdiv: clock divisor (I2C_CLK.CLK...kHz or 4/6/8/.../65536)
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT)

Note:
  • The I2C core clock is 250 MHz; default-clkdiv is 1500 (166.7kHz). (The Raspberry Pi datasheet is wrong, here.)
  • If the I2C is currently not locked by this program, setting the I2C-clock is delayed until the next lock.
SeeAlso:

I2C_CLK.*

6.5.8   Read I2C clock.

Usage:i2c_clk_read()
Returns:clock divisor
Note:This returns the current configuration, which may differ from the values set by i2c_clk() if the I2C is not locked.

6.5.9   Read byte from I2C-FIFO.

(low-level function without locking)

Usage:i2c_read_byte()
Retunrs:received byte (0..0xFF)
Raises:LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: BUFFER_EMPTY if RX FIFO is empty, COMM_FAILED on timeout/ACK error)

6.5.10   Write byte to I2C-FIFO.

(low-level function without locking)

Usage:

i2c_write_byte(byte)

Parameters:
  • byte: byte to send (int 0..0xFF / bytestring)
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: BUFFER_FULL if TX FIFO is full, COMM_FAILED on timeout/ACK error)

6.5.11   Wait until I2C is done.

Usage:i2c_wait_done()
Raises:LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: COMM_FAILED on timeout/ACK error)

6.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:

i2c_read(address, rxlen)

Parameters:
  • address: 7-bit I2C-slave address
  • rxlen: number of bytes to read (max. 65535)
Returns:

received data (bytestring)

Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT on invalid address, COMM_FAILED on timeout/ACK error)

6.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:

i2c_write(address, txdata)

Parameters:
  • address: 7-bit I2C-slave address
  • txdata: transmit-data (bytestring or list of 0..0xFF, max. 65535 bytes)
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT on invalid address, COMM_FAILED on timeout/ACK error)

6.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:

i2c_write_read(address, txdata, rxlen)

Parameters:
  • address: 7-bit I2C-slave address
  • txdata: transmit-data (bytestring or list of 0..0xFF, max. 65535 bytes)
  • rxlen: number of bytes to read (max. 65535)
Returns:

received data (bytestring)

Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT on invalid address, COMM_FAILED on timeout/ACK error)

6.5.15   Read data from I2C with 10-bit slave-address.

Like i2c_read(), but with 10-bit slave-address.

Usage:

i2c_read10(address, rxlen)

Parameters:
  • address: 10-bit I2C-slave address
  • rxlen: number of bytes to read (max. 65535)
Returns:

received data (bytestring)

Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT on invalid address, COMM_FAILED on timeout/ACK error)

6.5.16   Write data to I2C with 10-bit slave-address.

Like i2c_write(), but with 10-bit slave-address.

Usage:

i2c_write10(address, txdata)

Parameters:
  • address: 10-bit I2C-slave address
  • txdata: transmit-data (bytestring or list of 0..0xFF, max. 65534 bytes)
Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT on invalid address, COMM_FAILED on timeout/ACK error)

6.5.17   Write data to I2C, then read data, 10-bit slave-address.

Like i2c_write_read(), but with 10-bit slave-address.

Usage:

i2c_write_read10(address, txdata, rxlen)

Parameters:
  • address: 10-bit I2C-slave address
  • txdata: transmit-data (bytestring or list of 0..0xFF, max. 65534 bytes)
  • rxlen: number of bytes to read (max. 65535)
Returns:

received data (bytestring)

Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT on invalid address, COMM_FAILED on timeout/ACK error)

6.5.18   I2C-communication with Advamation RS-485-/I2C-protocol.

Communicate with a I2C-device with the Advamation RS-485-/I2C-protocol, incl. CRC/PEC.

Usage:

i2c_prot(address, cmd, txdata=None)

Parameters:
  • address: 7-bit I2C-slave address
  • cmd: I2C-protocol-command (AM_CMD.*)
  • txdata: transmit-data-bytes (bytestring or list of 0..0xFF, 0..16 bytes)
Returns:

received data (bytestring)

Raises:

LibraryNotInitialized, AM_ERROR (AM_ERROR_CODE: INVALID_ARGUMENT on invalid address/txlen, COMM_FAILED on timeout/ACK error, COMM_CRC on incorrect CRC, BUSY on locking-timeout)

SeeAlso:

advamation.AM_CMD, i2c_write_read()

7   UI-functions

7.1   Map enum GPIO.* to a string.

Usage:gpio2str(gpio)
Returns:string or "unknown"

7.2   Map string to enum GPIO.*.

Usage:str2gpio(s)
Returns:found GPIO enum or -1