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, consider-using-with
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.H6:
224 from adafruit_blinka.microcontroller.allwinner.h6.pin import Pin
225 elif detector.chip.id == ap_chip.H616:
226 from adafruit_blinka.microcontroller.allwinner.h616.pin import Pin
227 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
228 elif detector.board.any_nanopi and detector.chip.id == ap_chip.SUN8I:
229 from adafruit_blinka.microcontroller.allwinner.h3.pin import Pin
230 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
231 elif board_id == ap_board.GIANT_BOARD:
232 from adafruit_blinka.microcontroller.sama5.pin import Pin
233 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
234 elif board_id == ap_board.CORAL_EDGE_TPU_DEV:
235 from adafruit_blinka.microcontroller.nxp_imx8m.pin import Pin
236 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
237 elif board_id == ap_board.CORAL_EDGE_TPU_DEV_MINI:
238 from adafruit_blinka.microcontroller.mt8167.pin import Pin
239 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
240 elif board_id == ap_board.ODROID_C2:
241 from adafruit_blinka.microcontroller.amlogic.s905.pin import Pin
242 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
243 elif board_id == ap_board.ODROID_C4:
244 from adafruit_blinka.microcontroller.amlogic.s905x3.pin import Pin
245 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
246 elif board_id == ap_board.ODROID_XU4:
247 from adafruit_blinka.microcontroller.samsung.exynos5422.pin import Pin
248 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
249 elif board_id == ap_board.DRAGONBOARD_410C:
250 from adafruit_blinka.microcontroller.snapdragon.apq8016.pin import Pin
251 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
252 elif board_id == ap_board.JETSON_NANO:
253 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
254 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
255 elif board_id == ap_board.JETSON_TX1:
256 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
257 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
258 elif board_id == ap_board.JETSON_TX2:
259 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
260 from adafruit_blinka.microcontroller.tegra.t186.pin import Pin
261 elif board_id == ap_board.JETSON_XAVIER:
262 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
263 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
264 elif board_id == ap_board.JETSON_NX:
265 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
266 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
267 elif detector.board.ROCK_PI_S:
268 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
269 from adafruit_blinka.microcontroller.rockchip.rk3308.pin import Pin
270 elif detector.board.ROCK_PI_4:
271 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
272 from adafruit_blinka.microcontroller.rockchip.rk3399.pin import Pin
273 elif detector.board.SIFIVE_UNLEASHED:
274 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
275 from adafruit_blinka.microcontroller.hfu540.pin import Pin
276 elif detector.board.ftdi_ft232h:
277 from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI
278 from adafruit_blinka.microcontroller.ft232h.pin import Pin
279 elif detector.board.binho_nova:
280 from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
281 from adafruit_blinka.microcontroller.nova.pin import Pin
282 elif detector.board.greatfet_one:
283 from adafruit_blinka.microcontroller.nxp_lpc4330.spi import SPI as _SPI
284 from adafruit_blinka.microcontroller.nxp_lpc4330.pin import Pin
291 from adafruit_blinka.microcontroller.allwinner.a64.pin import Pin
292 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
293 elif board_id == ap_board.CLOCKWORK_CPI3:
294 from adafruit_blinka.microcontroller.allwinner.a33.pin import Pin
295 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
296 elif board_id == ap_board.ONION_OMEGA2:
297 from adafruit_blinka.microcontroller.mips24kec.pin import Pin
298 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
299 elif detector.board.any_lubancat and detector.chip.id == ap_chip.IMX6ULL:
300 from adafruit_blinka.microcontroller.nxp_imx6ull.pin import Pin
301 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
302 elif detector.board.pico_u2if:
303 from adafruit_blinka.microcontroller.pico_u2if.spi import SPI as _SPI
304 from adafruit_blinka.microcontroller.pico_u2if.pin import Pin
306 from machine import SPI as _SPI
307 from machine import Pin
310 # TODO check if #init ignores MOSI=None rather than unsetting, to save _pinIds attribute
317 sck=Pin(self._pins[0].id),
318 mosi=Pin(self._pins[1].id),
319 miso=Pin(self._pins[2].id),
322 raise RuntimeError("First call try_lock()")
325 """Deinitialization"""
331 """Return the baud rate if implemented"""
333 return self._spi.frequency
334 except AttributeError:
335 raise NotImplementedError(
336 "Frequency attribute not implemented for this platform"
337 ) from AttributeError
339 def write(self, buf, start=0, end=None):
340 """Write to the SPI device"""
341 return self._spi.write(buf, start, end)
343 def readinto(self, buf, start=0, end=None, write_value=0):
344 """Read from the SPI device into a buffer"""
345 return self._spi.readinto(buf, start, end, write_value=write_value)
348 self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
350 """Write to the SPI device and read from the SPI device into a buffer"""
351 return self._spi.write_readinto(
352 buffer_out, buffer_in, out_start, out_end, in_start, in_end
356 class UART(Lockable):
358 Busio UART Class for CircuitPython Compatibility. Used
359 for MicroPython and a few other non-Linux boards.
363 """Parity Enumeration"""
365 pass # pylint: disable=unnecessary-pass
367 Parity.ODD = Parity()
368 Parity.EVEN = Parity()
379 receiver_buffer_size=64,
382 if detector.board.any_embedded_linux:
384 "busio.UART not supported on this platform. Please use pyserial instead."
386 if detector.board.binho_nova:
387 from adafruit_blinka.microcontroller.nova.uart import UART as _UART
388 elif detector.board.greatfet_one:
389 from adafruit_blinka.microcontroller.nxp_lpc4330.uart import UART as _UART
391 from machine import UART as _UART
393 if detector.board.binho_nova:
394 from adafruit_blinka.microcontroller.nova.pin import uartPorts
396 from microcontroller.pin import uartPorts
398 self.baudrate = baudrate
400 if flow is not None: # default 0
401 raise NotImplementedError(
402 "Parameter '{}' unsupported on {}".format("flow", agnostic.board_id)
405 # translate parity flag for Micropython
406 if parity is UART.Parity.ODD:
408 elif parity is UART.Parity.EVEN:
413 raise ValueError("Invalid parity")
415 # check tx and rx have hardware support
416 for portId, portTx, portRx in uartPorts: #
417 if portTx == tx and portRx == rx:
425 read_buf_len=receiver_buffer_size,
430 "No Hardware UART on (tx,rx)={}\nValid UART ports: {}".format(
436 """Deinitialization"""
437 if detector.board.binho_nova:
441 def read(self, nbytes=None):
442 """Read from the UART"""
443 return self._uart.read(nbytes)
445 def readinto(self, buf, nbytes=None):
446 """Read from the UART into a buffer"""
447 return self._uart.readinto(buf, nbytes)
450 """Read a line of characters up to a newline charater from the UART"""
451 return self._uart.readline()
453 def write(self, buf):
454 """Write to the UART from a buffer"""
455 return self._uart.write(buf)
460 Stub class for OneWire, which is currently not implemented
463 def __init__(self, pin):
464 raise NotImplementedError("OneWire has not been implemented")
468 Deinitialize the OneWire bus and release any hardware resources for reuse.
470 raise NotImplementedError("OneWire has not been implemented")
474 Reset the OneWire bus and read presence
476 raise NotImplementedError("OneWire has not been implemented")
482 raise NotImplementedError("OneWire has not been implemented")
484 def write_bit(self, value):
486 Write out a bit based on value.
488 raise NotImplementedError("OneWire has not been implemented")