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 SCK, MOSI, MISO
160 self._pins = (SCK, MOSI, MISO)
162 if detector.board.binho_nova:
163 from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
164 from adafruit_blinka.microcontroller.nova.pin import SCK, MOSI, MISO
166 self._spi = _SPI(clock)
167 self._pins = (SCK, MOSI, MISO)
169 if detector.board.greatfet_one:
170 from adafruit_blinka.microcontroller.nxp_lpc4330.spi import SPI as _SPI
171 from adafruit_blinka.microcontroller.nxp_lpc4330.pin import SCK, MOSI, MISO
174 self._pins = (SCK, MOSI, MISO)
176 if detector.board.any_embedded_linux:
177 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
178 elif detector.board.ftdi_ft2232h:
179 from adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.spi import SPI as _SPI
181 from machine import SPI as _SPI
182 from microcontroller.pin import spiPorts
184 for portId, portSck, portMosi, portMiso in spiPorts:
187 and MOSI in (portMosi, None) # Clock is required!
188 and MISO in (portMiso, None) # But can do with just output
190 self._spi = _SPI(portId)
191 self._pins = (portSck, portMosi, portMiso)
195 "No Hardware SPI on (SCLK, MOSI, MISO)={}\nValid SPI ports:{}".format(
196 (clock, MOSI, MISO), spiPorts
200 def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
201 """Update the configuration"""
202 if detector.board.any_raspberry_pi or detector.board.any_raspberry_pi_40_pin:
203 from adafruit_blinka.microcontroller.bcm283x.pin import Pin
204 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
205 elif detector.board.BEAGLEBONE_AI:
206 from adafruit_blinka.microcontroller.dra74x.pin import Pin
207 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
208 elif detector.board.any_beaglebone:
209 from adafruit_blinka.microcontroller.am335x.pin import Pin
210 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
211 elif detector.board.any_orange_pi:
212 if detector.chip.id == ap_chip.SUN8I:
213 from adafruit_blinka.microcontroller.allwinner.h3.pin import Pin
214 elif detector.chip.id == ap_chip.H5:
215 from adafruit_blinka.microcontroller.allwinner.h5.pin import Pin
216 elif detector.chip.id == ap_chip.H616:
217 from adafruit_blinka.microcontroller.allwinner.h616.pin import Pin
218 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
219 elif detector.board.any_nanopi and detector.chip.id == ap_chip.SUN8I:
220 from adafruit_blinka.microcontroller.allwinner.h3.pin import Pin
221 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
222 elif board_id == ap_board.GIANT_BOARD:
223 from adafruit_blinka.microcontroller.sama5.pin import Pin
224 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
225 elif board_id == ap_board.CORAL_EDGE_TPU_DEV:
226 from adafruit_blinka.microcontroller.nxp_imx8m.pin import Pin
227 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
228 elif board_id == ap_board.CORAL_EDGE_TPU_DEV_MINI:
229 from adafruit_blinka.microcontroller.mt8167.pin import Pin
230 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
231 elif board_id == ap_board.ODROID_C2:
232 from adafruit_blinka.microcontroller.amlogic.s905.pin import Pin
233 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
234 elif board_id == ap_board.ODROID_C4:
235 from adafruit_blinka.microcontroller.amlogic.s905x3.pin import Pin
236 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
237 elif board_id == ap_board.ODROID_XU4:
238 from adafruit_blinka.microcontroller.samsung.exynos5422.pin import Pin
239 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
240 elif board_id == ap_board.DRAGONBOARD_410C:
241 from adafruit_blinka.microcontroller.snapdragon.apq8016.pin import Pin
242 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
243 elif board_id == ap_board.JETSON_NANO:
244 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
245 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
246 elif board_id == ap_board.JETSON_TX1:
247 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
248 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
249 elif board_id == ap_board.JETSON_TX2:
250 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
251 from adafruit_blinka.microcontroller.tegra.t186.pin import Pin
252 elif board_id == ap_board.JETSON_XAVIER:
253 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
254 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
255 elif board_id == ap_board.JETSON_NX:
256 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
257 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
258 elif detector.board.ROCK_PI_S:
259 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
260 from adafruit_blinka.microcontroller.rockchip.rk3308.pin import Pin
261 elif detector.board.ROCK_PI_4:
262 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
263 from adafruit_blinka.microcontroller.rockchip.rk3399.pin import Pin
264 elif detector.board.SIFIVE_UNLEASHED:
265 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
266 from adafruit_blinka.microcontroller.hfu540.pin import Pin
267 elif detector.board.ftdi_ft232h:
268 from adafruit_blinka.microcontroller.ftdi_mpsse.ft232h.spi import SPI as _SPI
269 from adafruit_blinka.microcontroller.ftdi_mpsse.ft232h.pin import Pin
270 elif detector.board.ftdi_ft2232h:
271 from adafruit_blinka.microcontroller.ftdi_mpsse.ft2232h.spi import SPI as _SPI
272 from adafruit_blinka.microcontroller.ftdi_mpsse.ft2232h.pin import Pin
273 elif detector.board.binho_nova:
274 from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
275 from adafruit_blinka.microcontroller.nova.pin import Pin
276 elif detector.board.greatfet_one:
277 from adafruit_blinka.microcontroller.nxp_lpc4330.spi import SPI as _SPI
278 from adafruit_blinka.microcontroller.nxp_lpc4330.pin import Pin
285 from adafruit_blinka.microcontroller.allwinner.a64.pin import Pin
286 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
287 elif board_id == ap_board.CLOCKWORK_CPI3:
288 from adafruit_blinka.microcontroller.allwinner.a33.pin import Pin
289 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
290 elif board_id == ap_board.ONION_OMEGA2:
291 from adafruit_blinka.microcontroller.mips24kec.pin import Pin
292 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
293 elif detector.board.any_lubancat and detector.chip.id == ap_chip.IMX6ULL:
294 from adafruit_blinka.microcontroller.nxp_imx6ull.pin import Pin
295 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
297 from machine import SPI as _SPI
298 from machine import Pin
301 # TODO check if #init ignores MOSI=None rather than unsetting, to save _pinIds attribute
308 sck=Pin(self._pins[0].id),
309 mosi=Pin(self._pins[1].id),
310 miso=Pin(self._pins[2].id),
313 raise RuntimeError("First call try_lock()")
316 """Deinitialization"""
322 """Return the baud rate if implemented"""
324 return self._spi.frequency
325 except AttributeError:
326 raise NotImplementedError(
327 "Frequency attribute not implemented for this platform"
328 ) from AttributeError
330 def write(self, buf, start=0, end=None):
331 """Write to the SPI device"""
332 return self._spi.write(buf, start, end)
334 def readinto(self, buf, start=0, end=None, write_value=0):
335 """Read from the SPI device into a buffer"""
336 return self._spi.readinto(buf, start, end, write_value=write_value)
339 self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
341 """Write to the SPI device and read from the SPI device into a buffer"""
342 return self._spi.write_readinto(
343 buffer_out, buffer_in, out_start, out_end, in_start, in_end
347 class UART(Lockable):
349 Busio UART Class for CircuitPython Compatibility. Used
350 for MicroPython and a few other non-Linux boards.
354 """Parity Enumeration"""
356 pass # pylint: disable=unnecessary-pass
358 Parity.ODD = Parity()
359 Parity.EVEN = Parity()
370 receiver_buffer_size=64,
373 if detector.board.any_embedded_linux:
375 "busio.UART not supported on this platform. Please use pyserial instead."
377 if detector.board.binho_nova:
378 from adafruit_blinka.microcontroller.nova.uart import UART as _UART
379 elif detector.board.greatfet_one:
380 from adafruit_blinka.microcontroller.nxp_lpc4330.uart import UART as _UART
382 from machine import UART as _UART
384 if detector.board.binho_nova:
385 from adafruit_blinka.microcontroller.nova.pin import uartPorts
387 from microcontroller.pin import uartPorts
389 self.baudrate = baudrate
391 if flow is not None: # default 0
392 raise NotImplementedError(
393 "Parameter '{}' unsupported on {}".format("flow", agnostic.board_id)
396 # translate parity flag for Micropython
397 if parity is UART.Parity.ODD:
399 elif parity is UART.Parity.EVEN:
404 raise ValueError("Invalid parity")
406 # check tx and rx have hardware support
407 for portId, portTx, portRx in uartPorts: #
408 if portTx == tx and portRx == rx:
416 read_buf_len=receiver_buffer_size,
421 "No Hardware UART on (tx,rx)={}\nValid UART ports: {}".format(
427 """Deinitialization"""
428 if detector.board.binho_nova:
432 def read(self, nbytes=None):
433 """Read from the UART"""
434 return self._uart.read(nbytes)
436 def readinto(self, buf, nbytes=None):
437 """Read from the UART into a buffer"""
438 return self._uart.readinto(buf, nbytes)
441 """Read a line of characters up to a newline charater from the UART"""
442 return self._uart.readline()
444 def write(self, buf):
445 """Write to the UART from a buffer"""
446 return self._uart.write(buf)
451 Stub class for OneWire, which is currently not implemented
454 def __init__(self, pin):
455 raise NotImplementedError("OneWire has not been implemented")
459 Deinitialize the OneWire bus and release any hardware resources for reuse.
461 raise NotImplementedError("OneWire has not been implemented")
465 Reset the OneWire bus and read presence
467 raise NotImplementedError("OneWire has not been implemented")
473 raise NotImplementedError("OneWire has not been implemented")
475 def write_bit(self, value):
477 Write out a bit based on value.
479 raise NotImplementedError("OneWire has not been implemented")