2 `busio` - Bus protocol support like I2C and SPI
3 =================================================
5 See `CircuitPython:busio` in CircuitPython for more details.
15 import adafruit_platformdetect.constants.boards as ap_board
16 import adafruit_platformdetect.constants.chips as ap_chip
17 from adafruit_blinka import Enum, Lockable, agnostic
18 from adafruit_blinka.agnostic import board_id, detector
20 # pylint: disable=import-outside-toplevel,too-many-branches,too-many-statements
21 # pylint: disable=too-many-arguments,too-many-function-args
26 Busio I2C Class for CircuitPython Compatibility. Used
27 for both MicroPython and Linux.
30 def __init__(self, scl, sda, frequency=100000):
31 self.init(scl, sda, frequency)
33 def init(self, scl, sda, frequency):
36 if detector.board.ftdi_ft232h:
37 from adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.i2c import I2C as _I2C
39 self._i2c = _I2C(frequency=frequency)
41 if detector.board.binho_nova:
42 from adafruit_blinka.microcontroller.nova.i2c import I2C as _I2C
44 self._i2c = _I2C(frequency=frequency)
46 if detector.board.microchip_mcp2221:
47 from adafruit_blinka.microcontroller.mcp2221.i2c import I2C as _I2C
49 self._i2c = _I2C(frequency=frequency)
51 if detector.board.greatfet_one:
52 from adafruit_blinka.microcontroller.nxp_lpc4330.i2c import I2C as _I2C
54 self._i2c = _I2C(frequency=frequency)
56 if detector.board.any_embedded_linux:
57 from adafruit_blinka.microcontroller.generic_linux.i2c import I2C as _I2C
58 elif detector.board.ftdi_ft2232h:
59 from adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.i2c import I2C as _I2C
61 from machine import I2C as _I2C
62 from microcontroller.pin import i2cPorts
64 for portId, portScl, portSda in i2cPorts:
66 if scl == portScl and sda == portSda:
67 self._i2c = _I2C(portId, mode=_I2C.MASTER, baudrate=frequency)
73 "No Hardware I2C on (scl,sda)={}\nValid I2C ports: {}".format(
77 if threading is not None:
78 self._lock = threading.RLock()
81 """Deinitialization"""
84 except AttributeError:
88 if threading is not None:
92 def __exit__(self, exc_type, exc_value, traceback):
93 if threading is not None:
98 """Scan for attached devices"""
99 return self._i2c.scan()
101 def readfrom_into(self, address, buffer, *, start=0, end=None):
102 """Read from a device at specified address into a buffer"""
103 if start != 0 or end is not None:
106 buffer = memoryview(buffer)[start:end]
107 stop = True # remove for efficiency later
108 return self._i2c.readfrom_into(address, buffer, stop=stop)
110 def writeto(self, address, buffer, *, start=0, end=None, stop=True):
111 """Write to a device at specified address from a buffer"""
112 if isinstance(buffer, str):
113 buffer = bytes([ord(x) for x in buffer])
114 if start != 0 or end is not None:
116 return self._i2c.writeto(address, memoryview(buffer)[start:], stop=stop)
117 return self._i2c.writeto(address, memoryview(buffer)[start:end], stop=stop)
118 return self._i2c.writeto(address, buffer, stop=stop)
120 def writeto_then_readfrom(
132 """ "Write to a device at specified address from a buffer then read
133 from a device at specified address into a buffer
135 return self._i2c.writeto_then_readfrom(
149 Busio SPI Class for CircuitPython Compatibility. Used
150 for both MicroPython and Linux.
153 def __init__(self, clock, MOSI=None, MISO=None):
155 if detector.board.ftdi_ft232h:
156 from adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.spi import SPI as _SPI
157 from adafruit_blinka.microcontroller.ftdi_mpsse.ft232h.pin import (
164 self._pins = (SCK, MOSI, MISO)
166 if detector.board.binho_nova:
167 from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
168 from adafruit_blinka.microcontroller.nova.pin import SCK, MOSI, MISO
170 self._spi = _SPI(clock)
171 self._pins = (SCK, MOSI, MISO)
173 if detector.board.greatfet_one:
174 from adafruit_blinka.microcontroller.nxp_lpc4330.spi import SPI as _SPI
175 from adafruit_blinka.microcontroller.nxp_lpc4330.pin import SCK, MOSI, MISO
178 self._pins = (SCK, MOSI, MISO)
180 if detector.board.any_embedded_linux:
181 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
182 elif detector.board.ftdi_ft2232h:
183 from adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.spi import SPI as _SPI
185 from machine import SPI as _SPI
186 from microcontroller.pin import spiPorts
188 for portId, portSck, portMosi, portMiso in spiPorts:
191 and MOSI in (portMosi, None) # Clock is required!
192 and MISO in (portMiso, None) # But can do with just output
194 self._spi = _SPI(portId)
195 self._pins = (portSck, portMosi, portMiso)
199 "No Hardware SPI on (SCLK, MOSI, MISO)={}\nValid SPI ports:{}".format(
200 (clock, MOSI, MISO), spiPorts
204 def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
205 """Update the configuration"""
206 if detector.board.any_raspberry_pi or detector.board.any_raspberry_pi_40_pin:
207 from adafruit_blinka.microcontroller.bcm283x.pin import Pin
208 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
209 elif detector.board.BEAGLEBONE_AI:
210 from adafruit_blinka.microcontroller.dra74x.pin import Pin
211 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
212 elif detector.board.any_beaglebone:
213 from adafruit_blinka.microcontroller.am335x.pin import Pin
214 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
215 elif detector.board.any_orange_pi:
216 if detector.chip.id == ap_chip.SUN8I:
217 from adafruit_blinka.microcontroller.allwinner.h3.pin import Pin
218 elif detector.chip.id == ap_chip.H5:
219 from adafruit_blinka.microcontroller.allwinner.h5.pin import Pin
220 elif detector.chip.id == ap_chip.H616:
221 from adafruit_blinka.microcontroller.allwinner.h616.pin import Pin
222 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
223 elif detector.board.any_nanopi and detector.chip.id == ap_chip.SUN8I:
224 from adafruit_blinka.microcontroller.allwinner.h3.pin import Pin
225 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
226 elif board_id == ap_board.GIANT_BOARD:
227 from adafruit_blinka.microcontroller.sama5.pin import Pin
228 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
229 elif board_id == ap_board.CORAL_EDGE_TPU_DEV:
230 from adafruit_blinka.microcontroller.nxp_imx8m.pin import Pin
231 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
232 elif board_id == ap_board.CORAL_EDGE_TPU_DEV_MINI:
233 from adafruit_blinka.microcontroller.mt8167.pin import Pin
234 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
235 elif board_id == ap_board.ODROID_C2:
236 from adafruit_blinka.microcontroller.amlogic.s905.pin import Pin
237 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
238 elif board_id == ap_board.ODROID_C4:
239 from adafruit_blinka.microcontroller.amlogic.s905x3.pin import Pin
240 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
241 elif board_id == ap_board.ODROID_XU4:
242 from adafruit_blinka.microcontroller.samsung.exynos5422.pin import Pin
243 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
244 elif board_id == ap_board.DRAGONBOARD_410C:
245 from adafruit_blinka.microcontroller.snapdragon.apq8016.pin import Pin
246 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
247 elif board_id == ap_board.JETSON_NANO:
248 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
249 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
250 elif board_id == ap_board.JETSON_TX1:
251 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
252 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
253 elif board_id == ap_board.JETSON_TX2:
254 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
255 from adafruit_blinka.microcontroller.tegra.t186.pin import Pin
256 elif board_id == ap_board.JETSON_XAVIER:
257 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
258 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
259 elif board_id == ap_board.JETSON_NX:
260 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
261 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
262 elif detector.board.ROCK_PI_S:
263 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
264 from adafruit_blinka.microcontroller.rockchip.rk3308.pin import Pin
265 elif detector.board.ROCK_PI_4:
266 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
267 from adafruit_blinka.microcontroller.rockchip.rk3399.pin import Pin
268 elif detector.board.SIFIVE_UNLEASHED:
269 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
270 from adafruit_blinka.microcontroller.hfu540.pin import Pin
271 elif detector.board.ftdi_ft232h:
272 from adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.spi import (
275 from adafruit_blinka.microcontroller.ftdi_mpsse.ft232h.pin import Pin
276 elif detector.board.ftdi_ft2232h:
277 from adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.spi import (
280 from adafruit_blinka.microcontroller.ftdi_mpsse.ft2232h.pin import Pin
281 elif detector.board.binho_nova:
282 from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
283 from adafruit_blinka.microcontroller.nova.pin import Pin
284 elif detector.board.greatfet_one:
285 from adafruit_blinka.microcontroller.nxp_lpc4330.spi import SPI as _SPI
286 from adafruit_blinka.microcontroller.nxp_lpc4330.pin import Pin
293 from adafruit_blinka.microcontroller.allwinner.a64.pin import Pin
294 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
295 elif board_id == ap_board.CLOCKWORK_CPI3:
296 from adafruit_blinka.microcontroller.allwinner.a33.pin import Pin
297 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
298 elif board_id == ap_board.ONION_OMEGA2:
299 from adafruit_blinka.microcontroller.mips24kec.pin import Pin
300 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
301 elif detector.board.any_lubancat and detector.chip.id == ap_chip.IMX6ULL:
302 from adafruit_blinka.microcontroller.nxp_imx6ull.pin import Pin
303 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
305 from machine import SPI as _SPI
306 from machine import Pin
309 # TODO check if #init ignores MOSI=None rather than unsetting, to save _pinIds attribute
316 sck=Pin(self._pins[0].id),
317 mosi=Pin(self._pins[1].id),
318 miso=Pin(self._pins[2].id),
321 raise RuntimeError("First call try_lock()")
324 """Deinitialization"""
330 """Return the baud rate if implemented"""
332 return self._spi.frequency
333 except AttributeError:
334 raise NotImplementedError(
335 "Frequency attribute not implemented for this platform"
336 ) from AttributeError
338 def write(self, buf, start=0, end=None):
339 """Write to the SPI device"""
340 return self._spi.write(buf, start, end)
342 def readinto(self, buf, start=0, end=None, write_value=0):
343 """Read from the SPI device into a buffer"""
344 return self._spi.readinto(buf, start, end, write_value=write_value)
347 self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
349 """Write to the SPI device and read from the SPI device into a buffer"""
350 return self._spi.write_readinto(
351 buffer_out, buffer_in, out_start, out_end, in_start, in_end
355 class UART(Lockable):
357 Busio UART Class for CircuitPython Compatibility. Used
358 for MicroPython and a few other non-Linux boards.
362 """Parity Enumeration"""
364 pass # pylint: disable=unnecessary-pass
366 Parity.ODD = Parity()
367 Parity.EVEN = Parity()
378 receiver_buffer_size=64,
381 if detector.board.any_embedded_linux:
383 "busio.UART not supported on this platform. Please use pyserial instead."
385 if detector.board.binho_nova:
386 from adafruit_blinka.microcontroller.nova.uart import UART as _UART
387 elif detector.board.greatfet_one:
388 from adafruit_blinka.microcontroller.nxp_lpc4330.uart import UART as _UART
390 from machine import UART as _UART
392 if detector.board.binho_nova:
393 from adafruit_blinka.microcontroller.nova.pin import uartPorts
395 from microcontroller.pin import uartPorts
397 self.baudrate = baudrate
399 if flow is not None: # default 0
400 raise NotImplementedError(
401 "Parameter '{}' unsupported on {}".format("flow", agnostic.board_id)
404 # translate parity flag for Micropython
405 if parity is UART.Parity.ODD:
407 elif parity is UART.Parity.EVEN:
412 raise ValueError("Invalid parity")
414 # check tx and rx have hardware support
415 for portId, portTx, portRx in uartPorts: #
416 if portTx == tx and portRx == rx:
424 read_buf_len=receiver_buffer_size,
429 "No Hardware UART on (tx,rx)={}\nValid UART ports: {}".format(
435 """Deinitialization"""
436 if detector.board.binho_nova:
440 def read(self, nbytes=None):
441 """Read from the UART"""
442 return self._uart.read(nbytes)
444 def readinto(self, buf, nbytes=None):
445 """Read from the UART into a buffer"""
446 return self._uart.readinto(buf, nbytes)
449 """Read a line of characters up to a newline charater from the UART"""
450 return self._uart.readline()
452 def write(self, buf):
453 """Write to the UART from a buffer"""
454 return self._uart.write(buf)
459 Stub class for OneWire, which is currently not implemented
462 def __init__(self, pin):
463 raise NotImplementedError("OneWire has not been implemented")
467 Deinitialize the OneWire bus and release any hardware resources for reuse.
469 raise NotImplementedError("OneWire has not been implemented")
473 Reset the OneWire bus and read presence
475 raise NotImplementedError("OneWire has not been implemented")
481 raise NotImplementedError("OneWire has not been implemented")
483 def write_bit(self, value):
485 Write out a bit based on value.
487 raise NotImplementedError("OneWire has not been implemented")