busio – Hardware accelerated external bus access — Adafruit CircuitPython 1 documentation (original) (raw)

The busio module contains classes to support a variety of serial protocols.

When the microcontroller does not support the behavior in a hardware accelerated fashion it may internally use a bitbang routine. However, if hardware support is available on a subset of pins but not those provided, then a RuntimeError will be raised. Use the bitbangio module to explicitly bitbang a serial protocol on any general purpose pins.

All classes change hardware state and should be deinitialized when they are no longer needed if the program continues after use. To do so, either call deinit() or use a context manager. SeeLifetime and ContextManagers for more info.

For example:

import busio from board import *

i2c = busio.I2C(SCL, SDA) i2c.try_lock() print(i2c.scan()) i2c.unlock() i2c.deinit()

This example will initialize the the device, lock the I2C bus, runscan(), unlock the bus, and then deinit() the hardware. The last step is optional because CircuitPython automatically resets hardware after a program finishes.

Note that drivers will typically handle communication if provided the bus instance (such as busio.I2C(board.SCL, board.SDA)), and that many of the methods listed here are lower level functionalities that are needed for working with custom drivers.

Tutorial for I2C and SPI:https://learn.adafruit.com/circuitpython-basics-i2c-and-spi

Tutorial for UART:https://learn.adafruit.com/circuitpython-essentials/circuitpython-uart-serial

Available on these boards

class busio.I2C(scl: microcontroller.Pin, sda: microcontroller.Pin, *, frequency: int = 100000, timeout: int = 255)

Two wire serial protocol

I2C is a two-wire protocol for communicating between devices. At the physical level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.

See also

Using this class directly requires careful lock management. Instead, use I2CDevice to manage locks.

See also

Using this class to directly read registers requires manual bit unpacking. Instead, use an existing driver or make one withRegister data descriptors.

See also

This class provides an I2C controller, which controls I2C targets (peripherals). To act as an I2C target, use i2ctarget.I2CTarget.

Parameters:

deinit() → None

Releases control of the underlying hardware so other classes can use it.

__enter__() → I2C

No-op used in Context Managers.

__exit__() → None

Automatically deinitializes the hardware on context exit. SeeLifetime and ContextManagers for more info.

probe(address: int) → List[int]

Check if a device at the specified address responds.

Parameters:

address (int) – 7-bit device address

Returns:

True if a device at address responds; False otherwise

Return type:

bool

scan() → List[int]

Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of those that respond.

Returns:

List of device ids on the I2C bus

Return type:

list

try_lock() → bool

Attempts to grab the I2C lock. Returns True on success.

Returns:

True when lock has been grabbed

Return type:

bool

unlock() → None

Releases the I2C lock.

readfrom_into(address: int, buffer: circuitpython_typing.WriteableBuffer, *, start: int = 0, end: int = sys.maxsize) → None

Read into buffer from the device selected by address. At least one byte must be read.

If start or end is provided, then the buffer will be sliced as if buffer[start:end] were passed, but without copying the data. The number of bytes read will be the length of buffer[start:end].

Parameters:

writeto(address: int, buffer: circuitpython_typing.ReadableBuffer, *, start: int = 0, end: int = sys.maxsize) → None

Write the bytes from buffer to the device selected by address and then transmit a stop bit.

If start or end is provided, then the buffer will be sliced as if buffer[start:end] were passed, but without copying the data. The number of bytes written will be the length of buffer[start:end].

Writing a buffer or slice of length zero is permitted, as it can be used to poll for the existence of a device.

Parameters:

writeto_then_readfrom(address: int, out_buffer: circuitpython_typing.ReadableBuffer, in_buffer: circuitpython_typing.WriteableBuffer, *, out_start: int = 0, out_end: int = sys.maxsize, in_start: int = 0, in_end: int = sys.maxsize) → None

