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.PINEH64:
294 from adafruit_blinka.microcontroller.allwinner.h6.pin import Pin
295 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
296 elif board_id == ap_board.CLOCKWORK_CPI3:
297 from adafruit_blinka.microcontroller.allwinner.a33.pin import Pin
298 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
299 elif board_id == ap_board.ONION_OMEGA2:
300 from adafruit_blinka.microcontroller.mips24kec.pin import Pin
301 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
302 elif detector.board.any_lubancat and detector.chip.id == ap_chip.IMX6ULL:
303 from adafruit_blinka.microcontroller.nxp_imx6ull.pin import Pin
304 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
305 elif detector.board.pico_u2if:
306 from adafruit_blinka.microcontroller.pico_u2if.spi import SPI as _SPI
307 from adafruit_blinka.microcontroller.pico_u2if.pin import Pin
309 from machine import SPI as _SPI
310 from machine import Pin
313 # TODO check if #init ignores MOSI=None rather than unsetting, to save _pinIds attribute
320 sck=Pin(self._pins[0].id),
321 mosi=Pin(self._pins[1].id),
322 miso=Pin(self._pins[2].id),
325 raise RuntimeError("First call try_lock()")
328 """Deinitialization"""
334 """Return the baud rate if implemented"""
336 return self._spi.frequency
337 except AttributeError:
338 raise NotImplementedError(
339 "Frequency attribute not implemented for this platform"
340 ) from AttributeError
342 def write(self, buf, start=0, end=None):
343 """Write to the SPI device"""
344 return self._spi.write(buf, start, end)
346 def readinto(self, buf, start=0, end=None, write_value=0):
347 """Read from the SPI device into a buffer"""
348 return self._spi.readinto(buf, start, end, write_value=write_value)
351 self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
353 """Write to the SPI device and read from the SPI device into a buffer"""
354 return self._spi.write_readinto(
355 buffer_out, buffer_in, out_start, out_end, in_start, in_end
359 class UART(Lockable):
361 Busio UART Class for CircuitPython Compatibility. Used
362 for MicroPython and a few other non-Linux boards.
366 """Parity Enumeration"""
368 pass # pylint: disable=unnecessary-pass
370 Parity.ODD = Parity()
371 Parity.EVEN = Parity()
382 receiver_buffer_size=64,
385 if detector.board.any_embedded_linux:
387 "busio.UART not supported on this platform. Please use pyserial instead."
389 if detector.board.binho_nova:
390 from adafruit_blinka.microcontroller.nova.uart import UART as _UART
391 elif detector.board.greatfet_one:
392 from adafruit_blinka.microcontroller.nxp_lpc4330.uart import UART as _UART
394 from machine import UART as _UART
396 if detector.board.binho_nova:
397 from adafruit_blinka.microcontroller.nova.pin import uartPorts
399 from microcontroller.pin import uartPorts
401 self.baudrate = baudrate
403 if flow is not None: # default 0
404 raise NotImplementedError(
405 "Parameter '{}' unsupported on {}".format("flow", agnostic.board_id)
408 # translate parity flag for Micropython
409 if parity is UART.Parity.ODD:
411 elif parity is UART.Parity.EVEN:
416 raise ValueError("Invalid parity")
418 # check tx and rx have hardware support
419 for portId, portTx, portRx in uartPorts: #
420 if portTx == tx and portRx == rx:
428 read_buf_len=receiver_buffer_size,
433 "No Hardware UART on (tx,rx)={}\nValid UART ports: {}".format(
439 """Deinitialization"""
440 if detector.board.binho_nova:
444 def read(self, nbytes=None):
445 """Read from the UART"""
446 return self._uart.read(nbytes)
448 def readinto(self, buf, nbytes=None):
449 """Read from the UART into a buffer"""
450 return self._uart.readinto(buf, nbytes)
453 """Read a line of characters up to a newline charater from the UART"""
454 return self._uart.readline()
456 def write(self, buf):
457 """Write to the UART from a buffer"""
458 return self._uart.write(buf)
463 Stub class for OneWire, which is currently not implemented
466 def __init__(self, pin):
467 raise NotImplementedError("OneWire has not been implemented")
471 Deinitialize the OneWire bus and release any hardware resources for reuse.
473 raise NotImplementedError("OneWire has not been implemented")
477 Reset the OneWire bus and read presence
479 raise NotImplementedError("OneWire has not been implemented")
485 raise NotImplementedError("OneWire has not been implemented")
487 def write_bit(self, value):
489 Write out a bit based on value.
491 raise NotImplementedError("OneWire has not been implemented")