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.ft232h.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.pico_u2if:
57 from adafruit_blinka.microcontroller.pico_u2if.i2c import I2C as _I2C
59 self._i2c = _I2C(scl, sda, frequency=frequency)
61 if detector.board.any_embedded_linux:
62 from adafruit_blinka.microcontroller.generic_linux.i2c import I2C as _I2C
64 from machine import I2C as _I2C
65 from microcontroller.pin import i2cPorts
67 for portId, portScl, portSda in i2cPorts:
69 if scl == portScl and sda == portSda:
70 self._i2c = _I2C(portId, mode=_I2C.MASTER, baudrate=frequency)
76 "No Hardware I2C on (scl,sda)={}\nValid I2C ports: {}".format(
80 if threading is not None:
81 self._lock = threading.RLock()
84 """Deinitialization"""
87 except AttributeError:
91 if threading is not None:
95 def __exit__(self, exc_type, exc_value, traceback):
96 if threading is not None:
101 """Scan for attached devices"""
102 return self._i2c.scan()
104 def readfrom_into(self, address, buffer, *, start=0, end=None):
105 """Read from a device at specified address into a buffer"""
106 if start != 0 or end is not None:
109 buffer = memoryview(buffer)[start:end]
110 stop = True # remove for efficiency later
111 return self._i2c.readfrom_into(address, buffer, stop=stop)
113 def writeto(self, address, buffer, *, start=0, end=None, stop=True):
114 """Write to a device at specified address from a buffer"""
115 if isinstance(buffer, str):
116 buffer = bytes([ord(x) for x in buffer])
117 if start != 0 or end is not None:
119 return self._i2c.writeto(address, memoryview(buffer)[start:], stop=stop)
120 return self._i2c.writeto(address, memoryview(buffer)[start:end], stop=stop)
121 return self._i2c.writeto(address, buffer, stop=stop)
123 def writeto_then_readfrom(
135 """ "Write to a device at specified address from a buffer then read
136 from a device at specified address into a buffer
138 return self._i2c.writeto_then_readfrom(
152 Busio SPI Class for CircuitPython Compatibility. Used
153 for both MicroPython and Linux.
156 def __init__(self, clock, MOSI=None, MISO=None):
158 if detector.board.ftdi_ft232h:
159 from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI
160 from adafruit_blinka.microcontroller.ft232h.pin import SCK, MOSI, MISO
163 self._pins = (SCK, MOSI, MISO)
165 if detector.board.binho_nova:
166 from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
167 from adafruit_blinka.microcontroller.nova.pin import SCK, MOSI, MISO
169 self._spi = _SPI(clock)
170 self._pins = (SCK, MOSI, MISO)
172 if detector.board.greatfet_one:
173 from adafruit_blinka.microcontroller.nxp_lpc4330.spi import SPI as _SPI
174 from adafruit_blinka.microcontroller.nxp_lpc4330.pin import SCK, MOSI, MISO
177 self._pins = (SCK, MOSI, MISO)
179 if detector.board.pico_u2if:
180 from adafruit_blinka.microcontroller.pico_u2if.spi import SPI as _SPI
182 self._spi = _SPI(clock) # this is really all that's needed
183 self._pins = (clock, clock, clock) # will determine MOSI/MISO from clock
185 if detector.board.any_embedded_linux:
186 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
188 from machine import SPI as _SPI
189 from microcontroller.pin import spiPorts
191 for portId, portSck, portMosi, portMiso in spiPorts:
194 and MOSI in (portMosi, None) # Clock is required!
195 and MISO in (portMiso, None) # But can do with just output
197 self._spi = _SPI(portId)
198 self._pins = (portSck, portMosi, portMiso)
202 "No Hardware SPI on (SCLK, MOSI, MISO)={}\nValid SPI ports:{}".format(
203 (clock, MOSI, MISO), spiPorts
207 def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
208 """Update the configuration"""
209 if detector.board.any_raspberry_pi or detector.board.any_raspberry_pi_40_pin:
210 from adafruit_blinka.microcontroller.bcm283x.pin import Pin
211 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
212 elif detector.board.BEAGLEBONE_AI:
213 from adafruit_blinka.microcontroller.dra74x.pin import Pin
214 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
215 elif detector.board.any_beaglebone:
216 from adafruit_blinka.microcontroller.am335x.pin import Pin
217 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
218 elif detector.board.any_orange_pi:
219 if detector.chip.id == ap_chip.SUN8I:
220 from adafruit_blinka.microcontroller.allwinner.h3.pin import Pin
221 elif detector.chip.id == ap_chip.H5:
222 from adafruit_blinka.microcontroller.allwinner.h5.pin import Pin
223 elif detector.chip.id == ap_chip.H616:
224 from adafruit_blinka.microcontroller.allwinner.h616.pin import Pin
225 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
226 elif detector.board.any_nanopi and detector.chip.id == ap_chip.SUN8I:
227 from adafruit_blinka.microcontroller.allwinner.h3.pin import Pin
228 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
229 elif board_id == ap_board.GIANT_BOARD:
230 from adafruit_blinka.microcontroller.sama5.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:
233 from adafruit_blinka.microcontroller.nxp_imx8m.pin import Pin
234 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
235 elif board_id == ap_board.CORAL_EDGE_TPU_DEV_MINI:
236 from adafruit_blinka.microcontroller.mt8167.pin import Pin
237 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
238 elif board_id == ap_board.ODROID_C2:
239 from adafruit_blinka.microcontroller.amlogic.s905.pin import Pin
240 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
241 elif board_id == ap_board.ODROID_C4:
242 from adafruit_blinka.microcontroller.amlogic.s905x3.pin import Pin
243 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
244 elif board_id == ap_board.ODROID_XU4:
245 from adafruit_blinka.microcontroller.samsung.exynos5422.pin import Pin
246 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
247 elif board_id == ap_board.DRAGONBOARD_410C:
248 from adafruit_blinka.microcontroller.snapdragon.apq8016.pin import Pin
249 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
250 elif board_id == ap_board.JETSON_NANO:
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_TX1:
254 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
255 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
256 elif board_id == ap_board.JETSON_TX2:
257 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
258 from adafruit_blinka.microcontroller.tegra.t186.pin import Pin
259 elif board_id == ap_board.JETSON_XAVIER:
260 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
261 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
262 elif board_id == ap_board.JETSON_NX:
263 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
264 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
265 elif detector.board.ROCK_PI_S:
266 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
267 from adafruit_blinka.microcontroller.rockchip.rk3308.pin import Pin
268 elif detector.board.ROCK_PI_4:
269 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
270 from adafruit_blinka.microcontroller.rockchip.rk3399.pin import Pin
271 elif detector.board.SIFIVE_UNLEASHED:
272 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
273 from adafruit_blinka.microcontroller.hfu540.pin import Pin
274 elif detector.board.ftdi_ft232h:
275 from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI
276 from adafruit_blinka.microcontroller.ft232h.pin import Pin
277 elif detector.board.binho_nova:
278 from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
279 from adafruit_blinka.microcontroller.nova.pin import Pin
280 elif detector.board.greatfet_one:
281 from adafruit_blinka.microcontroller.nxp_lpc4330.spi import SPI as _SPI
282 from adafruit_blinka.microcontroller.nxp_lpc4330.pin import Pin
289 from adafruit_blinka.microcontroller.allwinner.a64.pin import Pin
290 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
291 elif board_id == ap_board.CLOCKWORK_CPI3:
292 from adafruit_blinka.microcontroller.allwinner.a33.pin import Pin
293 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
294 elif board_id == ap_board.ONION_OMEGA2:
295 from adafruit_blinka.microcontroller.mips24kec.pin import Pin
296 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
297 elif detector.board.any_lubancat and detector.chip.id == ap_chip.IMX6ULL:
298 from adafruit_blinka.microcontroller.nxp_imx6ull.pin import Pin
299 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
300 elif detector.board.pico_u2if:
301 from adafruit_blinka.microcontroller.pico_u2if.spi import SPI as _SPI
302 from adafruit_blinka.microcontroller.pico_u2if.pin import Pin
304 from machine import SPI as _SPI
305 from machine import Pin
308 # TODO check if #init ignores MOSI=None rather than unsetting, to save _pinIds attribute
315 sck=Pin(self._pins[0].id),
316 mosi=Pin(self._pins[1].id),
317 miso=Pin(self._pins[2].id),
320 raise RuntimeError("First call try_lock()")
323 """Deinitialization"""
329 """Return the baud rate if implemented"""
331 return self._spi.frequency
332 except AttributeError:
333 raise NotImplementedError(
334 "Frequency attribute not implemented for this platform"
335 ) from AttributeError
337 def write(self, buf, start=0, end=None):
338 """Write to the SPI device"""
339 return self._spi.write(buf, start, end)
341 def readinto(self, buf, start=0, end=None, write_value=0):
342 """Read from the SPI device into a buffer"""
343 return self._spi.readinto(buf, start, end, write_value=write_value)
346 self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
348 """Write to the SPI device and read from the SPI device into a buffer"""
349 return self._spi.write_readinto(
350 buffer_out, buffer_in, out_start, out_end, in_start, in_end
354 class UART(Lockable):
356 Busio UART Class for CircuitPython Compatibility. Used
357 for MicroPython and a few other non-Linux boards.
361 """Parity Enumeration"""
363 pass # pylint: disable=unnecessary-pass
365 Parity.ODD = Parity()
366 Parity.EVEN = Parity()
377 receiver_buffer_size=64,
380 if detector.board.any_embedded_linux:
382 "busio.UART not supported on this platform. Please use pyserial instead."
384 if detector.board.binho_nova:
385 from adafruit_blinka.microcontroller.nova.uart import UART as _UART
386 elif detector.board.greatfet_one:
387 from adafruit_blinka.microcontroller.nxp_lpc4330.uart import UART as _UART
389 from machine import UART as _UART
391 if detector.board.binho_nova:
392 from adafruit_blinka.microcontroller.nova.pin import uartPorts
394 from microcontroller.pin import uartPorts
396 self.baudrate = baudrate
398 if flow is not None: # default 0
399 raise NotImplementedError(
400 "Parameter '{}' unsupported on {}".format("flow", agnostic.board_id)
403 # translate parity flag for Micropython
404 if parity is UART.Parity.ODD:
406 elif parity is UART.Parity.EVEN:
411 raise ValueError("Invalid parity")
413 # check tx and rx have hardware support
414 for portId, portTx, portRx in uartPorts: #
415 if portTx == tx and portRx == rx:
423 read_buf_len=receiver_buffer_size,
428 "No Hardware UART on (tx,rx)={}\nValid UART ports: {}".format(
434 """Deinitialization"""
435 if detector.board.binho_nova:
439 def read(self, nbytes=None):
440 """Read from the UART"""
441 return self._uart.read(nbytes)
443 def readinto(self, buf, nbytes=None):
444 """Read from the UART into a buffer"""
445 return self._uart.readinto(buf, nbytes)
448 """Read a line of characters up to a newline charater from the UART"""
449 return self._uart.readline()
451 def write(self, buf):
452 """Write to the UART from a buffer"""
453 return self._uart.write(buf)
458 Stub class for OneWire, which is currently not implemented
461 def __init__(self, pin):
462 raise NotImplementedError("OneWire has not been implemented")
466 Deinitialize the OneWire bus and release any hardware resources for reuse.
468 raise NotImplementedError("OneWire has not been implemented")
472 Reset the OneWire bus and read presence
474 raise NotImplementedError("OneWire has not been implemented")
480 raise NotImplementedError("OneWire has not been implemented")
482 def write_bit(self, value):
484 Write out a bit based on value.
486 raise NotImplementedError("OneWire has not been implemented")