Write the bytes from out_buffer to the device selected by address, generate no stop bit, generate a repeated start and read into in_buffer. out_buffer andin_buffer can be the same buffer because they are used sequentially.

If out_start or out_end is provided, then the buffer will be sliced as if out_buffer[out_start:out_end] were passed, but without copying the data. The number of bytes written will be the length of out_buffer[start:end].

If in_start or in_end is provided, then the input buffer will be sliced as if in_buffer[in_start:in_end] were passed, The number of bytes read will be the length of out_buffer[in_start:in_end].

Parameters:

class busio.SPI(clock: microcontroller.Pin, MOSI: microcontroller.Pin | None = None, MISO: microcontroller.Pin | None = None, half_duplex: bool = False)

A 3-4 wire serial protocol

SPI is a serial protocol that has exclusive pins for data in and out of the main device. It is typically faster than I2C because a separate pin is used to select a device rather than a transmitted address. This class only manages three of the four SPI lines: clock,MOSI, MISO. It is up to the client to manage the appropriate select line, often abbreviated CS or SS. (This is common because multiple secondaries can share the clock, MOSI and MISO lines and therefore the hardware.)

Available on these boards

See also

This class acts as an SPI main (controller). To act as an SPI secondary (target), use spitarget.SPITarget.

Construct an SPI object on the given pins.

Note

The SPI peripherals allocated in order of desirability, if possible, such as highest speed and not shared use first. For instance, on the nRF52840, there is a single 32MHz SPI peripheral, and multiple 8MHz peripherals, some of which may also be used for I2C. The 32MHz SPI peripheral is returned first, then the exclusive 8MHz SPI peripheral, and finally the shared 8MHz peripherals.

See also

Using this class directly requires careful lock management. Instead, use SPIDevice to manage locks.

See also

Using this class to directly read registers requires manual bit unpacking. Instead, use an existing driver or make one withRegister data descriptors.

Parameters:

Limitations: half_duplex is available only on STM; other chips do not have the hardware support.

deinit() → None

Turn off the SPI bus.

__enter__() → SPI

No-op used by Context Managers. Provided by context manager helper.

__exit__() → None

Automatically deinitializes the hardware when exiting a context. SeeLifetime and ContextManagers for more info.

configure(*, baudrate: int = 100000, polarity: int = 0, phase: int = 0, bits: int = 8) → None

Configures the SPI bus. The SPI object must be locked.

Parameters:

Note

On the SAMD21, it is possible to set the baudrate to 24 MHz, but that speed is not guaranteed to work. 12 MHz is the next available lower speed, and is within spec for the SAMD21.

Note

On the nRF52840, these baudrates are available: 125kHz, 250kHz, 1MHz, 2MHz, 4MHz, and 8MHz. If you pick a a baudrate other than one of these, the nearest lower baudrate will be chosen, with a minimum of 125kHz. Two SPI objects may be created, except on the Circuit Playground Bluefruit, which allows only one (to allow for an additional I2C object).

try_lock() → bool

Attempts to grab the SPI lock. Returns True on success.

Returns:

True when lock has been grabbed

Return type:

bool

unlock() → None

Releases the SPI lock.

write(buffer: circuitpython_typing.ReadableBuffer, *, start: int = 0, end: int = sys.maxsize) → None

Write the data contained in buffer. The SPI object must be locked. If the buffer is empty, nothing happens.

If start or end is provided, then the buffer will be sliced as if buffer[start:end] were passed, but without copying the data. The number of bytes written will be the length of buffer[start:end].

Parameters:

readinto(buffer: circuitpython_typing.WriteableBuffer, *, start: int = 0, end: int = sys.maxsize, write_value: int = 0) → None

Read into buffer while writing write_value for each byte read. The SPI object must be locked. If the number of bytes to read is 0, nothing happens.

If start or end is provided, then the buffer will be sliced as if buffer[start:end] were passed. The number of bytes read will be the length of buffer[start:end].

Parameters:

