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.any_embedded_linux:
57 from adafruit_blinka.microcontroller.generic_linux.i2c import I2C as _I2C
59 from machine import I2C as _I2C
60 from microcontroller.pin import i2cPorts
62 for portId, portScl, portSda in i2cPorts:
64 if scl == portScl and sda == portSda:
65 self._i2c = _I2C(portId, mode=_I2C.MASTER, baudrate=frequency)
71 "No Hardware I2C on (scl,sda)={}\nValid I2C ports: {}".format(
75 if threading is not None:
76 self._lock = threading.RLock()
79 """Deinitialization"""
82 except AttributeError:
86 if threading is not None:
90 def __exit__(self, exc_type, exc_value, traceback):
91 if threading is not None:
96 """Scan for attached devices"""
97 return self._i2c.scan()
99 def readfrom_into(self, address, buffer, *, start=0, end=None):
100 """Read from a device at specified address into a buffer"""
101 if start != 0 or end is not None:
104 buffer = memoryview(buffer)[start:end]
105 stop = True # remove for efficiency later
106 return self._i2c.readfrom_into(address, buffer, stop=stop)
108 def writeto(self, address, buffer, *, start=0, end=None, stop=True):
109 """Write to a device at specified address from a buffer"""
110 if isinstance(buffer, str):
111 buffer = bytes([ord(x) for x in buffer])
112 if start != 0 or end is not None:
114 return self._i2c.writeto(address, memoryview(buffer)[start:], stop=stop)
115 return self._i2c.writeto(address, memoryview(buffer)[start:end], stop=stop)
116 return self._i2c.writeto(address, buffer, stop=stop)
118 def writeto_then_readfrom(
130 """ "Write to a device at specified address from a buffer then read
131 from a device at specified address into a buffer
133 return self._i2c.writeto_then_readfrom(
147 Busio SPI Class for CircuitPython Compatibility. Used
148 for both MicroPython and Linux.
151 def __init__(self, clock, MOSI=None, MISO=None):
153 if detector.board.ftdi_ft232h:
154 from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI
155 from adafruit_blinka.microcontroller.ft232h.pin import SCK, MOSI, MISO
158 self._pins = (SCK, MOSI, MISO)
160 if detector.board.binho_nova:
161 from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
162 from adafruit_blinka.microcontroller.nova.pin import SCK, MOSI, MISO
164 self._spi = _SPI(clock)
165 self._pins = (SCK, MOSI, MISO)
167 if detector.board.greatfet_one:
168 from adafruit_blinka.microcontroller.nxp_lpc4330.spi import SPI as _SPI
169 from adafruit_blinka.microcontroller.nxp_lpc4330.pin import SCK, MOSI, MISO
172 self._pins = (SCK, MOSI, MISO)
174 if detector.board.any_embedded_linux:
175 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
177 from machine import SPI as _SPI
178 from microcontroller.pin import spiPorts
180 for portId, portSck, portMosi, portMiso in spiPorts:
183 and MOSI in (portMosi, None) # Clock is required!
184 and MISO in (portMiso, None) # But can do with just output
186 self._spi = _SPI(portId)
187 self._pins = (portSck, portMosi, portMiso)
191 "No Hardware SPI on (SCLK, MOSI, MISO)={}\nValid SPI ports:{}".format(
192 (clock, MOSI, MISO), spiPorts
196 def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
197 """Update the configuration"""
198 if detector.board.any_raspberry_pi or detector.board.any_raspberry_pi_40_pin:
199 from adafruit_blinka.microcontroller.bcm283x.pin import Pin
200 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
201 elif detector.board.BEAGLEBONE_AI:
202 from adafruit_blinka.microcontroller.dra74x.pin import Pin
203 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
204 elif detector.board.any_beaglebone:
205 from adafruit_blinka.microcontroller.am335x.pin import Pin
206 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
207 elif detector.board.any_orange_pi:
208 if detector.chip.id == ap_chip.SUN8I:
209 from adafruit_blinka.microcontroller.allwinner.h3.pin import Pin
210 elif detector.chip.id == ap_chip.H5:
211 from adafruit_blinka.microcontroller.allwinner.h5.pin import Pin
212 elif detector.chip.id == ap_chip.H616:
213 from adafruit_blinka.microcontroller.allwinner.h616.pin import Pin
214 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
215 elif detector.board.any_nanopi and detector.chip.id == ap_chip.SUN8I:
216 from adafruit_blinka.microcontroller.allwinner.h3.pin import Pin
217 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
218 elif board_id == ap_board.GIANT_BOARD:
219 from adafruit_blinka.microcontroller.sama5.pin import Pin
220 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
221 elif board_id == ap_board.CORAL_EDGE_TPU_DEV:
222 from adafruit_blinka.microcontroller.nxp_imx8m.pin import Pin
223 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
224 elif board_id == ap_board.CORAL_EDGE_TPU_DEV_MINI:
225 from adafruit_blinka.microcontroller.mt8167.pin import Pin
226 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
227 elif board_id == ap_board.ODROID_C2:
228 from adafruit_blinka.microcontroller.amlogic.s905.pin import Pin
229 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
230 elif board_id == ap_board.ODROID_C4:
231 from adafruit_blinka.microcontroller.amlogic.s905x3.pin import Pin
232 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
233 elif board_id == ap_board.ODROID_XU4:
234 from adafruit_blinka.microcontroller.samsung.exynos5422.pin import Pin
235 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
236 elif board_id == ap_board.DRAGONBOARD_410C:
237 from adafruit_blinka.microcontroller.snapdragon.apq8016.pin import Pin
238 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
239 elif board_id == ap_board.JETSON_NANO:
240 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
241 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
242 elif board_id == ap_board.JETSON_TX1:
243 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
244 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
245 elif board_id == ap_board.JETSON_TX2:
246 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
247 from adafruit_blinka.microcontroller.tegra.t186.pin import Pin
248 elif board_id == ap_board.JETSON_XAVIER:
249 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
250 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
251 elif board_id == ap_board.JETSON_NX:
252 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
253 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
254 elif detector.board.ROCK_PI_S:
255 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
256 from adafruit_blinka.microcontroller.rockchip.rk3308.pin import Pin
257 elif detector.board.ROCK_PI_4:
258 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
259 from adafruit_blinka.microcontroller.rockchip.rk3399.pin import Pin
260 elif detector.board.SIFIVE_UNLEASHED:
261 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
262 from adafruit_blinka.microcontroller.hfu540.pin import Pin
263 elif detector.board.ftdi_ft232h:
264 from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI
265 from adafruit_blinka.microcontroller.ft232h.pin import Pin
266 elif detector.board.binho_nova:
267 from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
268 from adafruit_blinka.microcontroller.nova.pin import Pin
269 elif detector.board.greatfet_one:
270 from adafruit_blinka.microcontroller.nxp_lpc4330.spi import SPI as _SPI
271 from adafruit_blinka.microcontroller.nxp_lpc4330.pin import Pin
278 from adafruit_blinka.microcontroller.allwinner.a64.pin import Pin
279 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
280 elif board_id == ap_board.CLOCKWORK_CPI3:
281 from adafruit_blinka.microcontroller.allwinner.a33.pin import Pin
282 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
283 elif board_id == ap_board.ONION_OMEGA2:
284 from adafruit_blinka.microcontroller.mips24kec.pin import Pin
285 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
286 elif detector.board.any_lubancat and detector.chip.id == ap_chip.IMX6ULL:
287 from adafruit_blinka.microcontroller.nxp_imx6ull.pin import Pin
288 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
290 from machine import SPI as _SPI
291 from machine import Pin
294 # TODO check if #init ignores MOSI=None rather than unsetting, to save _pinIds attribute
301 sck=Pin(self._pins[0].id),
302 mosi=Pin(self._pins[1].id),
303 miso=Pin(self._pins[2].id),
306 raise RuntimeError("First call try_lock()")
309 """Deinitialization"""
315 """Return the baud rate if implemented"""
317 return self._spi.frequency
318 except AttributeError:
319 raise NotImplementedError(
320 "Frequency attribute not implemented for this platform"
321 ) from AttributeError
323 def write(self, buf, start=0, end=None):
324 """Write to the SPI device"""
325 return self._spi.write(buf, start, end)
327 def readinto(self, buf, start=0, end=None, write_value=0):
328 """Read from the SPI device into a buffer"""
329 return self._spi.readinto(buf, start, end, write_value=write_value)
332 self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
334 """Write to the SPI device and read from the SPI device into a buffer"""
335 return self._spi.write_readinto(
336 buffer_out, buffer_in, out_start, out_end, in_start, in_end
340 class UART(Lockable):
342 Busio UART Class for CircuitPython Compatibility. Used
343 for MicroPython and a few other non-Linux boards.
347 """Parity Enumeration"""
349 pass # pylint: disable=unnecessary-pass
351 Parity.ODD = Parity()
352 Parity.EVEN = Parity()
363 receiver_buffer_size=64,
366 if detector.board.any_embedded_linux:
368 "busio.UART not supported on this platform. Please use pyserial instead."
370 if detector.board.binho_nova:
371 from adafruit_blinka.microcontroller.nova.uart import UART as _UART
372 elif detector.board.greatfet_one:
373 from adafruit_blinka.microcontroller.nxp_lpc4330.uart import UART as _UART
375 from machine import UART as _UART
377 if detector.board.binho_nova:
378 from adafruit_blinka.microcontroller.nova.pin import uartPorts
380 from microcontroller.pin import uartPorts
382 self.baudrate = baudrate
384 if flow is not None: # default 0
385 raise NotImplementedError(
386 "Parameter '{}' unsupported on {}".format("flow", agnostic.board_id)
389 # translate parity flag for Micropython
390 if parity is UART.Parity.ODD:
392 elif parity is UART.Parity.EVEN:
397 raise ValueError("Invalid parity")
399 # check tx and rx have hardware support
400 for portId, portTx, portRx in uartPorts: #
401 if portTx == tx and portRx == rx:
409 read_buf_len=receiver_buffer_size,
414 "No Hardware UART on (tx,rx)={}\nValid UART ports: {}".format(
420 """Deinitialization"""
421 if detector.board.binho_nova:
425 def read(self, nbytes=None):
426 """Read from the UART"""
427 return self._uart.read(nbytes)
429 def readinto(self, buf, nbytes=None):
430 """Read from the UART into a buffer"""
431 return self._uart.readinto(buf, nbytes)
434 """Read a line of characters up to a newline charater from the UART"""
435 return self._uart.readline()
437 def write(self, buf):
438 """Write to the UART from a buffer"""
439 return self._uart.write(buf)
444 Stub class for OneWire, which is currently not implemented
447 def __init__(self, pin):
448 raise NotImplementedError("OneWire has not been implemented")
452 Deinitialize the OneWire bus and release any hardware resources for reuse.
454 raise NotImplementedError("OneWire has not been implemented")
458 Reset the OneWire bus and read presence
460 raise NotImplementedError("OneWire has not been implemented")
466 raise NotImplementedError("OneWire has not been implemented")
468 def write_bit(self, value):
470 Write out a bit based on value.
472 raise NotImplementedError("OneWire has not been implemented")