write_readinto(out_buffer: circuitpython_typing.ReadableBuffer, in_buffer: circuitpython_typing.WriteableBuffer, *, out_start: int = 0, out_end: int = sys.maxsize, in_start: int = 0, in_end: int = sys.maxsize) → None

Write out the data in out_buffer while simultaneously reading data into in_buffer. The SPI object must be locked.

If out_start or out_end is provided, then the buffer will be sliced as if out_buffer[out_start:out_end] were passed, but without copying the data. The number of bytes written will be the length of out_buffer[out_start:out_end].

If in_start or in_end is provided, then the input buffer will be sliced as if in_buffer[in_start:in_end] were passed, The number of bytes read will be the length of out_buffer[in_start:in_end].

The lengths of the slices defined by out_buffer[out_start:out_end]and in_buffer[in_start:in_end] must be equal. If buffer slice lengths are both 0, nothing happens.

Parameters:

frequency_: int_

The actual SPI bus frequency. This may not match the frequency requested due to internal limitations.

class busio.UART(tx: microcontroller.Pin | None = None, rx: microcontroller.Pin | None = None, *, rts: microcontroller.Pin | None = None, cts: microcontroller.Pin | None = None, rs485_dir: microcontroller.Pin | None = None, rs485_invert: bool = False, baudrate: int = 9600, bits: int = 8, parity: Parity | None = None, stop: int = 1, timeout: float = 1, receiver_buffer_size: int = 64)

A bidirectional serial protocol

Available on these boards

A common bidirectional serial protocol that uses an an agreed upon speed rather than a shared clock line.

Parameters:

tx and rx cannot both be None.

New in CircuitPython 4.0: timeout has incompatibly changed units from milliseconds to seconds. The new upper limit on timeout is meant to catch mistaken use of milliseconds.

Limitations: RS485 is not supported on SAMD, Nordic, Broadcom, Spresense, or STM. On i.MX and Raspberry Pi RP2040, RS485 support is implemented in software: The timing for the rs485_dir pin signal is done on a best-effort basis, and may not meet RS485 specifications intermittently.

deinit() → None

Deinitialises the UART and releases any hardware resources for reuse.

__enter__() → UART

No-op used by Context Managers.

__exit__() → None

Automatically deinitializes the hardware when exiting a context. SeeLifetime and ContextManagers for more info.

read(nbytes: int | None = None) → bytes | None

Read bytes. If nbytes is specified then read at most that many bytes. Otherwise, read everything that arrives until the connection times out. Providing the number of bytes expected is highly recommended because it will be faster. If no bytes are read, return None.

Note

When no bytes are read due to a timeout, this function returns None. This matches the behavior of io.RawIOBase.read in Python 3, but differs from pyserial which returns b'' in that situation.

Returns:

Data read

Return type:

bytes or None

readinto(buf: circuitpython_typing.WriteableBuffer) → int | None

Read bytes into the buf. Read at most len(buf) bytes.

Returns:

number of bytes read and stored into buf

Return type:

int or None (on a non-blocking error)

New in CircuitPython 4.0: No length parameter is permitted.

readline() → bytes

Read a line, ending in a newline character, or return None if a timeout occurs sooner, or return everything readable if no newline is found andtimeout=0

Returns:

the line read

Return type:

bytes or None

write(buf: circuitpython_typing.ReadableBuffer) → int | None

Write the buffer of bytes to the bus.

New in CircuitPython 4.0: buf must be bytes, not a string.

return:

the number of bytes written

rtype:

int or None

baudrate_: int_

The current baudrate.

in_waiting_: int_

The number of bytes in the input buffer, available to be read

timeout_: float_

The current timeout, in seconds (float).

reset_input_buffer() → None

Discard any unread characters in the input buffer.

class busio.Parity

Enum-like class to define the parity used to verify correct data transfer.

ODD_: int_

Total number of ones should be odd.

EVEN_: int_

Total number of ones should be even.